diff --git a/card_stuffs/src/lib.rs b/card_stuffs/src/lib.rs index 023cf69..6299698 100644 --- a/card_stuffs/src/lib.rs +++ b/card_stuffs/src/lib.rs @@ -128,6 +128,8 @@ pub enum StackingError { SameColour, #[error("{0} is not \"next\" to {1}")] NotAdjacent(String, String), + #[error("Foundations need to be the same suit")] + WrongSuit, } impl Card { @@ -147,6 +149,7 @@ impl Card { pub fn can_be_placed_on_foundation(&self, top: &Option) -> Result<(), StackingError> { // TODO check suit is correct + println!("hello1"); match top { None => { if self.value == Value::Ace { @@ -156,6 +159,10 @@ impl Card { } }, Some(c) => { + if self.suit != c.suit { + println!("hellosuitsame"); + return Err(StackingError::WrongSuit); + } if self.value.indexed_values() + 1 == c.value.indexed_values() { return Ok(()); } else { @@ -289,12 +296,10 @@ impl Klondike { // TODO Check whether the card is the top of a pile / waste - it needs to be // TODO actually learn Rust properly so I can figure out why I need to clone the whole struct to check a value if source_card.pos != CardPosition::TopWaste && !self.clone().is_card_top_of_pile(&source_card.pos) { - // TODO as above - make this a proper error - println!("Can't move from this position"); + // TODO as above - make all these proper errors return false; } if source_card.card.unwrap().can_be_placed_on_foundation(&dest_card.card).is_err() { - println!("Can't be placed on foundation for some reason - wrong colour? wrong value?"); return false; } // TODO actually move the cards - it should be possible from here @@ -430,6 +435,7 @@ mod tests { match e { StackingError::NotAdjacent(_, _) => assert!(true), StackingError::SameColour => assert!(false, "Colour is different - incorrect error"), + StackingError::WrongSuit => unreachable!(), } } else { assert!(false, "Cards are not adjacent - should be an error") @@ -550,6 +556,8 @@ mod tests { }; assert!(klon.move_card_to_foundation(&source_card, &dest_card)); + + // TODO the following cases: // - moving a card from pile to foundation when something is already there // - moving Ace from waste to top of pile @@ -557,6 +565,59 @@ mod tests { // => for cases where it'll both work and not work - when cards are / aren't present } + #[test] + fn move_to_foundation_with_wrong_suit() { + let mut klon = Klondike::default(); + let ace = Card { + suit: Suit::Heart, + value: Value::Ace, + .. Default::default() + }; + let two = Card { + suit: Suit::Spade, + value: Value::Two, + .. Default::default() + }; + klon.waste.push(two.clone()); + klon.piles[0].push(ace.clone()); + let source_card = CardAndPosition { + card: Some(ace.clone()), + pos: CardPosition::TopWaste, + }; + let dest_card = CardAndPosition { + card: Some(two.clone()), + pos: CardPosition::Foundation(0), + }; + assert!(!klon.move_card_to_foundation(&source_card, &dest_card)); + // TODO this is passing - but I don't think it's passing for the right reason + } + + #[test] + fn move_ace_to_foundation_with_card_present() { + let mut klon = Klondike::default(); + let ace_heart = Card { + suit: Suit::Heart, + value: Value::Ace, + .. Default::default() + }; + let ace_spade = Card { + suit: Suit::Spade, + value: Value::Ace, + .. Default::default() + }; + klon.waste.push(ace_heart.clone()); + klon.piles[0].push(ace_spade.clone()); + let source_card = CardAndPosition { + card: Some(ace_heart.clone()), + pos: CardPosition::TopWaste, + }; + let dest_card = CardAndPosition { + card: Some(ace_spade.clone()), + pos: CardPosition::Foundation(0), + }; + assert!(!klon.move_card_to_foundation(&source_card, &dest_card)); + } + #[test] fn get_a_whole_deck() { let d = Deck::default();