card:*: small changes
This commit is contained in:
@@ -1,6 +1,20 @@
|
|||||||
use crate::card::{Card, PlayingCard, Rank, Suit};
|
use crate::card::{Card, PlayingCard, Rank, Suit};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
/*
|
||||||
|
In C this would look something like:
|
||||||
|
switch (self) {
|
||||||
|
case RANK_JACK: fprintf(fp, "J"); break;
|
||||||
|
case RANK_QUEEN: fprintf(fp, "Q"); break;
|
||||||
|
case RANK_KING: fprintf(fp, "K"); break;
|
||||||
|
case RANK_ACE: fprintf(fp, "A"); break;
|
||||||
|
case RANK_TWO: fprintf(fp, "2"); break;
|
||||||
|
default: fprintf(fp, "%d", self + 3); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
but I forgive Rust (for now 👀).
|
||||||
|
*/
|
||||||
|
|
||||||
impl Display for Rank {
|
impl Display for Rank {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
@@ -1,31 +1,36 @@
|
|||||||
use crate::card::{Card, PlayingCard, Rank, Suit};
|
use crate::card::{Card, PlayingCard, Rank, Suit};
|
||||||
|
|
||||||
impl Rank {
|
/*
|
||||||
pub fn ordinary_order(&self) -> i32 {
|
Because of https://github.com/rust-lang/rust/pull/22299, Range<i64> is not an
|
||||||
((*self as i32) + 2) % 13
|
ExactSizeIterator => Map<Range<i64>> is not an ESI. But Range<i32> is an ESI.
|
||||||
}
|
*/
|
||||||
|
|
||||||
|
impl Rank {
|
||||||
/** Generate an iterator over all ranks. */
|
/** Generate an iterator over all ranks. */
|
||||||
pub fn iter_all() -> impl ExactSizeIterator<Item = Rank> {
|
pub fn iter_all() -> impl ExactSizeIterator<Item = Rank> {
|
||||||
(0i32..13).map(|n| Rank::try_from(n as i64).unwrap())
|
(0i32..13)
|
||||||
|
.map(|n| n as i64)
|
||||||
|
.map(|n| Rank::try_from(n).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all cards within a rank, ordered by Suit. */
|
/** Generate an iterator over all cards within a rank, ordered by Suit. The
|
||||||
pub fn cards(self) -> impl Iterator<Item = Card> {
|
cards are all default initialised w.r.t. deck (0).*/
|
||||||
let n = self as i64;
|
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
||||||
((n * 4)..((n + 1) * 4)).map(Card::from)
|
let n = self as i32;
|
||||||
|
((n * 4)..((n + 1) * 4)).map(|x| Card::from(x as i64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Suit {
|
impl Suit {
|
||||||
/** Generate an iterator over all suits. */
|
/** Generate an iterator over all suits. */
|
||||||
pub fn iter_all() -> impl Iterator<Item = Suit> {
|
pub fn iter_all() -> impl ExactSizeIterator<Item = Suit> {
|
||||||
(0..4).filter_map(|x| Suit::try_from(x).ok())
|
(0i32..4).map(|n| Suit::try_from(n as i64).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all cards within a suit, ordered by Suit. */
|
/** Generate an iterator over all cards within a suit, ordered by Rank. The
|
||||||
pub fn cards(self) -> impl Iterator<Item = Card> {
|
cards are all default initialised in terms of deck (0).*/
|
||||||
Rank::iter_all().map(move |rank| Card::make_playing_card(rank, self))
|
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
||||||
|
Rank::iter_all().map(move |rank| Card::make_playing_card(0, rank, self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,42 +45,13 @@ impl PlayingCard {
|
|||||||
(rank * 4) + suit
|
(rank * 4) + suit
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all Playing Cards in a fixed deck. By
|
/** Generate an iterator over all Playing Cards in the `nth` deck. By
|
||||||
construction this is in ascending order. */
|
construction this is in ascending order. */
|
||||||
pub fn iter_all(deck: usize) -> impl Iterator<Item = Self> {
|
pub fn iter_all(n: i64) -> impl ExactSizeIterator<Item = Self> {
|
||||||
let deck = deck as i64;
|
(0i32..52)
|
||||||
((deck * 52)..((deck + 1) * 52))
|
.map(|x| x as i64)
|
||||||
.filter_map(|x| PlayingCard::try_from(x).ok())
|
.map(move |x| x + (52 * n))
|
||||||
}
|
.map(|x| PlayingCard::try_from(x).unwrap())
|
||||||
|
|
||||||
/** Return the Playing Card after the current one in terms of ordering.
|
|
||||||
|
|
||||||
Returns None if self is 2 of Spades (the highest possible Playing Card).
|
|
||||||
Respects deck of self. */
|
|
||||||
pub fn next(&self) -> Option<PlayingCard> {
|
|
||||||
match *self {
|
|
||||||
PlayingCard {
|
|
||||||
rank: Rank::Two,
|
|
||||||
suit: Suit::Spade,
|
|
||||||
..
|
|
||||||
} => None,
|
|
||||||
card => PlayingCard::try_from(i64::from(card) + 1).ok(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the Playing Card before the current one in terms of ordering.
|
|
||||||
|
|
||||||
Returns None if self is 3 of Diamonds (the lowest possible Playing Card).
|
|
||||||
Respects deck of self. */
|
|
||||||
pub fn prev(&self) -> Option<PlayingCard> {
|
|
||||||
match *self {
|
|
||||||
PlayingCard {
|
|
||||||
rank: Rank::Three,
|
|
||||||
suit: Suit::Diamond,
|
|
||||||
..
|
|
||||||
} => None,
|
|
||||||
card => PlayingCard::try_from(i64::from(card) - 1).ok(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,8 +60,8 @@ impl Card {
|
|||||||
Self::Joker(-1)
|
Self::Joker(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_playing_card(rank: Rank, suit: Suit) -> Self {
|
pub fn make_playing_card(deck: i64, rank: Rank, suit: Suit) -> Self {
|
||||||
Self::PlayingCard(PlayingCard::new(0, rank, suit))
|
Self::PlayingCard(PlayingCard::new(deck, rank, suit))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deck_abs(&self) -> i64 {
|
pub fn deck_abs(&self) -> i64 {
|
||||||
@@ -101,50 +77,10 @@ impl Card {
|
|||||||
|
|
||||||
Note that each deck gets two jokers.
|
Note that each deck gets two jokers.
|
||||||
*/
|
*/
|
||||||
pub fn iter_all(n: usize) -> impl Iterator<Item = Card> {
|
pub fn iter_all(n: i64) -> impl Iterator<Item = Card> {
|
||||||
(-((n as i64) * 2)..0).map(Card::from).chain(
|
// NOTE: I cannot make this into an ExactSizeIterator using the i32
|
||||||
(0..n)
|
// trick. Chain<ESI, ESI> is not an ESI, nor is FlatMap<T,U,T->U>
|
||||||
.flat_map(PlayingCard::iter_all)
|
// (where T and U are ESIs).
|
||||||
.map(Card::PlayingCard),
|
(-(n * 2)..(52 * n)).map(Card::from)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the Card after the current one in terms of ordering.
|
|
||||||
|
|
||||||
Returns None if self is a joker, or based on PlayingCard::next.*/
|
|
||||||
pub fn next(&self) -> Option<Card> {
|
|
||||||
match *self {
|
|
||||||
Card::Joker(_) => None,
|
|
||||||
Card::PlayingCard(card) => card.next().map(Card::PlayingCard),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the Card before the current one in terms of ordering.
|
|
||||||
|
|
||||||
Returns None if self is a joker, or based on PlayingCard::prev.*/
|
|
||||||
pub fn prev(&self) -> Option<Card> {
|
|
||||||
match *self {
|
|
||||||
Card::Joker(_) => None,
|
|
||||||
Card::PlayingCard(card) => card.prev().map(Card::PlayingCard),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_joker(&self) -> bool {
|
|
||||||
matches!(self, Self::Joker(_))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn playing_card(&self) -> Option<PlayingCard> {
|
|
||||||
match *self {
|
|
||||||
Self::Joker(_) => None,
|
|
||||||
Self::PlayingCard(card) => Some(card),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rank(&self) -> Option<Rank> {
|
|
||||||
self.playing_card().map(|pc| pc.rank)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn suit(&self) -> Option<Suit> {
|
|
||||||
self.playing_card().map(|pc| pc.suit)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
use crate::card::{Card, PlayingCard, Rank, Suit};
|
use crate::card::{Card, PlayingCard, Rank, Suit};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
/*
|
||||||
|
(1) In C this would just be a straight cast lol. At least T -> i64 is a normal
|
||||||
|
cast.
|
||||||
|
*/
|
||||||
impl TryFrom<i64> for Rank {
|
impl TryFrom<i64> for Rank {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
@@ -24,6 +28,7 @@ impl TryFrom<i64> for Rank {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (1)
|
||||||
impl TryFrom<i64> for Suit {
|
impl TryFrom<i64> for Suit {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
@@ -57,6 +62,15 @@ impl TryFrom<i64> for PlayingCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PlayingCard> for i64 {
|
||||||
|
fn from(card: PlayingCard) -> i64 {
|
||||||
|
let deck = card.deck;
|
||||||
|
let rank = card.rank as i64;
|
||||||
|
let suit = card.suit as i64;
|
||||||
|
(deck * 52) + (rank * 4) + suit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<i64> for Card {
|
impl From<i64> for Card {
|
||||||
fn from(n: i64) -> Self {
|
fn from(n: i64) -> Self {
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
@@ -68,15 +82,6 @@ impl From<i64> for Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PlayingCard> for i64 {
|
|
||||||
fn from(card: PlayingCard) -> i64 {
|
|
||||||
let deck = card.deck;
|
|
||||||
let rank = card.rank as i64;
|
|
||||||
let suit = card.suit as i64;
|
|
||||||
(deck * 52) + (rank * 4) + suit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Card> for i64 {
|
impl From<Card> for i64 {
|
||||||
fn from(card: Card) -> i64 {
|
fn from(card: Card) -> i64 {
|
||||||
match card {
|
match card {
|
||||||
|
|||||||
Reference in New Issue
Block a user