diff --git a/card_stuffs/src/lib.rs b/card_stuffs/src/lib.rs index 020d4d5..8797129 100644 --- a/card_stuffs/src/lib.rs +++ b/card_stuffs/src/lib.rs @@ -131,7 +131,7 @@ pub enum StackingError { } impl Card { - pub fn can_be_placed_on_top(&self, top: &Card) -> Result<(), StackingError> { + pub fn can_be_placed_on_top_pile(&self, top: &Card) -> Result<(), StackingError> { // Can't be the same Colour if self.suit.colour() == top.suit.colour() { return Err(StackingError::SameColour); @@ -144,6 +144,25 @@ impl Card { Ok(()) } + + pub fn can_be_placed_on_top_foundation(&self, top: &Option) -> Result<(), StackingError> { + match top { + None => { + if self.value == Value::Ace { + return Ok(()); + } else { + return Err(StackingError::NotAdjacent(self.to_string(), "an empty foundation".to_string())); + } + }, + Some(c) => { + if self.value.indexed_values() + 1 == c.value.indexed_values() { + return Ok(()); + } else { + return Err(StackingError::NotAdjacent(self.to_string(), c.to_string())); + } + } + } + } } #[derive(Debug)] @@ -188,6 +207,18 @@ impl Deck { } } +pub struct CardAndPosition { + card: Option, + pos: CardPosition, +} + +pub enum CardPosition { + Deck, // I don't think this will need to be used + TopWaste, // I don't think we'd ever interact with anything other than the top of the Waste + Pile(u8, u8), // (PileNumber, Index) + Foundation(u8) +} + #[derive(Debug, Copy, Clone)] pub enum NumPassesThroughDeck { Unlimited, @@ -234,7 +265,44 @@ impl Klondike { self.current_num_passes_through_deck += 1; } } - //pub fn move_one_stack_to_another(self, ) + + pub fn move_card(self, source_card: &CardAndPosition, dest_card: &CardAndPosition) { + // TODO raise errors properly + assert_eq!(source_card.card.unwrap().visible, true); + source_card.pos.is_valid_source(); + dest_card.pos.is_valid_dest(); + + match dest_card.pos { + CardPosition::Pile(_, _) => self.move_card_to_pile(&source_card, &dest_card), + CardPosition::Foundation(_) => self.move_card_to_foundation(source_card, dest_card), + CardPosition::Deck | CardPosition::TopWaste => unreachable!() + } + } + + pub fn move_card_to_foundation(self, source_card: &CardAndPosition, dest_card: &CardAndPosition) { + + } + pub fn move_card_to_pile(self, source_card: &CardAndPosition, dest_card: &CardAndPosition) { + + } +} + +impl CardPosition { + // Unsure this is "correct" to just panic - but it really shouldn't happen + fn is_valid_dest(&self) { + match self { + CardPosition::Deck => unreachable!("You can't move cards to deck"), + CardPosition::TopWaste => unreachable!("You can't move cards to waste"), + CardPosition::Pile(_, _) | CardPosition::Foundation(_) => (), + } + } + + fn is_valid_source(&self) { + match self { + CardPosition::Deck => unreachable!("You can't move cards from deck"), + CardPosition::TopWaste | CardPosition::Pile(_, _) | CardPosition::Foundation(_) => (), + } + } } impl Default for Klondike { @@ -282,25 +350,25 @@ mod tests { 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_pile(&bad_same_suit), Err(StackingError::SameColour)); let bad_same_colour = Card { suit: Suit::Diamond, 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_pile(&bad_same_colour), Err(StackingError::SameColour)); let should_stack_card = Card { suit: Suit::Club, 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_pile(&should_stack_card), Ok(())); let value_too_high = Card { suit: Suit::Club, 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_pile(&value_too_high); if let Err(e) = not_adj_error { match e { StackingError::NotAdjacent(_, _) => assert!(true), @@ -311,6 +379,22 @@ mod tests { } } + #[test] + fn basic_foundation_stacking() { + let testing_card = Card { + suit: Suit::Spade, + value: Value::Ace, + ..Default::default() + }; + assert_eq!(testing_card.can_be_placed_on_top_foundation(&None), Ok(())); + let testing_card = Card { + suit: Suit::Spade, + value: Value::Two, + ..Default::default() + }; + assert!(testing_card.can_be_placed_on_top_foundation(&None).is_err()); + } + #[test] fn get_a_whole_deck() { let d = Deck::default();