ckc_rs/cards/
four.rs

1use crate::cards::HandValidator;
2use crate::{CKCNumber, HandError, PokerCard, Shifty};
3use core::slice::Iter;
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct Four([CKCNumber; 4]);
8
9impl Four {
10    pub const OMAHA_PERMUTATIONS: [[u8; 2]; 6] = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]];
11
12    //region accessors
13
14    #[must_use]
15    pub fn second(&self) -> CKCNumber {
16        self.0[1]
17    }
18
19    #[must_use]
20    pub fn third(&self) -> CKCNumber {
21        self.0[2]
22    }
23
24    #[must_use]
25    pub fn forth(&self) -> CKCNumber {
26        self.0[3]
27    }
28
29    pub fn set_first(&mut self, card_number: CKCNumber) {
30        self.0[0] = card_number;
31    }
32
33    pub fn set_second(&mut self, card_number: CKCNumber) {
34        self.0[1] = card_number;
35    }
36
37    pub fn set_third(&mut self, card_number: CKCNumber) {
38        self.0[2] = card_number;
39    }
40
41    pub fn set_forth(&mut self, card_number: CKCNumber) {
42        self.0[3] = card_number;
43    }
44
45    #[must_use]
46    pub fn to_arr(&self) -> [CKCNumber; 4] {
47        self.0
48    }
49
50    //endregion
51
52    fn from_index(index: &str) -> Option<[CKCNumber; 4]> {
53        let mut esses = index.split_whitespace();
54
55        let first = CKCNumber::from_index(esses.next()?);
56        let second = CKCNumber::from_index(esses.next()?);
57        let third = CKCNumber::from_index(esses.next()?);
58        let forth = CKCNumber::from_index(esses.next()?);
59        let hand: [CKCNumber; 4] = [first, second, third, forth];
60        Some(hand)
61    }
62}
63
64impl From<[CKCNumber; 4]> for Four {
65    fn from(array: [CKCNumber; 4]) -> Self {
66        Four(array)
67    }
68}
69
70impl HandValidator for Four {
71    fn are_unique(&self) -> bool {
72        (self.first() != self.second())
73            && (self.first() != self.third())
74            && (self.first() != self.forth())
75            && (self.second() != self.third())
76            && (self.second() != self.forth())
77            && (self.third() != self.forth())
78    }
79
80    fn first(&self) -> CKCNumber {
81        self.0[0]
82    }
83
84    fn sort(&self) -> Four {
85        let mut array = *self;
86        array.sort_in_place();
87        array
88    }
89
90    fn sort_in_place(&mut self) {
91        self.0.sort_unstable();
92        self.0.reverse();
93    }
94
95    fn iter(&self) -> Iter<'_, CKCNumber> {
96        self.0.iter()
97    }
98}
99
100impl TryFrom<&'static str> for Four {
101    type Error = HandError;
102
103    fn try_from(index: &'static str) -> Result<Self, Self::Error> {
104        match Four::from_index(index) {
105            None => Err(HandError::InvalidIndex),
106            Some(four) => Ok(Four::from(four)),
107        }
108    }
109}
110
111impl Shifty for Four {
112    fn shift_suit(&self) -> Self {
113        Four([
114            self.first().shift_suit(),
115            self.second().shift_suit(),
116            self.third().shift_suit(),
117            self.forth().shift_suit(),
118        ])
119    }
120}
121
122#[cfg(test)]
123#[allow(non_snake_case)]
124mod cards_four_tests {
125    use super::*;
126    use crate::CardNumber;
127
128    #[test]
129    fn sort() {
130        let four = Four::try_from("KC QD A♠ T♠").unwrap().sort();
131
132        let expected = Four::try_from("A♠ KC QD T♠").unwrap();
133
134        assert_eq!(four, expected);
135    }
136
137    #[test]
138    fn default() {
139        let four = Four::default();
140
141        assert_eq!(four.first(), CardNumber::BLANK);
142        assert_eq!(four.second(), CardNumber::BLANK);
143        assert_eq!(four.third(), CardNumber::BLANK);
144        assert_eq!(four.forth(), CardNumber::BLANK);
145        assert!(four.contain_blank());
146        assert!(!four.are_unique());
147        assert!(!four.is_valid());
148    }
149
150    #[test]
151    fn try_from__index() {
152        let four = Four::try_from("A♠ K♠ Q♠ J♠");
153
154        assert!(four.is_ok());
155        let four = four.unwrap();
156        assert_eq!(four.first(), CardNumber::ACE_SPADES);
157        assert_eq!(four.second(), CardNumber::KING_SPADES);
158        assert_eq!(four.third(), CardNumber::QUEEN_SPADES);
159        assert_eq!(four.forth(), CardNumber::JACK_SPADES);
160        assert!(!four.contain_blank());
161        assert!(four.are_unique());
162        assert!(four.is_valid());
163    }
164
165    #[test]
166    fn try_from__index__blank() {
167        let four = Four::try_from("A♠ K♠ XX J♠");
168
169        assert!(four.is_ok());
170        let four = four.unwrap();
171        assert_eq!(four.first(), CardNumber::ACE_SPADES);
172        assert_eq!(four.second(), CardNumber::KING_SPADES);
173        assert_eq!(four.third(), CardNumber::BLANK);
174        assert_eq!(four.forth(), CardNumber::JACK_SPADES);
175        assert!(four.contain_blank());
176        assert!(!four.is_valid());
177    }
178
179    #[test]
180    fn try_from__index__too_short() {
181        let four = Four::try_from("A♠ K♠ Q♠");
182
183        assert!(four.is_err());
184    }
185
186    #[test]
187    fn shifty__shift_suit() {
188        assert_eq!(
189            Four::try_from("AH KH QH JH").unwrap().shift_suit(),
190            Four::try_from("AD KD QD JD").unwrap()
191        )
192    }
193}