Compare commits

..

3 Commits

Author SHA1 Message Date
499020b904 "Cleaned up" some things and started on a possible Klondike struct 2025-02-24 23:52:17 +00:00
71dab0cf5c Couple of clippy lints
Not 100% sure what the "must_use" is really for... so didn't "fix" them
2025-02-24 23:25:28 +00:00
387c3f0beb Added a basic deck 2025-02-24 23:17:53 +00:00
3 changed files with 154 additions and 43 deletions

33
card_stuffs/Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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
}
} }