balatro_rs/core/
hand.rs

1use indexmap::IndexMap;
2use itertools::Itertools;
3use std::fmt;
4
5use crate::core::card::Card;
6use crate::core::card::Suit;
7use crate::core::card::Value;
8use crate::core::error::PlayHandError;
9use crate::core::rank::HandRank;
10
11// Hand, SelectHand and MadeHand are all representations of a collection of Card,
12// just at different phases in the cycle of selecting, executing and scoring cards.
13// Hand represents all drawn cards, cards available for action (play/discard).
14// SelectHand represents (up to 5) cards user selects from hand for action.
15// MadeHand represents actual poker hand level and associated cards from a selected hand.
16
17// Hand represents all drawn cards, cards available for action (play/discard)
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[derive(Debug, Clone, Hash, PartialEq, Eq)]
20pub struct Hand(Vec<Card>);
21
22// MadeHand represents actual poker hand level and associated cards from a selected hand.
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24#[derive(Debug, Clone, Hash, PartialEq, Eq)]
25pub struct MadeHand {
26    pub hand: SelectHand,
27    pub rank: HandRank,
28}
29
30// SelectHand represents (up to 5) cards user selects from hand for action
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[derive(Debug, Clone, Hash, PartialEq, Eq)]
33pub struct SelectHand(Vec<Card>);
34
35impl SelectHand {
36    pub fn new(cards: Vec<Card>) -> Self {
37        Self(cards)
38    }
39    pub fn push(&mut self, c: Card) {
40        self.0.push(c);
41    }
42    pub fn append(&mut self, cards: Vec<Card>) {
43        self.0.extend(cards);
44    }
45    pub fn truncate(&mut self, len: usize) {
46        self.0.truncate(len)
47    }
48    pub fn len(&self) -> usize {
49        self.0.len()
50    }
51    pub fn is_empty(&self) -> bool {
52        self.0.is_empty()
53    }
54    // Get all values in a hand. Sorted lowest to highest.
55    pub fn values(&self) -> Vec<Value> {
56        self.0.iter().map(|x| x.value).sorted().collect()
57    }
58    pub fn cards(&self) -> Vec<Card> {
59        return self.0.clone();
60    }
61
62    // Get map of each value with corresponding cards.
63    // For example, Ks, Ah, Jh, Jc, Jd -> {A: [Ah], K: [Ks], J: [Jh, Jc: Jd]}
64    pub fn values_freq(&self) -> IndexMap<Value, Vec<Card>> {
65        let mut counts: IndexMap<Value, Vec<Card>> = IndexMap::new();
66        for card in self.0.clone() {
67            if let Some(cards) = counts.get(&card.value) {
68                let mut copy = cards.clone();
69                copy.push(card);
70                counts.insert(card.value, copy);
71            } else {
72                counts.insert(card.value, vec![card]);
73            }
74        }
75        // Return sorted by value
76        return counts
77            .into_iter()
78            .sorted_by(|a, b| Ord::cmp(&b.0, &a.0))
79            .collect();
80    }
81
82    // Get all suits in a hand
83    pub fn suits(&self) -> Vec<Suit> {
84        self.0.iter().map(|x| x.suit).sorted().collect()
85    }
86
87    // Get map of each suit with corresponding cards.
88    // For example, Ks, Ah, Jh, Jc, Jd -> {h: [Jh, Ah], s: [Ks], c: [Jc], d: [Jd]}
89    pub fn suits_freq(&self) -> IndexMap<Suit, Vec<Card>> {
90        let mut counts: IndexMap<Suit, Vec<Card>> = IndexMap::new();
91        for card in self.0.clone() {
92            if let Some(cards) = counts.get(&card.suit) {
93                let mut copy = cards.clone();
94                copy.push(card);
95                counts.insert(card.suit, copy);
96            } else {
97                counts.insert(card.suit, vec![card]);
98            }
99        }
100        // Return sorted by suit
101        return counts
102            .into_iter()
103            .sorted_by(|a, b| Ord::cmp(&b.0, &a.0))
104            .collect();
105    }
106
107    /// Can play any number of cards, it is our responsibility
108    /// to determine the best hand. Higher tier hands take precedence
109    /// over lower tier hands regardless of their level or scoring.
110    /// For example, if hand is Kd Kd Kd Kd 2d, best hand will be a
111    // Four of a Kind and never a Flush.
112    //
113    // Hand ranking:
114    // FlushFive
115    // FlushHouse
116    // FiveOfAKind
117    // RoyalFlush
118    // StraightFlush
119    // FourOfAKind
120    // FullHouse
121    // Flush
122    // Straight
123    // ThreeOfAKind
124    // TwoPair
125    // OnePair
126    // HighCard
127    pub fn best_hand(&self) -> Result<MadeHand, PlayHandError> {
128        if self.len() == 0 {
129            return Err(PlayHandError::NoCards);
130        }
131        if self.len() > 5 {
132            return Err(PlayHandError::TooManyCards);
133        }
134
135        // We start trying to evaluate best hands first, so we
136        // can return best hand right when we find it.
137        if let Some(hand) = self.is_flush_five() {
138            return Ok(MadeHand {
139                hand,
140                rank: HandRank::FlushFive,
141            });
142        }
143        if let Some(hand) = self.is_flush_house() {
144            return Ok(MadeHand {
145                hand,
146                rank: HandRank::FlushHouse,
147            });
148        }
149        if let Some(hand) = self.is_five_of_kind() {
150            return Ok(MadeHand {
151                hand,
152                rank: HandRank::FiveOfAKind,
153            });
154        }
155        if let Some(hand) = self.is_royal_flush() {
156            return Ok(MadeHand {
157                hand,
158                rank: HandRank::RoyalFlush,
159            });
160        }
161        if let Some(hand) = self.is_straight_flush() {
162            return Ok(MadeHand {
163                hand,
164                rank: HandRank::StraightFlush,
165            });
166        }
167        if let Some(hand) = self.is_four_of_kind() {
168            return Ok(MadeHand {
169                hand,
170                rank: HandRank::FourOfAKind,
171            });
172        }
173        if let Some(hand) = self.is_fullhouse() {
174            return Ok(MadeHand {
175                hand,
176                rank: HandRank::FullHouse,
177            });
178        }
179        if let Some(hand) = self.is_flush() {
180            return Ok(MadeHand {
181                hand,
182                rank: HandRank::Flush,
183            });
184        }
185        if let Some(hand) = self.is_straight() {
186            return Ok(MadeHand {
187                hand,
188                rank: HandRank::Straight,
189            });
190        }
191        if let Some(hand) = self.is_three_of_kind() {
192            return Ok(MadeHand {
193                hand,
194                rank: HandRank::ThreeOfAKind,
195            });
196        }
197        if let Some(hand) = self.is_two_pair() {
198            return Ok(MadeHand {
199                hand,
200                rank: HandRank::TwoPair,
201            });
202        }
203        if let Some(hand) = self.is_pair() {
204            return Ok(MadeHand {
205                hand,
206                rank: HandRank::OnePair,
207            });
208        }
209        if let Some(hand) = self.is_highcard() {
210            return Ok(MadeHand {
211                hand,
212                rank: HandRank::HighCard,
213            });
214        }
215        // We didn't match any known hand, oops...
216        return Err(PlayHandError::UnknownHand);
217    }
218
219    pub fn is_highcard(&self) -> Option<SelectHand> {
220        if self.len() < 1 {
221            return None;
222        }
223        if let Some((_value, cards)) = self
224            .values_freq()
225            .into_iter()
226            .find(|(_key, val)| val.len() == 1)
227        {
228            return Some(SelectHand::new(cards));
229        } else {
230            return None;
231        }
232    }
233
234    pub fn is_pair(&self) -> Option<SelectHand> {
235        if self.len() < 2 {
236            return None;
237        }
238        if let Some((_value, cards)) = self
239            .values_freq()
240            .into_iter()
241            .find(|(_key, val)| val.len() == 2)
242        {
243            return Some(SelectHand::new(cards));
244        } else {
245            return None;
246        }
247    }
248
249    pub fn is_two_pair(&self) -> Option<SelectHand> {
250        if self.len() < 4 {
251            return None;
252        }
253
254        // First find first pair
255        let first = self
256            .values_freq()
257            .into_iter()
258            .find(|(_key, val)| val.len() == 2);
259        if first.is_none() {
260            return None;
261        }
262        let first_val = first
263            .as_ref()
264            .unwrap()
265            .1
266            .first()
267            .expect("values freq has empty Vec<card>")
268            .value;
269
270        // Next find second pair that isn't same value as first pair
271        let second = self
272            .values_freq()
273            .into_iter()
274            .find(|(key, val)| *key != first_val && val.len() == 2);
275        if second.is_none() {
276            return None;
277        }
278
279        // Combine first and second pair
280        let mut cards: Vec<Card> = Vec::new();
281        cards.extend(first.unwrap().1);
282        cards.extend(second.unwrap().1);
283        return Some(SelectHand::new(cards));
284    }
285
286    pub fn is_three_of_kind(&self) -> Option<SelectHand> {
287        if self.len() < 3 {
288            return None;
289        }
290        if let Some((_value, cards)) = self
291            .values_freq()
292            .into_iter()
293            .find(|(_key, val)| val.len() == 3)
294        {
295            return Some(SelectHand::new(cards));
296        } else {
297            return None;
298        }
299    }
300
301    pub fn is_straight(&self) -> Option<SelectHand> {
302        if self.len() != 5 {
303            return None;
304        }
305        // Iterate our sorted values. Each value must be one more than the previous.
306        let values = self.values();
307        if values.windows(2).all(|v| (v[1] as u16 - v[0] as u16) == 1) {
308            return Some(self.clone());
309        }
310
311        // Special case for low ace.
312        // Values are sorted with Ace as high (2, 3, 4, 5, A)
313        // Therefore, we can check that last value is ace, first value is two.
314        // Then remove the last value (ace) from vec and check for incremental values
315        // for everything else (2, 3, 4, 5).
316        if values[4] == Value::Ace && values[0] == Value::Two {
317            let skip_last: Vec<Value> = values.into_iter().rev().skip(1).rev().collect();
318            if skip_last
319                .windows(2)
320                .all(|v| (v[1] as u16 - v[0] as u16) == 1)
321            {
322                return Some(self.clone());
323            }
324        }
325        return None;
326    }
327
328    pub fn is_flush(&self) -> Option<SelectHand> {
329        if self.len() < 5 {
330            return None;
331        }
332        if let Some((_value, cards)) = self
333            .suits_freq()
334            .into_iter()
335            .find(|(_key, val)| val.len() == 5)
336        {
337            return Some(SelectHand::new(cards));
338        } else {
339            return None;
340        }
341    }
342
343    pub fn is_fullhouse(&self) -> Option<SelectHand> {
344        if self.len() < 5 {
345            return None;
346        }
347
348        // First find 3ok
349        let three = self
350            .values_freq()
351            .into_iter()
352            .find(|(_key, val)| val.len() == 3);
353        if three.is_none() {
354            return None;
355        }
356        let three_val = three
357            .as_ref()
358            .unwrap()
359            .1
360            .first()
361            .expect("values freq has empty Vec<card>")
362            .value;
363
364        // Next find 2ok that isn't same value as 3ok
365        let two = self
366            .values_freq()
367            .into_iter()
368            .find(|(key, val)| *key != three_val && val.len() == 2);
369        if two.is_none() {
370            return None;
371        }
372
373        // Combine 3ok and 2ok
374        let mut cards: Vec<Card> = Vec::new();
375        cards.extend(three.unwrap().1);
376        cards.extend(two.unwrap().1);
377        return Some(SelectHand::new(cards));
378    }
379
380    pub fn is_four_of_kind(&self) -> Option<SelectHand> {
381        if self.len() < 4 {
382            return None;
383        }
384        if let Some((_value, cards)) = self
385            .values_freq()
386            .into_iter()
387            .find(|(_key, val)| val.len() == 4)
388        {
389            return Some(SelectHand::new(cards));
390        } else {
391            return None;
392        }
393    }
394
395    pub fn is_straight_flush(&self) -> Option<SelectHand> {
396        if self.is_flush().is_some() && self.is_straight().is_some() {
397            return Some(self.clone());
398        }
399        return None;
400    }
401
402    pub fn is_royal_flush(&self) -> Option<SelectHand> {
403        if self.is_straight_flush().is_some()
404            && self.values().into_iter().eq(vec![
405                Value::Ten,
406                Value::Jack,
407                Value::Queen,
408                Value::King,
409                Value::Ace,
410            ])
411        {
412            return Some(self.clone());
413        }
414        return None;
415    }
416
417    pub fn is_five_of_kind(&self) -> Option<SelectHand> {
418        if self.len() < 5 {
419            return None;
420        }
421        if let Some((_value, cards)) = self
422            .values_freq()
423            .into_iter()
424            .find(|(_key, val)| val.len() == 5)
425        {
426            return Some(SelectHand::new(cards));
427        } else {
428            return None;
429        }
430    }
431
432    pub fn is_flush_house(&self) -> Option<SelectHand> {
433        if self.is_flush().is_some() && self.is_fullhouse().is_some() {
434            return Some(self.clone());
435        }
436        return None;
437    }
438
439    pub fn is_flush_five(&self) -> Option<SelectHand> {
440        if self.is_flush().is_some() && self.is_five_of_kind().is_some() {
441            return Some(self.clone());
442        }
443        return None;
444    }
445}
446
447impl Default for SelectHand {
448    fn default() -> Self {
449        let cards: Vec<Card> = Vec::new();
450        Self(cards)
451    }
452}
453
454impl fmt::Display for SelectHand {
455    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
456        write!(f, "[")?;
457        for card in &self.0 {
458            write!(f, "{}", card)?;
459        }
460        write!(f, "]")?;
461        return Ok(());
462    }
463}
464
465#[cfg(test)]
466mod tests {
467    use super::*;
468
469    #[test]
470    fn test_values() {
471        let c3 = Card::new(Value::Two, Suit::Heart);
472        let c4 = Card::new(Value::Three, Suit::Diamond);
473        let c5 = Card::new(Value::Jack, Suit::Heart);
474        let c1 = Card::new(Value::King, Suit::Heart);
475        let c2 = Card::new(Value::Ace, Suit::Spade);
476
477        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
478        let values = hand.values();
479
480        // Should have 5 values
481        assert_eq!(values.len(), 5);
482
483        // Expect sorted (2, 3, J, K, A)
484        assert_eq!(values[0], Value::Two);
485        assert_eq!(values[1], Value::Three);
486        assert_eq!(values[2], Value::Jack);
487        assert_eq!(values[3], Value::King);
488        assert_eq!(values[4], Value::Ace);
489    }
490
491    #[test]
492    fn test_values_freq() {
493        let c1 = Card::new(Value::Two, Suit::Heart);
494        let c2 = Card::new(Value::Three, Suit::Diamond);
495        let c3 = Card::new(Value::Four, Suit::Heart);
496        let c4 = Card::new(Value::King, Suit::Heart);
497        let c5 = Card::new(Value::King, Suit::Spade);
498
499        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
500        let freq = hand.values_freq();
501
502        // Should have 4 values (K, 2, 3, 4)
503        assert_eq!(freq.len(), 4);
504
505        // Expect 2 kings and 1 each of 2, 3, 4
506        assert_eq!(freq.get(&Value::King).unwrap().len(), 2);
507        assert_eq!(freq.get(&Value::Two).unwrap().len(), 1);
508        assert_eq!(freq.get(&Value::Three).unwrap().len(), 1);
509        assert_eq!(freq.get(&Value::Four).unwrap().len(), 1);
510
511        // No extra cards
512        assert_eq!(freq.get(&Value::Five), None);
513        assert_eq!(freq.get(&Value::Nine), None);
514
515        // Can also check the cards in the vec are as expected
516        assert_eq!(freq.get(&Value::King).unwrap()[0].value, Value::King);
517        assert_eq!(freq.get(&Value::King).unwrap()[1].value, Value::King);
518        assert_eq!(freq.get(&Value::Two).unwrap()[0].value, Value::Two);
519        assert_eq!(freq.get(&Value::Three).unwrap()[0].value, Value::Three);
520        assert_eq!(freq.get(&Value::Four).unwrap()[0].value, Value::Four);
521
522        // Check ordered by value
523        assert_eq!(freq.into_iter().nth(0).unwrap().0, Value::King)
524    }
525
526    #[test]
527    fn test_suits_freq() {
528        let c1 = Card::new(Value::King, Suit::Heart);
529        let c2 = Card::new(Value::King, Suit::Spade);
530        let c3 = Card::new(Value::Two, Suit::Heart);
531        let c4 = Card::new(Value::Three, Suit::Diamond);
532        let c5 = Card::new(Value::Four, Suit::Heart);
533
534        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
535        let freq = hand.suits_freq();
536
537        // Should have 3 values (heart, spade, diamond)
538        assert_eq!(freq.len(), 3);
539
540        // Expect 3 hearts and 1 each of spade and diamond
541        assert_eq!(freq.get(&Suit::Heart).unwrap().len(), 3);
542        assert_eq!(freq.get(&Suit::Spade).unwrap().len(), 1);
543        assert_eq!(freq.get(&Suit::Diamond).unwrap().len(), 1);
544
545        // No clubs to be found
546        assert_eq!(freq.get(&Suit::Club), None);
547
548        // Can also check the cards in the vec are as expected
549        assert_eq!(freq.get(&Suit::Heart).unwrap()[0].suit, Suit::Heart);
550        assert_eq!(freq.get(&Suit::Heart).unwrap()[1].suit, Suit::Heart);
551        assert_eq!(freq.get(&Suit::Heart).unwrap()[2].suit, Suit::Heart);
552        assert_eq!(freq.get(&Suit::Spade).unwrap()[0].suit, Suit::Spade);
553        assert_eq!(freq.get(&Suit::Diamond).unwrap()[0].suit, Suit::Diamond);
554    }
555
556    #[test]
557    fn test_best_hand() {
558        let c1 = Card::new(Value::Ace, Suit::Heart);
559        let c2 = Card::new(Value::Two, Suit::Heart);
560        let c3 = Card::new(Value::Three, Suit::Diamond);
561
562        // Best hand is flush five (Ah, Ah, Ah, Ah, Ah)
563        let hand = SelectHand::new(vec![c1, c1, c1, c1, c1]);
564        let best = hand.best_hand().expect("is best hand");
565        assert_eq!(best.rank, HandRank::FlushFive);
566        assert_eq!(best.hand.len(), 5);
567
568        // 4ok is better than flush (Ah, Ah, Ah, Ah, 2h)
569        let hand = SelectHand::new(vec![c1, c1, c1, c1, c2]);
570        let best = hand.best_hand().expect("is best hand");
571        assert_eq!(best.clone().rank, HandRank::FourOfAKind);
572        assert_eq!(best.hand.len(), 4);
573
574        // Two pair is better than pair (Ah, Ah, 2h, 2h, 3d)
575        let hand = SelectHand::new(vec![c1, c1, c2, c2, c3]);
576        let best = hand.best_hand().expect("is best hand");
577        assert_eq!(best.clone().rank, HandRank::TwoPair);
578        assert_eq!(best.hand.len(), 4);
579
580        // At worst, we get a high card (Ah, 2h, 3d)
581        let hand = SelectHand::new(vec![c1, c2, c3]);
582        let best = hand.best_hand().expect("is best hand");
583        assert_eq!(best.clone().rank, HandRank::HighCard);
584        assert_eq!(best.hand.len(), 1);
585    }
586
587    #[test]
588    fn test_highcard() {
589        let c1 = Card::new(Value::Ace, Suit::Heart);
590        let c2 = Card::new(Value::King, Suit::Heart);
591        let c3 = Card::new(Value::Three, Suit::Diamond);
592        let c4 = Card::new(Value::Four, Suit::Diamond);
593        let c5 = Card::new(Value::Five, Suit::Diamond);
594        let c6 = Card::new(Value::Six, Suit::Diamond);
595
596        // Valid 5 (A, K, 3, 4, 5)
597        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
598        let hc = hand.is_highcard();
599        assert_eq!(hc.clone().unwrap().len(), 1);
600        assert_eq!(hc.unwrap().0[0].value, Value::Ace);
601
602        // Valid 5 (K, A, 3, 4, 5)
603        let hand = SelectHand::new(vec![c2, c1, c3, c4, c5]);
604        let hc = hand.is_highcard();
605        assert_eq!(hc.clone().unwrap().len(), 1);
606        assert_eq!(hc.unwrap().0[0].value, Value::Ace);
607
608        // Valid 5 (K, 3, 4, 5, 6)
609        let hand = SelectHand::new(vec![c2, c3, c4, c5, c6]);
610        let hc = hand.is_highcard();
611        assert_eq!(hc.clone().unwrap().len(), 1);
612        assert_eq!(hc.unwrap().0[0].value, Value::King);
613
614        // Valid 4 (K, 3, 4, 5)
615        let hand = SelectHand::new(vec![c2, c3, c4, c5]);
616        let hc = hand.is_highcard();
617        assert_eq!(hc.clone().unwrap().len(), 1);
618        assert_eq!(hc.unwrap().0[0].value, Value::King);
619
620        // Valid 3 (K, 3, 4)
621        let hand = SelectHand::new(vec![c2, c3, c4]);
622        let hc = hand.is_highcard();
623        assert_eq!(hc.clone().unwrap().len(), 1);
624        assert_eq!(hc.unwrap().0[0].value, Value::King);
625
626        // Valid 2 (K, 3)
627        let hand = SelectHand::new(vec![c2, c3]);
628        let hc = hand.is_highcard();
629        assert_eq!(hc.clone().unwrap().len(), 1);
630        assert_eq!(hc.unwrap().0[0].value, Value::King);
631
632        // Valid 1 (K)
633        let hand = SelectHand::new(vec![c2]);
634        let hc = hand.is_highcard();
635        assert_eq!(hc.clone().unwrap().len(), 1);
636        assert_eq!(hc.unwrap().0[0].value, Value::King);
637    }
638
639    #[test]
640    fn test_pair() {
641        let c1 = Card::new(Value::King, Suit::Heart);
642        let c2 = Card::new(Value::King, Suit::Diamond);
643        let c3 = Card::new(Value::Three, Suit::Diamond);
644        let c4 = Card::new(Value::Four, Suit::Diamond);
645        let c5 = Card::new(Value::Five, Suit::Diamond);
646        let c6 = Card::new(Value::Six, Suit::Diamond);
647
648        // Valid 5 (K, K, 3, 4, 5)
649        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
650        let is_2 = hand.is_pair();
651        assert_eq!(is_2.unwrap().len(), 2);
652
653        // Valid 4 (K, K, 3, 4)
654        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
655        let is_2 = hand.is_pair();
656        assert_eq!(is_2.unwrap().len(), 2);
657
658        // Valid 3 (K, K, 3)
659        let hand = SelectHand::new(vec![c1, c2, c3]);
660        let is_2 = hand.is_pair();
661        assert_eq!(is_2.unwrap().len(), 2);
662
663        // Valid 2 (K, K)
664        let hand = SelectHand::new(vec![c1, c2]);
665        let is_2 = hand.is_pair();
666        assert_eq!(is_2.unwrap().len(), 2);
667
668        // Invalid 1 (K)
669        let hand = SelectHand::new(vec![c1]);
670        let is_2 = hand.is_pair();
671        assert_eq!(is_2, None);
672
673        // Invalid 2 (K, 3)
674        let hand = SelectHand::new(vec![c1, c3]);
675        let is_2 = hand.is_pair();
676        assert_eq!(is_2, None);
677
678        // Invalid 3 (K, 3, 4)
679        let hand = SelectHand::new(vec![c1, c3, c4]);
680        let is_2 = hand.is_pair();
681        assert_eq!(is_2, None);
682
683        // Invalid 4 (K, 3, 4, 5)
684        let hand = SelectHand::new(vec![c1, c3, c4, c5]);
685        let is_2 = hand.is_pair();
686        assert_eq!(is_2, None);
687
688        // Invalid 5 (K, 3, 4, 5, 6)
689        let hand = SelectHand::new(vec![c1, c3, c4, c5, c6]);
690        let is_2 = hand.is_pair();
691        assert_eq!(is_2, None);
692    }
693
694    #[test]
695    fn test_two_pair() {
696        let c1 = Card::new(Value::King, Suit::Heart);
697        let c2 = Card::new(Value::King, Suit::Spade);
698        let c3 = Card::new(Value::Four, Suit::Diamond);
699        let c4 = Card::new(Value::Four, Suit::Heart);
700        let not1 = Card::new(Value::Two, Suit::Heart);
701        let not2 = Card::new(Value::Three, Suit::Heart);
702
703        // Valid 5 (K, K, 4, 4, 2)
704        let hand = SelectHand::new(vec![c1, c2, c3, c4, not1]);
705        let tp = hand.is_two_pair();
706        assert_eq!(tp.unwrap().len(), 4);
707
708        // Valid 4 (K, K, 4, 4)
709        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
710        let tp = hand.is_two_pair();
711        assert_eq!(tp.unwrap().len(), 4);
712
713        // Invalid 5 (K, K, K, K, 2)
714        let hand = SelectHand::new(vec![c1, c1, c2, c2, not1]);
715        let tp = hand.is_two_pair();
716        assert_eq!(tp, None);
717
718        // Invalid 5 (K, 4, 3, 2, 2)
719        let hand = SelectHand::new(vec![c1, c4, not1, not2, not2]);
720        let tp = hand.is_two_pair();
721        assert_eq!(tp, None);
722
723        // Invalid 5 (K, K, 4, 3, 2)
724        let hand = SelectHand::new(vec![c1, c1, c4, not1, not2]);
725        let tp = hand.is_two_pair();
726        assert_eq!(tp, None);
727
728        // Invalid 4 (K, K, 4, 2)
729        let hand = SelectHand::new(vec![c1, c2, c4, not1]);
730        let tp = hand.is_two_pair();
731        assert_eq!(tp, None);
732    }
733
734    #[test]
735    fn test_three_of_kind() {
736        let c1 = Card::new(Value::King, Suit::Heart);
737        let c2 = Card::new(Value::King, Suit::Spade);
738        let c3 = Card::new(Value::King, Suit::Heart);
739        let not1 = Card::new(Value::Ace, Suit::Heart);
740        let not2 = Card::new(Value::Two, Suit::Heart);
741
742        // Valid 5 (K, K, K, A, 2)
743        let hand = SelectHand::new(vec![c1, c2, c3, not1, not2]);
744        let is_3 = hand.is_three_of_kind();
745        assert_eq!(is_3.unwrap().len(), 3);
746
747        // Valid 4 (K, K, K, A)
748        let hand = SelectHand::new(vec![c1, c2, c3, not1]);
749        let is_3 = hand.is_three_of_kind();
750        assert_eq!(is_3.unwrap().len(), 3);
751
752        // Valid 3 (K, K, K)
753        let hand = SelectHand::new(vec![c1, c2, c3]);
754        let is_3 = hand.is_three_of_kind();
755        assert_eq!(is_3.unwrap().len(), 3);
756
757        // Invalid 3 (K, K, A)
758        let hand = SelectHand::new(vec![c1, c2, not1]);
759        let is_3 = hand.is_three_of_kind();
760        assert_eq!(is_3, None);
761
762        // Invalid 4 (K, K, A, A),
763        let hand = SelectHand::new(vec![c1, c2, not1, not1]);
764        let is_3 = hand.is_three_of_kind();
765        assert_eq!(is_3, None);
766
767        // Invalid 5 (K, K, A, A, 2),
768        let hand = SelectHand::new(vec![c1, c2, not1, not1, not2]);
769        let is_3 = hand.is_three_of_kind();
770        assert_eq!(is_3, None);
771
772        // Invalid 2 (K, K)
773        let hand = SelectHand::new(vec![c1, c2]);
774        let is_3 = hand.is_three_of_kind();
775        assert_eq!(is_3, None);
776    }
777
778    #[test]
779    fn test_straight() {
780        let c1 = Card::new(Value::Ace, Suit::Heart);
781        let c2 = Card::new(Value::Two, Suit::Heart);
782        let c3 = Card::new(Value::Three, Suit::Heart);
783        let c4 = Card::new(Value::Four, Suit::Heart);
784        let c5 = Card::new(Value::Five, Suit::Heart);
785        let c6 = Card::new(Value::Six, Suit::Diamond);
786        let c7 = Card::new(Value::Seven, Suit::Diamond);
787
788        // Valid 5 (2, 3, 4 ,5 ,6)
789        let hand = SelectHand::new(vec![c2, c3, c4, c5, c6]);
790        let straight = hand.is_straight();
791        assert_eq!(straight.unwrap().len(), 5);
792
793        // Valid 5 with low ace (A, 2, 3, 4 ,5)
794        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
795        let straight = hand.is_straight();
796        assert_eq!(straight.unwrap().len(), 5);
797
798        // Invalid 5 (2, 3, 4, 5, 7)
799        let hand = SelectHand::new(vec![c2, c3, c4, c5, c7]);
800        let straight = hand.is_straight();
801        assert_eq!(straight, None);
802
803        // Invalid 5 with low ace (A, 2, 3, 4, 7)
804        let hand = SelectHand::new(vec![c1, c2, c3, c4, c7]);
805        let straight = hand.is_straight();
806        assert_eq!(straight, None);
807
808        // Invalid 4 (2, 3, 4, 5)
809        let hand = SelectHand::new(vec![c2, c3, c4, c5]);
810        let straight = hand.is_straight();
811        assert_eq!(straight, None);
812    }
813
814    #[test]
815    fn test_flush() {
816        let c1 = Card::new(Value::King, Suit::Heart);
817        let c2 = Card::new(Value::Queen, Suit::Heart);
818        let c3 = Card::new(Value::Jack, Suit::Heart);
819        let c4 = Card::new(Value::Seven, Suit::Heart);
820        let c5 = Card::new(Value::Eight, Suit::Heart);
821        let not = Card::new(Value::Ace, Suit::Diamond);
822
823        // Valid 5 (h, h, h, h, h)
824        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
825        let flush = hand.is_flush();
826        assert_eq!(flush.unwrap().len(), 5);
827
828        // Valid 5 from 7 cards (h, h, h, h, h, d, d)
829        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5, not, not]);
830        let flush = hand.is_flush();
831        assert_eq!(flush.unwrap().len(), 5);
832
833        // Invalid 5 (h, h, h, h, d)
834        let hand = SelectHand::new(vec![c1, c2, c3, c4, not]);
835        let flush = hand.is_flush();
836        assert_eq!(flush, None);
837
838        // Invalid 4 (h, h, h, h)
839        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
840        let flush = hand.is_flush();
841        assert_eq!(flush, None);
842    }
843
844    #[test]
845    fn test_fullhouse() {
846        let c1 = Card::new(Value::King, Suit::Heart);
847        let c2 = Card::new(Value::King, Suit::Spade);
848        let c3 = Card::new(Value::King, Suit::Heart);
849        let c4 = Card::new(Value::Four, Suit::Diamond);
850        let c5 = Card::new(Value::Four, Suit::Heart);
851        let not1 = Card::new(Value::Two, Suit::Heart);
852        let not2 = Card::new(Value::Three, Suit::Heart);
853
854        // Valid 5 (K, K, K, 4, 4)
855        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
856        let is_fh = hand.is_fullhouse();
857        assert_eq!(is_fh.unwrap().len(), 5);
858
859        // Valid 5 from 7 cards (K, K, K, 4, 4, 2, 3)
860        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5, not1, not2]);
861        let is_fh = hand.is_fullhouse();
862        assert_eq!(is_fh.unwrap().len(), 5);
863
864        // Invalid 5 (K, K, K, K, 2)
865        let hand = SelectHand::new(vec![c1, c2, c3, c3, not1]);
866        let is_fh = hand.is_fullhouse();
867        assert_eq!(is_fh, None);
868
869        // Invalid 5 (K, K, 4, 4, 2)
870        let hand = SelectHand::new(vec![c1, c2, c4, c5, not1]);
871        let is_fh = hand.is_fullhouse();
872        assert_eq!(is_fh, None);
873
874        // Invalid 4 (K, K, 4, 4)
875        let hand = SelectHand::new(vec![c1, c2, c4, c5]);
876        let is_fh = hand.is_fullhouse();
877        assert_eq!(is_fh, None);
878    }
879
880    #[test]
881    fn test_four_of_kind() {
882        let c1 = Card::new(Value::King, Suit::Heart);
883        let c2 = Card::new(Value::King, Suit::Spade);
884        let c3 = Card::new(Value::King, Suit::Heart);
885        let c4 = Card::new(Value::King, Suit::Diamond);
886        let not = Card::new(Value::Ace, Suit::Heart);
887
888        // Valid 4 (K, K, K, K)
889        let hand = SelectHand::new(vec![c1, c2, c3, c4, not]);
890        let is_4 = hand.is_four_of_kind();
891        assert_eq!(is_4.unwrap().len(), 4);
892
893        // Valid 4 from 7 cards (K, K, K, K, A, A, A)
894        let hand = SelectHand::new(vec![c1, c2, c3, c4, not, not, not]);
895        let is_4 = hand.is_four_of_kind();
896        assert_eq!(is_4.unwrap().len(), 4);
897
898        // Invalid 4 (K, K, K, A)
899        let hand = SelectHand::new(vec![c1, c2, c3, not]);
900        let is_4 = hand.is_four_of_kind();
901        assert_eq!(is_4, None);
902
903        // Invalid 3 (K, K, K)
904        let hand = SelectHand::new(vec![c1, c2, c3]);
905        let is_4 = hand.is_four_of_kind();
906        assert_eq!(is_4, None);
907    }
908
909    #[test]
910    fn test_straight_flush() {
911        let c1 = Card::new(Value::Ace, Suit::Heart);
912        let c2 = Card::new(Value::Two, Suit::Heart);
913        let c3 = Card::new(Value::Three, Suit::Heart);
914        let c4 = Card::new(Value::Four, Suit::Heart);
915        let c5 = Card::new(Value::Five, Suit::Heart);
916        let c6 = Card::new(Value::Six, Suit::Heart);
917        let not1 = Card::new(Value::Seven, Suit::Heart);
918        let not2 = Card::new(Value::Six, Suit::Diamond);
919
920        // Valid 5 (2h, 3h, 4h, 5h ,6h)
921        let hand = SelectHand::new(vec![c2, c3, c4, c5, c6]);
922        let sf = hand.is_straight_flush();
923        assert_eq!(sf.unwrap().len(), 5);
924
925        // Valid 5 with low ace (Ah, 2h, 3h, 4h, 5h)
926        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
927        let sf = hand.is_straight_flush();
928        assert_eq!(sf.unwrap().len(), 5);
929
930        // Invalid 5, wrong value (2h, 3h, 4h, 5h, 7h)
931        let hand = SelectHand::new(vec![c2, c3, c4, c5, not1]);
932        let sf = hand.is_straight_flush();
933        assert_eq!(sf, None);
934
935        // Invalid 5, wrong suit (2h, 3h, 4h, 5h, 6d)
936        let hand = SelectHand::new(vec![c2, c3, c4, c5, not2]);
937        let sf = hand.is_straight_flush();
938        assert_eq!(sf, None);
939
940        // Invalid 4 (2h, 3h, 4h, 5h)
941        let hand = SelectHand::new(vec![c2, c3, c4, c5]);
942        let sf = hand.is_straight_flush();
943        assert_eq!(sf, None);
944    }
945
946    #[test]
947    fn test_royal_flush() {
948        let c1 = Card::new(Value::Ten, Suit::Spade);
949        let c2 = Card::new(Value::Jack, Suit::Spade);
950        let c3 = Card::new(Value::Queen, Suit::Spade);
951        let c4 = Card::new(Value::King, Suit::Spade);
952        let c5 = Card::new(Value::Ace, Suit::Spade);
953        let not1 = Card::new(Value::Nine, Suit::Spade);
954        let not2 = Card::new(Value::Ace, Suit::Diamond);
955
956        // Valid 5 (10s, Js, Qs, Ks, As)
957        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
958        let rf = hand.is_royal_flush();
959        assert_eq!(rf.unwrap().len(), 5);
960
961        // Valid 5, scrambled input order (Js, 10s, Ks, Qs, As)
962        let hand = SelectHand::new(vec![c2, c1, c4, c3, c5]);
963        let rf = hand.is_royal_flush();
964        assert_eq!(rf.unwrap().len(), 5);
965
966        // Invalid 5, wrong value (9s, Js, Qs, Ks, As)
967        let hand = SelectHand::new(vec![not1, c2, c3, c4, c5]);
968        let rf = hand.is_royal_flush();
969        assert_eq!(rf, None);
970
971        // Invalid 5, wrong suit (10s, Js, Qs, Ks, Ad)
972        let hand = SelectHand::new(vec![c1, c2, c3, c4, not2]);
973        let rf = hand.is_royal_flush();
974        assert_eq!(rf, None);
975
976        // Invalid 4 (2h, 3h, 4h, 5h)
977        let hand = SelectHand::new(vec![c2, c3, c4, c5]);
978        let rf = hand.is_royal_flush();
979        assert_eq!(rf, None);
980    }
981
982    #[test]
983    fn test_five_of_kind() {
984        let c1 = Card::new(Value::King, Suit::Heart);
985        let c2 = Card::new(Value::King, Suit::Spade);
986        let c3 = Card::new(Value::King, Suit::Heart);
987        let c4 = Card::new(Value::King, Suit::Diamond);
988        let c5 = Card::new(Value::King, Suit::Heart);
989        let not = Card::new(Value::Ace, Suit::Heart);
990
991        // Valid 5 (K, K, K, K, K)
992        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
993        let is_5 = hand.is_five_of_kind();
994        assert_eq!(is_5.unwrap().len(), 5);
995
996        // Valid 5 from 7 cards (K, K, K, K, K, A, A)
997        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5, not, not]);
998        let is_5 = hand.is_five_of_kind();
999        assert_eq!(is_5.unwrap().len(), 5);
1000
1001        // Invalid 5 (K, K, K, K, A)
1002        let hand = SelectHand::new(vec![c1, c2, c3, c4, not]);
1003        let is_5 = hand.is_five_of_kind();
1004        assert_eq!(is_5, None);
1005
1006        // Invalid 4 (K, K, K, K)
1007        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
1008        let is_5 = hand.is_five_of_kind();
1009        assert_eq!(is_5, None);
1010    }
1011
1012    #[test]
1013    fn test_flush_house() {
1014        let c1 = Card::new(Value::King, Suit::Heart);
1015        let c2 = Card::new(Value::King, Suit::Heart);
1016        let c3 = Card::new(Value::King, Suit::Heart);
1017        let c4 = Card::new(Value::Ace, Suit::Heart);
1018        let c5 = Card::new(Value::Ace, Suit::Heart);
1019        let not1 = Card::new(Value::Two, Suit::Heart);
1020        let not2 = Card::new(Value::Ace, Suit::Diamond);
1021
1022        // Valid 5 (Kh, Kh, Kh, Ah, Ah)
1023        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
1024        let fh = hand.is_flush_house();
1025        assert_eq!(fh.unwrap().len(), 5);
1026
1027        // Invalid 5 (Kh, Kh, Kh, Ah, 2h)
1028        let hand = SelectHand::new(vec![c1, c2, c3, c4, not1]);
1029        let fh = hand.is_flush_house();
1030        assert_eq!(fh, None);
1031
1032        // Invalid 5 (Kh, Kh, Kh, Ah, Ad)
1033        let hand = SelectHand::new(vec![c1, c2, c3, c4, not2]);
1034        let fh = hand.is_flush_house();
1035        assert_eq!(fh, None);
1036
1037        // Invalid 4 (Kh, Kh, Kh, Ah)
1038        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
1039        let fh = hand.is_flush_house();
1040        assert_eq!(fh, None);
1041    }
1042
1043    #[test]
1044    fn test_flush_five() {
1045        let c1 = Card::new(Value::King, Suit::Heart);
1046        let c2 = Card::new(Value::King, Suit::Heart);
1047        let c3 = Card::new(Value::King, Suit::Heart);
1048        let c4 = Card::new(Value::King, Suit::Heart);
1049        let c5 = Card::new(Value::King, Suit::Heart);
1050        let not1 = Card::new(Value::Two, Suit::Heart);
1051        let not2 = Card::new(Value::King, Suit::Diamond);
1052
1053        // Valid 5 (Kh, Kh, Kh, Kh, Kh)
1054        let hand = SelectHand::new(vec![c1, c2, c3, c4, c5]);
1055        let ff = hand.is_flush_five();
1056        assert_eq!(ff.unwrap().len(), 5);
1057
1058        // Invalid 5 (Kh, Kh, Kh, Kh, 2h)
1059        let hand = SelectHand::new(vec![c1, c2, c3, c4, not1]);
1060        let ff = hand.is_flush_five();
1061        assert_eq!(ff, None);
1062
1063        // Invalid 5 (Kh, Kh, Kh, Kh, Kd)
1064        let hand = SelectHand::new(vec![c1, c2, c3, c4, not2]);
1065        let ff = hand.is_flush_five();
1066        assert_eq!(ff, None);
1067
1068        // Invalid 4 (Kh, Kh, Kh, Kh)
1069        let hand = SelectHand::new(vec![c1, c2, c3, c4]);
1070        let ff = hand.is_flush_five();
1071        assert_eq!(ff, None);
1072    }
1073}