Compare commits
3 Commits
6f5d7d7361
...
499020b904
| Author | SHA1 | Date | |
|---|---|---|---|
| 499020b904 | |||
| 71dab0cf5c | |||
| 387c3f0beb |
33
card_stuffs/Cargo.lock
generated
33
card_stuffs/Cargo.lock
generated
@@ -13,9 +13,17 @@ name = "card_stuffs"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.93"
|
version = "1.0.93"
|
||||||
@@ -34,6 +42,31 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.98"
|
version = "2.0.98"
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.96"
|
anyhow = "1.0.96"
|
||||||
|
strum = "0.27.1"
|
||||||
|
strum_macros = "0.27.1"
|
||||||
thiserror = "2.0.11"
|
thiserror = "2.0.11"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use anyhow::Result;
|
use strum::IntoEnumIterator;
|
||||||
|
use strum_macros::EnumIter;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug, EnumIter, Copy, Clone)]
|
||||||
pub enum Suit {
|
pub enum Suit {
|
||||||
Heart,
|
Heart,
|
||||||
Diamond,
|
Diamond,
|
||||||
@@ -19,10 +20,8 @@ pub enum Colour {
|
|||||||
impl Suit {
|
impl Suit {
|
||||||
pub fn colour(&self) -> Colour {
|
pub fn colour(&self) -> Colour {
|
||||||
match *self {
|
match *self {
|
||||||
Suit::Heart => Colour::Red,
|
Self::Heart | Suit::Diamond => Colour::Red,
|
||||||
Suit::Diamond => Colour::Red,
|
Self::Club | Suit::Spade => Colour::Black,
|
||||||
Suit::Club => Colour::Black,
|
|
||||||
Suit::Spade => Colour::Black,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,15 +29,15 @@ impl Suit {
|
|||||||
impl fmt::Display for Suit {
|
impl fmt::Display for Suit {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Suit::Heart => write!(f, "♥"),
|
Self::Heart => write!(f, "♥"),
|
||||||
Suit::Diamond => write!(f, "♦"),
|
Self::Diamond => write!(f, "♦"),
|
||||||
Suit::Club => write!(f, "♣"),
|
Self::Club => write!(f, "♣"),
|
||||||
Suit::Spade => write!(f, "♠"),
|
Self::Spade => write!(f, "♠"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug, EnumIter, Copy, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Ace,
|
Ace,
|
||||||
Two,
|
Two,
|
||||||
@@ -56,22 +55,22 @@ pub enum Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn indexed_values(&self) -> u8 {
|
fn indexed_values(&self) -> u8 {
|
||||||
// It might also make sense for Ace to be high... depends on context
|
// It might also make sense for Ace to be high... depends on context
|
||||||
match self {
|
match self {
|
||||||
Value::Ace => 1,
|
Self::Ace => 1,
|
||||||
Value::Two => 2,
|
Self::Two => 2,
|
||||||
Value::Three => 3,
|
Self::Three => 3,
|
||||||
Value::Four => 4,
|
Self::Four => 4,
|
||||||
Value::Five => 5,
|
Self::Five => 5,
|
||||||
Value::Six => 6,
|
Self::Six => 6,
|
||||||
Value::Seven => 7,
|
Self::Seven => 7,
|
||||||
Value::Eight => 8,
|
Self::Eight => 8,
|
||||||
Value::Nine => 9,
|
Self::Nine => 9,
|
||||||
Value::Ten => 10,
|
Self::Ten => 10,
|
||||||
Value::Jack => 11,
|
Self::Jack => 11,
|
||||||
Value::Queen => 12,
|
Self::Queen => 12,
|
||||||
Value::King => 13,
|
Self::King => 13,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,19 +78,19 @@ impl Value {
|
|||||||
impl fmt::Display for Value {
|
impl fmt::Display for Value {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Value::Ace => write!(f, "A"),
|
Self::Ace => write!(f, "A"),
|
||||||
Value::Two => write!(f, "2"),
|
Self::Two => write!(f, "2"),
|
||||||
Value::Three => write!(f, "3"),
|
Self::Three => write!(f, "3"),
|
||||||
Value::Four => write!(f, "4"),
|
Self::Four => write!(f, "4"),
|
||||||
Value::Five => write!(f, "5"),
|
Self::Five => write!(f, "5"),
|
||||||
Value::Six => write!(f, "6"),
|
Self::Six => write!(f, "6"),
|
||||||
Value::Seven => write!(f, "7"),
|
Self::Seven => write!(f, "7"),
|
||||||
Value::Eight => write!(f, "8"),
|
Self::Eight => write!(f, "8"),
|
||||||
Value::Nine => write!(f, "9"),
|
Self::Nine => write!(f, "9"),
|
||||||
Value::Ten => write!(f, "T"),
|
Self::Ten => write!(f, "T"),
|
||||||
Value::Jack => write!(f, "J"),
|
Self::Jack => write!(f, "J"),
|
||||||
Value::Queen => write!(f, "Q"),
|
Self::Queen => write!(f, "Q"),
|
||||||
Value::King => write!(f, "K"),
|
Self::King => write!(f, "K"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,6 +99,7 @@ impl fmt::Display for Value {
|
|||||||
pub struct Card {
|
pub struct Card {
|
||||||
pub suit: Suit,
|
pub suit: Suit,
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,6 +109,16 @@ impl fmt::Display for Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Card {
|
||||||
|
fn default() -> Self {
|
||||||
|
Card {
|
||||||
|
suit: Suit::Spade,
|
||||||
|
value: Value::Ace, // If you like to gamble...
|
||||||
|
visible: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, PartialEq)]
|
#[derive(Error, Debug, PartialEq)]
|
||||||
pub enum StackingError {
|
pub enum StackingError {
|
||||||
#[error("Trying to stack the same coloured suit")]
|
#[error("Trying to stack the same coloured suit")]
|
||||||
@@ -118,7 +128,7 @@ pub enum StackingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Card {
|
impl Card {
|
||||||
pub fn can_be_placed_on_top(&self, top: Card) -> Result<(), StackingError> {
|
pub fn can_be_placed_on_top(&self, top: &Card) -> Result<(), StackingError> {
|
||||||
// Can't be the same Colour
|
// Can't be the same Colour
|
||||||
if self.suit.colour() == top.suit.colour() {
|
if self.suit.colour() == top.suit.colour() {
|
||||||
return Err(StackingError::SameColour);
|
return Err(StackingError::SameColour);
|
||||||
@@ -133,6 +143,60 @@ impl Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Deck {
|
||||||
|
pub cards: Vec<Card>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Deck {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut array = Vec::new();
|
||||||
|
for suit in Suit::iter() {
|
||||||
|
for value in Value::iter() {
|
||||||
|
array.push(
|
||||||
|
Card {
|
||||||
|
suit,
|
||||||
|
value,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Deck {
|
||||||
|
cards: array,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NumPassesThroughDeck {
|
||||||
|
Unlimited,
|
||||||
|
Limited(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Klondike {
|
||||||
|
piles: [Vec<Card>; 7],
|
||||||
|
deck: Vec<Card>,
|
||||||
|
waste: Vec<Card>,
|
||||||
|
foundation: [Vec<Card>; 4], // 4 = len of num suits
|
||||||
|
max_num_passes_through_deck: NumPassesThroughDeck,
|
||||||
|
current_num_passes_through_deck: u64,
|
||||||
|
num_cards_turned: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
impl Default for Klondike {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut deck = Deck::default;
|
||||||
|
// shuffle deck
|
||||||
|
// deal some cards
|
||||||
|
let mut
|
||||||
|
// set some settings?
|
||||||
|
Self {
|
||||||
|
piles:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -143,27 +207,32 @@ mod tests {
|
|||||||
let testing_card = Card {
|
let testing_card = Card {
|
||||||
suit: Suit::Heart,
|
suit: Suit::Heart,
|
||||||
value: Value::Five,
|
value: Value::Five,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
let bad_same_suit = Card {
|
let bad_same_suit = Card {
|
||||||
suit: Suit::Heart,
|
suit: Suit::Heart,
|
||||||
value: Value::Six,
|
value: Value::Six,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(testing_card.can_be_placed_on_top(bad_same_suit), Err(StackingError::SameColour));
|
assert_eq!(testing_card.can_be_placed_on_top(&bad_same_suit), Err(StackingError::SameColour));
|
||||||
let bad_same_colour = Card {
|
let bad_same_colour = Card {
|
||||||
suit: Suit::Diamond,
|
suit: Suit::Diamond,
|
||||||
value: Value::Six,
|
value: Value::Six,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(testing_card.can_be_placed_on_top(bad_same_colour), Err(StackingError::SameColour));
|
assert_eq!(testing_card.can_be_placed_on_top(&bad_same_colour), Err(StackingError::SameColour));
|
||||||
let should_stack_card = Card {
|
let should_stack_card = Card {
|
||||||
suit: Suit::Club,
|
suit: Suit::Club,
|
||||||
value: Value::Six,
|
value: Value::Six,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(testing_card.can_be_placed_on_top(should_stack_card), Ok(()));
|
assert_eq!(testing_card.can_be_placed_on_top(&should_stack_card), Ok(()));
|
||||||
let value_too_high = Card {
|
let value_too_high = Card {
|
||||||
suit: Suit::Club,
|
suit: Suit::Club,
|
||||||
value: Value::Seven,
|
value: Value::Seven,
|
||||||
|
..Default::default()
|
||||||
};
|
};
|
||||||
let not_adj_error = testing_card.can_be_placed_on_top(value_too_high);
|
let not_adj_error = testing_card.can_be_placed_on_top(&value_too_high);
|
||||||
if let Err(e) = not_adj_error {
|
if let Err(e) = not_adj_error {
|
||||||
match e {
|
match e {
|
||||||
StackingError::NotAdjacent(_, _) => assert!(true),
|
StackingError::NotAdjacent(_, _) => assert!(true),
|
||||||
@@ -173,4 +242,11 @@ mod tests {
|
|||||||
assert!(false, "Cards are not adjacent - should be an error")
|
assert!(false, "Cards are not adjacent - should be an error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_a_whole_deck() {
|
||||||
|
let d = Deck::default();
|
||||||
|
assert_eq!(d.cards.len(), 52); // Probably should test whether all cards are in... eh
|
||||||
|
println!("{:#?}", d); // A "manual" review looks alright
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user