1use crate::analysis::eval::Eval;
2use crate::analysis::evals::Evals;
3use crate::types::arrays::five_card::FiveCard;
4use crate::types::arrays::two_card::TwoCard;
5use crate::types::arrays::{Evaluable, Vectorable};
6use crate::types::playing_card::PlayingCard;
7use crate::types::playing_cards::PlayingCards;
8use crate::types::poker_cards::PokerCards;
9use crate::types::U32Card;
10use ckc_rs::cards::seven::Seven;
11use ckc_rs::{CardNumber, HandError, PokerCard};
12use core::fmt;
13use serde::{Deserialize, Serialize};
14use std::fmt::Formatter;
15
16#[derive(
17 Serialize, Deserialize, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd,
18)]
19pub struct SevenCard([U32Card; 7]);
20
21impl SevenCard {
22 #[must_use]
23 pub fn new(two: TwoCard, five: FiveCard) -> SevenCard {
24 SevenCard([
25 two.first(),
26 two.second(),
27 five.first(),
28 five.second(),
29 five.third(),
30 five.forth(),
31 five.fifth(),
32 ])
33 }
34
35 #[must_use]
37 pub fn first(&self) -> U32Card {
38 self.0[0]
39 }
40
41 #[must_use]
42 pub fn second(&self) -> U32Card {
43 self.0[1]
44 }
45
46 #[must_use]
47 pub fn third(&self) -> U32Card {
48 self.0[2]
49 }
50
51 #[must_use]
52 pub fn forth(&self) -> U32Card {
53 self.0[3]
54 }
55
56 #[must_use]
57 pub fn fifth(&self) -> U32Card {
58 self.0[4]
59 }
60
61 #[must_use]
62 pub fn sixth(&self) -> U32Card {
63 self.0[5]
64 }
65
66 #[must_use]
67 pub fn seventh(&self) -> U32Card {
68 self.0[6]
69 }
70 #[must_use]
73 pub fn sort(&self) -> SevenCard {
74 let mut c = *self;
75 c.sort_in_place();
76 c
77 }
78
79 pub fn sort_in_place(&mut self) {
80 self.0.sort_unstable();
81 self.0.reverse();
82 }
83
84 #[must_use]
85 pub fn to_arr(&self) -> [U32Card; 7] {
86 self.0
87 }
88
89 #[must_use]
90 pub fn to_seven(&self) -> Seven {
91 Seven::from(self.to_arr())
92 }
93}
94
95impl fmt::Display for SevenCard {
96 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
97 write!(f, "{}", PlayingCards::from(&self.to_vec()))
98 }
99}
100
101impl Evaluable for SevenCard {
102 fn evals(&self) -> Evals {
103 let mut evals = Evals::default();
104 let mut subhand: [U32Card; 5] = [CardNumber::BLANK; 5];
105
106 for ids in &ckc_rs::cards::seven::Seven::FIVE_CARD_PERMUTATIONS {
107 for i in 0..5 {
108 subhand[i] = self.0[ids[i] as usize];
109 }
110 let (hand, eval) = FiveCard::from(subhand).evaluate();
111 evals.push(Eval::raw(hand, eval));
112 }
113 evals
114 }
115}
116
117impl From<[PlayingCard; 7]> for SevenCard {
118 fn from(array: [PlayingCard; 7]) -> Self {
119 SevenCard::from([
120 array[0].as_u32(),
121 array[1].as_u32(),
122 array[2].as_u32(),
123 array[3].as_u32(),
124 array[4].as_u32(),
125 array[5].as_u32(),
126 array[6].as_u32(),
127 ])
128 }
129}
130
131impl From<[U32Card; 7]> for SevenCard {
132 fn from(array: [U32Card; 7]) -> Self {
133 SevenCard(array)
134 }
135}
136
137impl TryFrom<&PlayingCards> for SevenCard {
138 type Error = HandError;
139
140 fn try_from(playing_cards: &PlayingCards) -> Result<Self, Self::Error> {
141 SevenCard::try_from(&PokerCards::from(playing_cards))
142 }
143}
144
145impl TryFrom<&PokerCards> for SevenCard {
146 type Error = HandError;
147
148 fn try_from(poker_cards: &PokerCards) -> Result<Self, Self::Error> {
149 match poker_cards.len() {
150 0..=6 => Err(HandError::NotEnoughCards),
151 7 => Ok(SevenCard::from([
152 *poker_cards.get(0).unwrap(),
153 *poker_cards.get(1).unwrap(),
154 *poker_cards.get(2).unwrap(),
155 *poker_cards.get(3).unwrap(),
156 *poker_cards.get(4).unwrap(),
157 *poker_cards.get(5).unwrap(),
158 *poker_cards.get(6).unwrap(),
159 ])),
160 _ => Err(HandError::TooManyCards),
161 }
162 }
163}
164
165impl TryFrom<&'static str> for SevenCard {
166 type Error = HandError;
167
168 fn try_from(value: &'static str) -> Result<Self, Self::Error> {
228 match PokerCards::try_from(value) {
229 Ok(cards) => SevenCard::try_from(&cards),
230 Err(e) => Err(e),
231 }
232 }
233}
234
235impl TryFrom<Vec<&PlayingCard>> for SevenCard {
236 type Error = HandError;
237
238 fn try_from(v: Vec<&PlayingCard>) -> Result<Self, Self::Error> {
239 SevenCard::try_from(&PlayingCards::from(v))
240 }
241}
242
243impl Vectorable for SevenCard {
244 #[must_use]
245 fn to_vec(&self) -> Vec<U32Card> {
246 self.0.to_vec()
247 }
248}
249
250#[cfg(test)]
251#[allow(non_snake_case)]
252mod types_arrays_seven_card_tests {
253 use super::*;
254 use ckc_rs::hand_rank::HandRank;
255 use ckc_rs::CardNumber;
256
257 #[test]
258 fn sort() {
259 let seven = SevenCard::try_from("9H AS KS QS JS TS 2H").unwrap().sort();
260
261 assert_eq!("A♠ K♠ Q♠ J♠ T♠ 9♥ 2♥", seven.to_string());
262 }
263
264 #[test]
265 fn sort_in_place() {
266 let mut seven = SevenCard::try_from("9H AS KS QS JS TS 2H").unwrap();
267
268 seven.sort_in_place();
269
270 assert_eq!("A♠ K♠ Q♠ J♠ T♠ 9♥ 2♥", seven.to_string());
271 }
272
273 #[test]
274 fn display() {
275 let playing_cards = SevenCard::try_from("9H AS KS QS JS TS 2H").unwrap();
276
277 assert_eq!("9♥ A♠ K♠ Q♠ J♠ T♠ 2♥", playing_cards.to_string());
278 }
279
280 #[test]
281 fn from__array() {
282 let expected = SevenCard([
283 CardNumber::ACE_CLUBS,
284 CardNumber::KING_CLUBS,
285 CardNumber::QUEEN_CLUBS,
286 CardNumber::JACK_CLUBS,
287 CardNumber::TEN_CLUBS,
288 CardNumber::NINE_CLUBS,
289 CardNumber::EIGHT_CLUBS,
290 ]);
291
292 let actual = SevenCard::from([
293 CardNumber::ACE_CLUBS,
294 CardNumber::KING_CLUBS,
295 CardNumber::QUEEN_CLUBS,
296 CardNumber::JACK_CLUBS,
297 CardNumber::TEN_CLUBS,
298 CardNumber::NINE_CLUBS,
299 CardNumber::EIGHT_CLUBS,
300 ]);
301
302 assert_eq!(expected, actual);
303 }
304
305 #[test]
306 fn eval() {
307 let five_cards = FiveCard::try_from("AC KC QC JC TC").unwrap();
308 let two_cards = TwoCard::try_from("9C 8C").unwrap();
309
310 let seven = SevenCard::new(two_cards, five_cards);
311
312 assert_eq!(five_cards.eval(), seven.eval());
313 }
314
315 #[test]
316 fn evaluable() {
317 let five_cards = FiveCard::try_from("AC KC QC JC TC").unwrap();
318 let two_cards = TwoCard::try_from("9C 8C").unwrap();
319
320 let seven = SevenCard::new(two_cards, five_cards);
321
322 let (hand, hand_rank) = seven.evaluate();
323
324 assert_eq!(HandRank::from(1), hand_rank);
325 assert_eq!(five_cards, hand);
326 }
327
328 #[test]
329 fn try_from__playing_cards() {
330 let playing_cards = PlayingCards::try_from("9H AS KS QS JS TS 2H").unwrap();
331
332 let a = SevenCard::try_from(&playing_cards).unwrap();
333
334 assert_eq!(playing_cards.get_index(0).unwrap().as_u32(), a.first());
335 assert_eq!(playing_cards.get_index(1).unwrap().as_u32(), a.second());
336 assert_eq!(playing_cards.get_index(2).unwrap().as_u32(), a.third());
337 assert_eq!(playing_cards.get_index(3).unwrap().as_u32(), a.forth());
338 assert_eq!(playing_cards.get_index(4).unwrap().as_u32(), a.fifth());
339 assert_eq!(playing_cards.get_index(5).unwrap().as_u32(), a.sixth());
340 assert_eq!(playing_cards.get_index(6).unwrap().as_u32(), a.seventh());
341 }
342
343 #[test]
344 fn try_from__poker_cards() {
345 let poker_cards = PokerCards::try_from("9H AS KS QS JS TS 2H").unwrap();
346
347 let a = SevenCard::try_from(&poker_cards).unwrap();
348
349 assert_eq!(*poker_cards.get(0).unwrap(), a.first());
350 assert_eq!(*poker_cards.get(1).unwrap(), a.second());
351 assert_eq!(*poker_cards.get(2).unwrap(), a.third());
352 assert_eq!(*poker_cards.get(3).unwrap(), a.forth());
353 assert_eq!(*poker_cards.get(4).unwrap(), a.fifth());
354 assert_eq!(*poker_cards.get(5).unwrap(), a.sixth());
355 assert_eq!(*poker_cards.get(6).unwrap(), a.seventh());
356 }
357
358 #[test]
359 fn try_from__vec_playing_card() {
360 let v = vec![
361 &PlayingCard::ACE_SPADES,
362 &PlayingCard::KING_SPADES,
363 &PlayingCard::QUEEN_SPADES,
364 &PlayingCard::JACK_SPADES,
365 &PlayingCard::TEN_SPADES,
366 &PlayingCard::NINE_SPADES,
367 &PlayingCard::EIGHT_SPADES,
368 ];
369
370 let seven = SevenCard::try_from(v).unwrap();
371
372 assert_eq!("A♠ K♠ Q♠ J♠ T♠ 9♠ 8♠", seven.to_string())
373 }
374}