fudd/types/slots/
omaha_hand.rs

1use crate::types::arrays::four_card::FourCard;
2use crate::types::card_slot::CardSlot;
3use crate::types::playing_card::PlayingCard;
4use crate::types::playing_cards::PlayingCards;
5use crate::types::U32Card;
6use ckc_rs::PokerCard;
7use log::warn;
8use serde::{Deserialize, Serialize};
9use std::cell::Cell;
10use std::fmt;
11
12#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
13pub struct OmahaHand(
14    Cell<PlayingCard>,
15    Cell<PlayingCard>,
16    Cell<PlayingCard>,
17    Cell<PlayingCard>,
18);
19
20impl OmahaHand {
21    #[must_use]
22    pub fn new(
23        first: PlayingCard,
24        second: PlayingCard,
25        third: PlayingCard,
26        forth: PlayingCard,
27    ) -> OmahaHand {
28        OmahaHand(
29            Cell::new(first),
30            Cell::new(second),
31            Cell::new(third),
32            Cell::new(forth),
33        )
34    }
35
36    pub fn get_first_card(&self) -> PlayingCard {
37        self.0.get()
38    }
39
40    pub fn get_second_card(&self) -> PlayingCard {
41        self.1.get()
42    }
43
44    pub fn get_third_card(&self) -> PlayingCard {
45        self.2.get()
46    }
47
48    pub fn get_forth_card(&self) -> PlayingCard {
49        self.3.get()
50    }
51
52    pub fn take_first_card(&self, card: PlayingCard) {
53        self.0.set(card);
54    }
55
56    pub fn take_second_card(&self, card: PlayingCard) {
57        self.1.set(card);
58    }
59
60    pub fn take_third_card(&self, card: PlayingCard) {
61        self.2.set(card);
62    }
63
64    pub fn take_forth_card(&self, card: PlayingCard) {
65        self.3.set(card);
66    }
67
68    pub fn to_array(&self) -> [U32Card; 4] {
69        [
70            self.get_first_card().as_u32(),
71            self.get_second_card().as_u32(),
72            self.get_third_card().as_u32(),
73            self.get_forth_card().as_u32(),
74        ]
75    }
76}
77
78impl CardSlot for OmahaHand {
79    fn take(&self, card: PlayingCard) -> bool {
80        if self.get_first_card().is_blank() {
81            self.take_first_card(card);
82            return true;
83        }
84        if self.get_second_card().is_blank() {
85            self.take_second_card(card);
86            return true;
87        }
88        if self.get_third_card().is_blank() {
89            self.take_third_card(card);
90            return true;
91        }
92        if self.get_forth_card().is_blank() {
93            self.take_forth_card(card);
94            return true;
95        }
96        false
97    }
98
99    fn fold(&self) -> PlayingCards {
100        let folded = self.to_playing_cards();
101        self.0.set(PlayingCard::default());
102        self.1.set(PlayingCard::default());
103        self.2.set(PlayingCard::default());
104        self.3.set(PlayingCard::default());
105        folded
106    }
107
108    fn is_dealt(&self) -> bool {
109        !self.get_first_card().is_blank()
110            && !self.get_second_card().is_blank()
111            && !self.get_third_card().is_blank()
112            && !self.get_forth_card().is_blank()
113    }
114
115    fn to_playing_cards(&self) -> PlayingCards {
116        let mut playing_cards = PlayingCards::default();
117        playing_cards.insert(self.0.get());
118        playing_cards.insert(self.1.get());
119        playing_cards.insert(self.2.get());
120        playing_cards.insert(self.3.get());
121        playing_cards
122    }
123}
124
125impl Default for OmahaHand {
126    fn default() -> OmahaHand {
127        OmahaHand::new(
128            PlayingCard::default(),
129            PlayingCard::default(),
130            PlayingCard::default(),
131            PlayingCard::default(),
132        )
133    }
134}
135
136impl fmt::Display for OmahaHand {
137    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138        write!(f, "{}", self.to_playing_cards())
139    }
140}
141
142impl From<[U32Card; 4]> for OmahaHand {
143    fn from(array: [U32Card; 4]) -> Self {
144        let hand = OmahaHand::default();
145        hand.take_first_card(PlayingCard::from(array[0]));
146        hand.take_second_card(PlayingCard::from(array[1]));
147        hand.take_third_card(PlayingCard::from(array[2]));
148        hand.take_forth_card(PlayingCard::from(array[3]));
149        hand
150    }
151}
152
153impl From<FourCard> for OmahaHand {
154    fn from(four_cards: FourCard) -> Self {
155        OmahaHand::from(four_cards.to_arr())
156    }
157}
158
159impl From<&'static str> for OmahaHand {
160    fn from(value: &'static str) -> OmahaHand {
161        let omaha = OmahaHand::default();
162        if !omaha.take_from_index(value) {
163            warn!("Invalid index: {}", value);
164        }
165        omaha
166    }
167}
168
169#[cfg(test)]
170#[allow(non_snake_case)]
171mod types_slots_omaha_hand_tests {
172    use super::*;
173
174    #[test]
175    fn from__four_cards() {
176        let index = "AS KD 4C 2S";
177        let four = FourCard::try_from(index).unwrap();
178        let omaha = OmahaHand::from(index);
179
180        assert_eq!(four.to_string(), omaha.to_string());
181    }
182}