fudd/types/arrays/
six_card.rs1use crate::analysis::eval::Eval;
2use crate::analysis::evals::Evals;
3use crate::types::arrays::five_card::FiveCard;
4use crate::types::arrays::three_card::ThreeCard;
5use crate::types::arrays::two_card::TwoCard;
6use crate::types::arrays::{Evaluable, Vectorable};
7use crate::types::playing_card::PlayingCard;
8use crate::types::playing_cards::PlayingCards;
9use crate::types::poker_cards::PokerCards;
10use crate::types::U32Card;
11use ckc_rs::{CardNumber, HandError, PokerCard};
12
13#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
14pub struct SixCard([U32Card; 6]);
15
16impl SixCard {
17 pub const PERMUTATIONS: [[u8; 5]; 6] = [
19 [0, 1, 2, 3, 4],
20 [0, 1, 2, 3, 5],
21 [0, 1, 2, 4, 5],
22 [0, 1, 3, 4, 5],
23 [0, 2, 3, 4, 5],
24 [1, 2, 3, 4, 5],
25 ];
26
27 #[must_use]
28 pub fn from_1_and_2_and_3(one: U32Card, two: TwoCard, three: ThreeCard) -> SixCard {
29 SixCard::from([
30 one,
31 two.first(),
32 two.second(),
33 three.first(),
34 three.second(),
35 three.third(),
36 ])
37 }
38
39 #[must_use]
41 pub fn first(&self) -> U32Card {
42 self.0[0]
43 }
44
45 #[must_use]
46 pub fn second(&self) -> U32Card {
47 self.0[1]
48 }
49
50 #[must_use]
51 pub fn third(&self) -> U32Card {
52 self.0[2]
53 }
54
55 #[must_use]
56 pub fn forth(&self) -> U32Card {
57 self.0[3]
58 }
59
60 #[must_use]
61 pub fn fifth(&self) -> U32Card {
62 self.0[4]
63 }
64
65 #[must_use]
66 pub fn sixth(&self) -> U32Card {
67 self.0[5]
68 }
69 }
71
72impl Evaluable for SixCard {
73 fn evals(&self) -> Evals {
74 let mut evals = Evals::default();
75 let mut subhand: [U32Card; 5] = [CardNumber::BLANK; 5];
76
77 for ids in &crate::types::arrays::six_card::SixCard::PERMUTATIONS {
78 for i in 0..5 {
79 subhand[i] = self.0[ids[i] as usize];
80 }
81 let (hand, eval) = FiveCard::from(subhand).evaluate();
82 evals.push(Eval::raw(hand, eval));
83 }
84 evals
85 }
86}
87
88impl From<[PlayingCard; 6]> for SixCard {
89 fn from(array: [PlayingCard; 6]) -> Self {
90 SixCard::from([
91 array[0].as_u32(),
92 array[1].as_u32(),
93 array[2].as_u32(),
94 array[3].as_u32(),
95 array[4].as_u32(),
96 array[5].as_u32(),
97 ])
98 }
99}
100
101impl From<[U32Card; 6]> for SixCard {
102 fn from(value: [U32Card; 6]) -> Self {
103 SixCard(value)
104 }
105}
106
107impl TryFrom<&PlayingCards> for SixCard {
108 type Error = HandError;
109
110 fn try_from(playing_cards: &PlayingCards) -> Result<Self, Self::Error> {
111 match playing_cards.len() {
112 0..=5 => Err(HandError::NotEnoughCards),
113 6 => Ok(SixCard::from([
114 *playing_cards.get_index(0).unwrap(),
115 *playing_cards.get_index(1).unwrap(),
116 *playing_cards.get_index(2).unwrap(),
117 *playing_cards.get_index(3).unwrap(),
118 *playing_cards.get_index(4).unwrap(),
119 *playing_cards.get_index(5).unwrap(),
120 ])),
121 _ => Err(HandError::TooManyCards),
122 }
123 }
124}
125
126impl TryFrom<&PokerCards> for SixCard {
127 type Error = HandError;
128
129 fn try_from(poker_cards: &PokerCards) -> Result<Self, Self::Error> {
130 SixCard::try_from(&PlayingCards::from(poker_cards))
131 }
132}
133
134impl TryFrom<&'static str> for SixCard {
135 type Error = HandError;
136
137 fn try_from(value: &'static str) -> Result<Self, Self::Error> {
197 match PokerCards::try_from(value) {
198 Ok(cards) => SixCard::try_from(&cards),
199 Err(e) => Err(e),
200 }
201 }
202}
203
204impl Vectorable for SixCard {
205 #[must_use]
206 fn to_vec(&self) -> Vec<U32Card> {
207 self.0.to_vec()
208 }
209}
210
211#[cfg(test)]
212#[allow(non_snake_case)]
213mod types_arrays_six_card_tests {
214 use super::*;
215 use ckc_rs::hand_rank::HandRankClass;
216 use rstest::rstest;
217
218 #[test]
219 fn eval() {
220 let ckcs = SixCard::try_from("6H AH KH QH JH TH").unwrap().eval();
221
222 assert_eq!(ckcs.rank.class, HandRankClass::RoyalFlush);
223 }
224
225 #[rstest]
226 #[case("9H AH KH QH JH TH", "AH KH QH JH TH")]
227 #[case("9H AH KS QH JD TH", "A♥ K♠ Q♥ J♦ T♥")]
228 #[case("9H AH KS QH JD TH", "A♥ K♠ Q♥ J♦ T♥")]
229 #[case("9H TD KS QH 9D TH", "TH TD 9H 9D KS")]
230 fn eval__many(#[case] index: &'static str, #[case] best_index: &'static str) {
231 let hand = SixCard::try_from(index).unwrap().eval();
232
233 let expected = FiveCard::try_from(best_index).unwrap();
234
235 assert_eq!(hand.hand, expected);
236 }
237
238 #[test]
239 fn try_from__poker_cards() {
240 let poker_cards = PokerCards::try_from("9H AS KS QS JS TS").unwrap();
241
242 let a = SixCard::try_from(&poker_cards).unwrap();
243
244 assert_eq!(*poker_cards.get(0).unwrap(), a.first());
245 assert_eq!(*poker_cards.get(1).unwrap(), a.second());
246 assert_eq!(*poker_cards.get(2).unwrap(), a.third());
247 assert_eq!(*poker_cards.get(3).unwrap(), a.forth());
248 assert_eq!(*poker_cards.get(4).unwrap(), a.fifth());
249 assert_eq!(*poker_cards.get(5).unwrap(), a.sixth());
250 }
251}