diff --git a/src/hand.rs b/src/hand.rs index d6a80a5..cfdc931 100644 --- a/src/hand.rs +++ b/src/hand.rs @@ -2,7 +2,7 @@ use crate::card::{CardValue, PlayingCard}; use core::fmt; use std::collections::HashMap; -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Debug)] pub enum HandType { HighCard, OnePair, @@ -214,8 +214,8 @@ fn is_straight_flush(hand: &PokerHand) -> bool { assert!(hand.len() == 5); let suit = hand[0].suit; - let mut min_val = CardValue::Two; - let mut max_val = CardValue::Ace; + let mut min_val = CardValue::Ace; + let mut max_val = CardValue::Two; // Must all be the same suit for i in 0..5 { @@ -294,7 +294,7 @@ fn is_flush(hand: &PokerHand) -> bool { fn is_straight(hand: &PokerHand) -> bool { for i in 1..4 { let current_card = hand.cards[i].value as u8; - let previous_card = hand.cards[i].value as u8; + let previous_card = hand.cards[i - 1].value as u8; if current_card != previous_card - 1 { return false; } @@ -325,3 +325,259 @@ fn is_one_pair(hand: &PokerHand) -> bool { // https://stackoverflow.com/questions/45353757/how-to-count-the-elements-in-a-vector-with-some-value-without-looping count.iter().filter(|&n| *n == 2).count() == 1 } + +#[cfg(test)] +mod tests { + use crate::card::CardSuit; + + use super::*; + + #[test] + fn one_pair_test() { + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Ace, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Ace, + }; + let card3 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Two, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Eight, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::OnePair); + + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Ace, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::King, + }; + let card3 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Two, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Eight, + }; + + let nopair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(nopair); + assert_eq!(hand.hand_type(), HandType::HighCard); + } + + #[test] + fn two_pair_test() { + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Ace, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Ace, + }; + let card3 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Two, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::TwoPair); + } + + #[test] + fn three_of_a_kind_tests() { + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Ace, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Ace, + }; + let card3 = PlayingCard { + suit: CardSuit::Spades, + value: CardValue::Ace, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Two, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::ThreeOfAKind); + } + + #[test] + fn staight_test() { + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Eight, + }; + let card3 = PlayingCard { + suit: CardSuit::Spades, + value: CardValue::Seven, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Five, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Nine, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::Straight); + } + + #[test] + fn flush_test() { + let card1 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card2 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Two, + }; + let card3 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Queen, + }; + let card4 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Jack, + }; + let card5 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Ace, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::Flush); + } + + #[test] + fn full_house_test() { + let card1 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Six, + }; + let card2 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card3 = PlayingCard { + suit: CardSuit::Spades, + value: CardValue::Two, + }; + let card4 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card5 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Two, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::FullHouse); + } + + #[test] + fn four_of_a_kind_test() { + let card1 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Six, + }; + let card2 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card3 = PlayingCard { + suit: CardSuit::Spades, + value: CardValue::Six, + }; + let card4 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Six, + }; + let card5 = PlayingCard { + suit: CardSuit::Clubs, + value: CardValue::Two, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::FourOfAKind); + } + + #[test] + fn straight_flush_test() { + let card1 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Jack, + }; + let card2 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Ten, + }; + let card3 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Nine, + }; + let card4 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Seven, + }; + let card5 = PlayingCard { + suit: CardSuit::Diamonds, + value: CardValue::Eight, + }; + + let pair = vec![card1, card2, card3, card4, card5]; + let hand = PokerHand::new(pair); + assert_eq!(hand.hand_type(), HandType::StraightFlush); + } +}