1use crate::cards::five::Five;
2use crate::cards::two::Two;
3use crate::cards::{HandRanker, HandValidator, Permutator};
4use crate::hand_rank::HandRankValue;
5use crate::{CKCNumber, HandError, PokerCard, Shifty};
6use core::slice::Iter;
7use serde::{Deserialize, Serialize};
8
9#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
10pub struct Seven([CKCNumber; 7]);
11
12impl Seven {
13 pub const FIVE_CARD_PERMUTATIONS: [[u8; 5]; 21] = [
15 [0, 1, 2, 3, 4],
16 [0, 1, 2, 3, 5],
17 [0, 1, 2, 3, 6],
18 [0, 1, 2, 4, 5],
19 [0, 1, 2, 4, 6],
20 [0, 1, 2, 5, 6],
21 [0, 1, 3, 4, 5],
22 [0, 1, 3, 4, 6],
23 [0, 1, 3, 5, 6],
24 [0, 1, 4, 5, 6],
25 [0, 2, 3, 4, 5],
26 [0, 2, 3, 4, 6],
27 [0, 2, 3, 5, 6],
28 [0, 2, 4, 5, 6],
29 [0, 3, 4, 5, 6],
30 [1, 2, 3, 4, 5],
31 [1, 2, 3, 4, 6],
32 [1, 2, 3, 5, 6],
33 [1, 2, 4, 5, 6],
34 [1, 3, 4, 5, 6],
35 [2, 3, 4, 5, 6],
36 ];
37
38 #[must_use]
39 pub fn new(two: Two, five: Five) -> Self {
40 Self([
41 two.first(),
42 two.second(),
43 five.first(),
44 five.second(),
45 five.third(),
46 five.forth(),
47 five.fifth(),
48 ])
49 }
50
51 #[must_use]
54 pub fn second(&self) -> CKCNumber {
55 self.0[1]
56 }
57
58 #[must_use]
59 pub fn third(&self) -> CKCNumber {
60 self.0[2]
61 }
62
63 #[must_use]
64 pub fn forth(&self) -> CKCNumber {
65 self.0[3]
66 }
67
68 #[must_use]
69 pub fn fifth(&self) -> CKCNumber {
70 self.0[4]
71 }
72
73 #[must_use]
74 pub fn sixth(&self) -> CKCNumber {
75 self.0[5]
76 }
77
78 #[must_use]
79 pub fn seventh(&self) -> CKCNumber {
80 self.0[6]
81 }
82
83 pub fn set_first(&mut self, card_number: CKCNumber) {
84 self.0[0] = card_number;
85 }
86
87 pub fn set_second(&mut self, card_number: CKCNumber) {
88 self.0[1] = card_number;
89 }
90
91 pub fn set_third(&mut self, card_number: CKCNumber) {
92 self.0[2] = card_number;
93 }
94
95 pub fn set_forth(&mut self, card_number: CKCNumber) {
96 self.0[3] = card_number;
97 }
98
99 pub fn set_fifth(&mut self, card_number: CKCNumber) {
100 self.0[4] = card_number;
101 }
102
103 pub fn set_sixth(&mut self, card_number: CKCNumber) {
104 self.0[5] = card_number;
105 }
106
107 pub fn set_seventh(&mut self, card_number: CKCNumber) {
108 self.0[6] = card_number;
109 }
110
111 #[must_use]
112 pub fn to_arr(&self) -> [CKCNumber; 7] {
113 self.0
114 }
115
116 fn from_index(index: &str) -> Option<[CKCNumber; 7]> {
119 let mut esses = index.split_whitespace();
120
121 let first = CKCNumber::from_index(esses.next()?);
122 let second = CKCNumber::from_index(esses.next()?);
123 let third = CKCNumber::from_index(esses.next()?);
124 let forth = CKCNumber::from_index(esses.next()?);
125 let fifth = CKCNumber::from_index(esses.next()?);
126 let sixth = CKCNumber::from_index(esses.next()?);
127 let seventh = CKCNumber::from_index(esses.next()?);
128 let hand: [CKCNumber; 7] = [first, second, third, forth, fifth, sixth, seventh];
129 Some(hand)
130 }
131}
132
133impl From<[CKCNumber; 7]> for Seven {
134 fn from(array: [CKCNumber; 7]) -> Self {
135 Seven(array)
136 }
137}
138
139impl HandRanker for Seven {
140 fn hand_rank_value_and_hand(&self) -> (HandRankValue, Five) {
141 let mut best_hrv: HandRankValue = 0u16;
142 let mut best_hand = Five::default();
143
144 for perm in Seven::FIVE_CARD_PERMUTATIONS {
145 let hand = self.five_from_permutation(perm);
146 let hrv = hand.hand_rank_value();
147 if (best_hrv == 0) || hrv != 0 && hrv < best_hrv {
148 best_hrv = hrv;
149 best_hand = hand;
150 }
151 }
152
153 (best_hrv, best_hand.sort())
154 }
155
156 fn hand_rank_value_validated(&self) -> HandRankValue {
157 if !self.is_valid() {
158 return crate::hand_rank::NO_HAND_RANK_VALUE;
159 }
160 self.hand_rank_value()
161 }
162}
163
164impl HandValidator for Seven {
165 fn are_unique(&self) -> bool {
166 let sorted = self.sort();
167 let mut last: CKCNumber = u32::MAX;
168 for c in sorted.iter() {
169 if *c >= last {
170 return false;
171 }
172 last = *c;
173 }
174 true
175 }
176
177 fn first(&self) -> CKCNumber {
178 self.0[0]
179 }
180
181 fn sort(&self) -> Seven {
182 let mut array = *self;
183 array.sort_in_place();
184 array
185 }
186
187 fn sort_in_place(&mut self) {
188 self.0.sort_unstable();
189 self.0.reverse();
190 }
191
192 fn iter(&self) -> Iter<'_, CKCNumber> {
193 self.0.iter()
194 }
195}
196
197impl Permutator for Seven {
198 fn five_from_permutation(&self, permutation: [u8; 5]) -> Five {
199 Five::new(
200 self.0[permutation[0] as usize],
201 self.0[permutation[1] as usize],
202 self.0[permutation[2] as usize],
203 self.0[permutation[3] as usize],
204 self.0[permutation[4] as usize],
205 )
206 }
207}
208
209impl Shifty for Seven {
210 fn shift_suit(&self) -> Self {
211 Seven([
212 self.first().shift_suit(),
213 self.second().shift_suit(),
214 self.third().shift_suit(),
215 self.forth().shift_suit(),
216 self.fifth().shift_suit(),
217 self.sixth().shift_suit(),
218 self.seventh().shift_suit(),
219 ])
220 }
221}
222
223impl TryFrom<&'static str> for Seven {
224 type Error = HandError;
225
226 fn try_from(index: &'static str) -> Result<Self, Self::Error> {
227 match Seven::from_index(index) {
228 None => Err(HandError::InvalidIndex),
229 Some(seven) => Ok(Seven::from(seven)),
230 }
231 }
232}
233
234#[cfg(test)]
235#[allow(non_snake_case)]
236mod cards_seven_tests {
237 use super::*;
238 use crate::CardNumber;
239
240 #[test]
241 fn sort() {
242 let seven = Seven::try_from("KC 8C QD A♠ 9h 2C T♠").unwrap().sort();
243
244 let expected = Seven::try_from("A♠ KC QD T♠ 9h 8c 2C").unwrap();
245
246 assert_eq!(seven, expected);
247 }
248
249 #[test]
250 fn default() {
251 let seven = Seven::default();
252
253 assert_eq!(seven.first(), CardNumber::BLANK);
254 assert_eq!(seven.second(), CardNumber::BLANK);
255 assert_eq!(seven.third(), CardNumber::BLANK);
256 assert_eq!(seven.forth(), CardNumber::BLANK);
257 assert_eq!(seven.fifth(), CardNumber::BLANK);
258 assert_eq!(seven.sixth(), CardNumber::BLANK);
259 assert_eq!(seven.seventh(), CardNumber::BLANK);
260 assert!(seven.contain_blank());
261 assert!(!seven.are_unique());
262 assert!(!seven.is_valid());
263 }
264
265 #[test]
266 fn five_from_permutation() {
267 let seven = Seven::try_from("A♠ K♠ Q♠ J♠ T♠ 9♠ 8♠").unwrap();
268
269 assert_eq!(
270 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[0]),
271 Five::try_from("A♠ K♠ Q♠ J♠ T♠").unwrap()
272 );
273 assert_eq!(
274 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[1]),
275 Five::try_from("A♠ K♠ Q♠ J♠ 9♠").unwrap()
276 );
277 assert_eq!(
278 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[2]),
279 Five::try_from("A♠ K♠ Q♠ J♠ 8♠").unwrap()
280 );
281 assert_eq!(
282 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[3]),
283 Five::try_from("A♠ K♠ Q♠ T♠ 9♠").unwrap()
284 );
285 assert_eq!(
286 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[4]),
287 Five::try_from("A♠ K♠ Q♠ T♠ 8♠").unwrap()
288 );
289 assert_eq!(
290 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[5]),
291 Five::try_from("A♠ K♠ Q♠ 9♠ 8♠").unwrap()
292 );
293 assert_eq!(
294 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[6]),
295 Five::try_from("A♠ K♠ J♠ T♠ 9♠").unwrap()
296 );
297 assert_eq!(
298 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[7]),
299 Five::try_from("A♠ K♠ J♠ T♠ 8♠").unwrap()
300 );
301 assert_eq!(
302 seven.five_from_permutation(Seven::FIVE_CARD_PERMUTATIONS[20]),
303 Five::try_from("Q♠ J♠ T♠ 9♠ 8♠").unwrap()
304 );
305 }
306
307 #[test]
308 fn hand_rank_value() {
309 assert_eq!(1, Seven::try_from("T♠ A♠ K♠ J♠ Q♠ 9♠ 8♠").unwrap().hand_rank_value());
310 assert_eq!(2, Seven::try_from("T♠ 8♠ K♠ J♠ Q♠ 9♠ 7♠").unwrap().hand_rank_value());
311 assert_eq!(3, Seven::try_from("T♠ 8♠ 7♠ J♠ 6♠ Q♠ 9♠").unwrap().hand_rank_value());
312 assert_eq!(7414, Seven::try_from("9S 8D 7C 5D 4♥ 3D 2D").unwrap().hand_rank_value());
313 }
314
315 #[test]
316 fn hand_rank_value_and_hand() {
317 let (value, hand) = Seven::try_from("T♠ A♠ K♠ J♠ Q♠ 9♠ 8♠")
318 .unwrap()
319 .hand_rank_value_and_hand();
320
321 assert_eq!(hand, Five::try_from("A♠ K♠ Q♠ J♠ T♠").unwrap());
322 assert_eq!(value, 1);
323 }
324
325 #[test]
326 fn shifty__shift_suit() {
327 assert_eq!(
328 Seven::try_from("A♠ K♠ Q♠ J♠ T♠ 9♠ 8♠").unwrap().shift_suit(),
329 Seven::try_from("A♥ K♥ Q♥ J♥ T♥ 9♥ 8♥").unwrap()
330 )
331 }
332
333 #[test]
334 fn try_from__index() {
335 let seven = Seven::try_from("A♠ K♠ Q♠ J♠ T♠ 9♠ 8♠");
336
337 assert!(seven.is_ok());
338 let seven = seven.unwrap();
339 assert_eq!(seven.first(), CardNumber::ACE_SPADES);
340 assert_eq!(seven.second(), CardNumber::KING_SPADES);
341 assert_eq!(seven.third(), CardNumber::QUEEN_SPADES);
342 assert_eq!(seven.forth(), CardNumber::JACK_SPADES);
343 assert_eq!(seven.fifth(), CardNumber::TEN_SPADES);
344 assert_eq!(seven.sixth(), CardNumber::NINE_SPADES);
345 assert_eq!(seven.seventh(), CardNumber::EIGHT_SPADES);
346 assert!(!seven.contain_blank());
347 assert!(seven.are_unique());
348 assert!(seven.is_valid());
349 }
350
351 #[test]
352 fn try_from__index__blank() {
353 let seven = Seven::try_from("A♠ K♠ XX J♠ T♠ 9♠ 8♠");
354
355 assert!(seven.is_ok());
356 let seven = seven.unwrap();
357 assert_eq!(seven.first(), CardNumber::ACE_SPADES);
358 assert_eq!(seven.second(), CardNumber::KING_SPADES);
359 assert_eq!(seven.third(), CardNumber::BLANK);
360 assert_eq!(seven.forth(), CardNumber::JACK_SPADES);
361 assert_eq!(seven.fifth(), CardNumber::TEN_SPADES);
362 assert_eq!(seven.sixth(), CardNumber::NINE_SPADES);
363 assert_eq!(seven.seventh(), CardNumber::EIGHT_SPADES);
364 assert!(seven.contain_blank());
365 assert!(!seven.is_valid());
366 }
367
368 #[test]
369 fn try_from__index__too_short() {
370 let seven = Seven::try_from("A♠ K♠ Q♠ J♠ T♠");
371
372 assert!(seven.is_err());
373 }
374}