1#![deny(missing_docs)]
2#[derive(Copy, Clone, PartialEq, Eq)]
7pub struct Card {
8 offset: u8,
9}
10
11impl std::fmt::Debug for Card {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 let rank = self.rank();
14 match rank {
15 11 => write!(f, "J{:?}", self.suit()),
16 12 => write!(f, "Q{:?}", self.suit()),
17 13 => write!(f, "K{:?}", self.suit()),
18 14 => write!(f, "A{:?}", self.suit()),
19 _ => write!(f, "{}{:?}", rank, self.suit()),
20 }
21 }
22}
23impl std::fmt::Debug for Suit {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match self {
26 Suit::Clubs => write!(f, "C"),
27 Suit::Diamonds => write!(f, "D"),
28 Suit::Hearts => write!(f, "H"),
29 Suit::Spades => write!(f, "S"),
30 }
31 }
32}
33
34#[test]
35fn debug() {
36 assert_eq!(&format!("{:?}", Card::new(Suit::Hearts, 4)), "4H");
37 assert_eq!(&format!("{:?}", Card::SA), "AS");
38}
39
40impl Card {
42 pub const fn new(suit: Suit, rank: u8) -> Card {
44 Card {
47 offset: rank + 16 * suit as u8,
48 }
49 }
50 pub const fn suit(self) -> Suit {
52 match self.offset >> 4 {
53 0 => Suit::Clubs,
54 1 => Suit::Diamonds,
55 2 => Suit::Hearts,
56 _ => Suit::Spades,
57 }
58 }
59 pub const fn rank(self) -> u8 {
61 self.offset % 16
62 }
63 pub const C2: Card = Card::new(Suit::Clubs, 2);
65 pub const C3: Card = Card::new(Suit::Clubs, 3);
67 pub const C4: Card = Card::new(Suit::Clubs, 4);
69 pub const C5: Card = Card::new(Suit::Clubs, 5);
71 pub const C6: Card = Card::new(Suit::Clubs, 6);
73 pub const C7: Card = Card::new(Suit::Clubs, 7);
75 pub const C8: Card = Card::new(Suit::Clubs, 8);
77 pub const C9: Card = Card::new(Suit::Clubs, 9);
79 pub const C10: Card = Card::new(Suit::Clubs, 10);
81 pub const CJ: Card = Card::new(Suit::Clubs, 11);
83 pub const CQ: Card = Card::new(Suit::Clubs, 12);
85 pub const CK: Card = Card::new(Suit::Clubs, 13);
87 pub const CA: Card = Card::new(Suit::Clubs, 14);
89
90 pub const D2: Card = Card::new(Suit::Diamonds, 2);
92 pub const D3: Card = Card::new(Suit::Diamonds, 3);
94 pub const D4: Card = Card::new(Suit::Diamonds, 4);
96 pub const D5: Card = Card::new(Suit::Diamonds, 5);
98 pub const D6: Card = Card::new(Suit::Diamonds, 6);
100 pub const D7: Card = Card::new(Suit::Diamonds, 7);
102 pub const D8: Card = Card::new(Suit::Diamonds, 8);
104 pub const D9: Card = Card::new(Suit::Diamonds, 9);
106 pub const D10: Card = Card::new(Suit::Diamonds, 10);
108 pub const DJ: Card = Card::new(Suit::Diamonds, 11);
110 pub const DQ: Card = Card::new(Suit::Diamonds, 12);
112 pub const DK: Card = Card::new(Suit::Diamonds, 13);
114 pub const DA: Card = Card::new(Suit::Diamonds, 14);
116
117 pub const H2: Card = Card::new(Suit::Hearts, 2);
119 pub const H3: Card = Card::new(Suit::Hearts, 3);
121 pub const H4: Card = Card::new(Suit::Hearts, 4);
123 pub const H5: Card = Card::new(Suit::Hearts, 5);
125 pub const H6: Card = Card::new(Suit::Hearts, 6);
127 pub const H7: Card = Card::new(Suit::Hearts, 7);
129 pub const H8: Card = Card::new(Suit::Hearts, 8);
131 pub const H9: Card = Card::new(Suit::Hearts, 9);
133 pub const H10: Card = Card::new(Suit::Hearts, 10);
135 pub const HJ: Card = Card::new(Suit::Hearts, 11);
137 pub const HQ: Card = Card::new(Suit::Hearts, 12);
139 pub const HK: Card = Card::new(Suit::Hearts, 13);
141 pub const HA: Card = Card::new(Suit::Hearts, 14);
143
144 pub const S2: Card = Card::new(Suit::Spades, 2);
146 pub const S3: Card = Card::new(Suit::Spades, 3);
148 pub const S4: Card = Card::new(Suit::Spades, 4);
150 pub const S5: Card = Card::new(Suit::Spades, 5);
152 pub const S6: Card = Card::new(Suit::Spades, 6);
154 pub const S7: Card = Card::new(Suit::Spades, 7);
156 pub const S8: Card = Card::new(Suit::Spades, 8);
158 pub const S9: Card = Card::new(Suit::Spades, 9);
160 pub const S10: Card = Card::new(Suit::Spades, 10);
162 pub const SJ: Card = Card::new(Suit::Spades, 11);
164 pub const SQ: Card = Card::new(Suit::Spades, 12);
166 pub const SK: Card = Card::new(Suit::Spades, 13);
168 pub const SA: Card = Card::new(Suit::Spades, 14);
170}
171
172#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
174pub enum Suit {
175 Clubs = 0,
177 Diamonds = 1,
179 Hearts = 2,
181 Spades = 3,
183}
184
185#[derive(Copy, Clone, PartialEq, Eq, Debug)]
192pub struct Cards {
193 bits: u64,
194}
195
196impl Cards {
197 pub const fn len(&self) -> usize {
199 self.bits.count_ones() as usize
200 }
201
202 pub fn insert(&mut self, card: Card) {
204 self.bits = self.bits | (1 << card.offset)
205 }
206
207 pub fn contains(&self, card: Card) -> bool {
209 self.bits & (1 << card.offset) != 0
210 }
211
212 pub fn union(&self, cards: Cards) -> Cards {
214 Cards {
215 bits: self.bits | cards.bits,
216 }
217 }
218
219 pub fn pick(&mut self, mut num: usize) -> Option<Cards> {
222 let mut bits = self.bits;
223 let mut n_left = self.len();
224 if num > n_left {
225 return None;
226 }
227 let mut kept = 0;
228 let mut given = 0;
229 let mut rng = rand::thread_rng();
230 while n_left > 0 {
231 if n_left == num {
232 given |= bits;
233 break;
234 } else if num == 0 {
235 kept |= bits;
236 break;
237 }
238 use rand::Rng;
239 let chosen = rng.gen::<u64>() & bits;
240 if chosen != 0 {
241 let num_chosen = chosen.count_ones() as usize;
242 if num_chosen <= num {
243 bits &= !chosen;
244 given |= chosen;
245 n_left -= num_chosen;
246 num -= num_chosen;
247 } else if num_chosen + num < n_left {
248 bits &= !chosen;
249 kept |= chosen;
250 n_left -= num_chosen;
251 }
252 }
253 }
254 self.bits = kept;
255 Some(Cards { bits: given })
256 }
257
258 pub const ALL: Cards = Cards {
260 bits: 0x7ffc + (0x7ffc << 16) + (0x7ffc << 32) + (0x7ffc << 48),
261 };
262 pub const EMPTY: Cards = Cards { bits: 0 };
264}
265
266impl Iterator for Cards {
267 type Item = Card;
268
269 fn next(&mut self) -> Option<Self::Item> {
270 if self.bits == 0 {
271 None
272 } else {
273 let next = self.bits.trailing_zeros();
274 self.bits = self.bits & !(1 << next);
275 Some(Card { offset: next as u8 })
276 }
277 }
278}
279
280#[test]
281fn all_cards() {
282 for c in Cards::ALL {
283 println!("c: {:?}", c);
284 }
285 assert_eq!(Cards::ALL.len(), 52);
286}
287#[test]
288fn iterate() {
289 let mut cards = Cards::EMPTY;
290 assert_eq!(cards.next(), None);
291 assert_eq!(cards.len(), 0);
292 cards.insert(Card::C2);
293 assert_eq!(cards.len(), 1);
294 cards.insert(Card::C4);
295 assert_eq!(cards.len(), 2);
296 assert!(cards.contains(Card::C4));
297 assert!(!cards.contains(Card::C3));
298 assert!(cards.contains(Card::C2));
299 assert_eq!(cards.next(), Some(Card::C2));
300 assert_eq!(cards.next(), Some(Card::C4));
301 assert_eq!(cards.next(), None);
302
303 assert_eq!(cards.len(), 0);
304 cards.insert(Card::C2);
305 assert_eq!(cards.len(), 1);
306 cards.insert(Card::C4);
307 assert_eq!(cards.len(), 2);
308
309 let two_cards = cards;
310
311 let mut hand = cards.pick(2).unwrap();
312 assert_eq!(cards.len(), 0);
313 assert_eq!(hand.len(), 2);
314 assert_eq!(hand, two_cards);
315
316 let other = hand.pick(1).unwrap();
317 assert_eq!(other.union(hand), two_cards);
318}