1use super::*;
2
3#[derive(Debug, Clone)]
4pub struct Rng {
5 initial_state: Vec<Card>,
6 current_state: Vec<Card>,
7 pub(crate) mem: Vec<Card>,
8 mem_unused: Vec<Card>,
9}
10
11impl Default for Rng {
12 fn default() -> Self {
13 Self::new(Card::ARR_ALL.to_vec())
14 }
15}
16
17impl Rng {
18 pub fn new(initial: Vec<Card>) -> Self {
19 let len = initial.len();
20
21 Self {
22 initial_state: initial,
23 current_state: Vec::with_capacity(len),
24 mem: Vec::with_capacity(5),
25 mem_unused: Vec::with_capacity(len),
26 }
27 }
28
29 pub fn reset(&mut self) {
30 self.current_state.clone_from(&self.initial_state);
31 }
32
33 pub fn deal_n(&mut self, range: &mut PQLRange, mut n: u8) -> Option<()> {
34 while n > 0 {
35 let len = self.current_state.len();
36
37 if len > 0 {
38 let i = fastrand::usize(0..len);
39 let c = self.current_state.swap_remove(i);
40
41 self.mem.push(c);
42
43 if range.is_satisfied(self.mem.as_ref()) {
44 n -= 1;
45 } else {
46 self.mem.pop();
47 self.mem_unused.push(c);
48 }
49 } else {
50 return None;
51 }
52 }
53
54 self.current_state.append(&mut self.mem_unused);
55
56 Some(())
57 }
58
59 pub fn deal(&mut self, range: &mut PQLRange) -> Option<()> {
60 self.mem_unused.clear();
61 self.mem.clear();
62
63 match range {
64 PQLRange::Hand2(_) => self.deal_n(range, 2),
65 PQLRange::Hand4(_) => self.deal_n(range, 4),
66 PQLRange::Board(_) => {
67 self.deal_n(range, 3)?;
68 self.deal_n(range, 1)?;
69 self.deal_n(range, 1)
70 }
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::Rng;
78 use crate::{Card, Card64, c64, cards, *};
79
80 #[test]
81 fn test_reset() {
82 let cards = cards!["As 2h"];
83
84 let mut dealer = Rng::new(cards.clone());
85 dealer.current_state.clear();
86
87 dealer.reset();
88
89 assert_eq!(dealer.current_state, cards);
90 }
91
92 #[test]
93 fn test_deal() {
94 fastrand::seed(0);
95 let mut range = PQLRange::from_src("AA", PQLGame::Omaha).unwrap();
96
97 let mut dealer = Rng::new(Card::ARR_ALL.to_vec());
98 dealer.reset();
99
100 let res = dealer.deal(&mut range);
101 let c = c64!("As 2s 9c Ac");
102
103 assert!(res.is_some());
104 assert_eq!(Card64::from(dealer.mem.as_ref()), c);
105 assert_eq!(
106 Card64::from(dealer.current_state.as_ref()),
107 Card64::all() & !c
108 );
109
110 dealer.mem.clear();
111 let res = dealer.deal_n(&mut range, 2);
112 let c_n = c64!("6s Td");
113
114 assert!(res.is_some());
115 assert_eq!(Card64::from(dealer.mem.as_ref()), c_n);
116 assert_eq!(
117 Card64::from(dealer.current_state.as_ref()),
118 Card64::all() & !c & !c_n
119 );
120
121 dealer.current_state.clear();
122 assert_eq!(dealer.deal(&mut range), None);
123
124 let mut dealer = Rng::new(cards!("2s 2h 2d 2c 3s"));
125
126 dealer.reset();
127 assert!(
128 dealer
129 .deal(&mut PQLBoardRange::from_src("AAA").unwrap().into())
130 .is_none()
131 );
132 dealer.reset();
133 assert!(
134 dealer
135 .deal(&mut PQLBoardRange::from_src("222A").unwrap().into())
136 .is_none()
137 );
138 }
139}