1use crate::{Card, Hand};
12use core::fmt;
13use core::str::FromStr;
14use rand::{Rng, RngExt as _};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
22#[cfg_attr(
23 feature = "serde",
24 derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
25)]
26pub struct Deck(Hand);
27
28impl Deck {
29 pub const ALL: Self = Self(Hand::ALL);
31
32 pub const EMPTY: Self = Self(Hand::EMPTY);
34
35 #[must_use]
37 #[inline]
38 pub const fn len(&self) -> usize {
39 self.0.len()
40 }
41
42 #[must_use]
44 #[inline]
45 pub const fn is_empty(&self) -> bool {
46 self.0.is_empty()
47 }
48
49 pub const fn clear(&mut self) {
51 self.0 = Hand::EMPTY;
52 }
53
54 pub fn insert(&mut self, card: Card) -> bool {
59 self.0.insert(card)
60 }
61
62 #[must_use]
64 #[inline]
65 pub const fn take(&mut self) -> Hand {
66 core::mem::replace(&mut self.0, Hand::EMPTY)
67 }
68
69 #[must_use]
79 pub fn draw(&mut self, rng: &mut (impl Rng + ?Sized), n: usize) -> Hand {
80 let len = self.0.len();
81 if n >= len {
82 return self.take();
83 }
84
85 let mut hand = Hand::EMPTY;
86 for i in 0..n {
87 let bits = (0..rng.random_range(..len - i))
88 .fold(self.0.to_bits(), |bits, _| bits & (bits - 1));
89 let selected = Hand::from_bits_retain(bits & bits.wrapping_neg());
90 hand |= selected;
91 self.0 ^= selected;
92 }
93 hand
94 }
95
96 #[must_use]
98 pub fn pop(&mut self, rng: &mut (impl Rng + ?Sized)) -> Option<Card> {
99 self.draw(rng, 1).into_iter().next()
100 }
101}
102
103impl From<Hand> for Deck {
104 fn from(hand: Hand) -> Self {
105 Self(hand)
106 }
107}
108
109impl From<Deck> for Hand {
110 fn from(deck: Deck) -> Self {
111 deck.0
112 }
113}
114
115impl fmt::Display for Deck {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 self.0.fmt(f)
118 }
119}
120
121impl FromStr for Deck {
122 type Err = <Hand as FromStr>::Err;
123
124 fn from_str(s: &str) -> Result<Self, Self::Err> {
125 s.parse::<Hand>().map(Self)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 struct Lcg(u64);
135
136 impl Lcg {
137 fn step(&mut self) -> u32 {
138 self.0 = self
139 .0
140 .wrapping_mul(6_364_136_223_846_793_005)
141 .wrapping_add(1_442_695_040_888_963_407);
142 (self.0 >> 32) as u32
143 }
144 }
145
146 impl rand::rand_core::TryRng for Lcg {
147 type Error = core::convert::Infallible;
148
149 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
150 Ok(self.step())
151 }
152
153 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
154 Ok(u64::from(self.step()) << 32 | u64::from(self.step()))
155 }
156
157 fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
158 dst.fill_with(|| self.step() as u8);
159 Ok(())
160 }
161 }
162
163 #[test]
164 fn drawing_partitions_the_deck() {
165 let mut rng = Lcg(2026);
166 let mut deck = Deck::ALL;
167
168 let first = deck.draw(&mut rng, 10);
169 let second = deck.draw(&mut rng, 10);
170 let upcard = deck.pop(&mut rng).unwrap();
171
172 assert_eq!(first.len(), 10);
173 assert_eq!(second.len(), 10);
174 assert_eq!(deck.len(), 31);
175 assert!((first & second).is_empty());
176 assert!(!first.contains(upcard) && !second.contains(upcard));
177
178 let rest = deck.take();
179 assert!(deck.is_empty());
180 assert_eq!(first | second | Hand::from(upcard) | rest, Hand::ALL);
181
182 assert_eq!(deck.pop(&mut rng), None);
183 assert!(deck.insert(upcard));
184 assert!(!deck.insert(upcard));
185 deck.clear();
186 assert_eq!(deck, Deck::EMPTY);
187 }
188}