3 pub const NUM_RANKS: u8 = 13;
4 pub const NUM_SUITS: u8 = 4;
5 pub const NUM_JOKERS: u8 = 2;
6 pub const NUM_CARDS: u8 = NUM_RANKS * NUM_SUITS + NUM_JOKERS;
8 #[derive(Clone, Copy, Eq, PartialEq)]
11 #[derive(Clone, Copy, Eq, PartialEq)]
14 #[derive(Clone, Copy, Eq, PartialEq)]
18 pub fn is_joker(&self) -> bool {
19 self.0 >= NUM_RANKS * NUM_SUITS
22 pub fn rank(&self) -> Option<Rank> {
23 (!self.is_joker()).then_some(Rank(self.0 >> 2))
26 pub fn suit(&self) -> Option<Suit> {
27 (!self.is_joker()).then_some(Suit(self.0 & 3))
31 #[derive(Clone, Copy)]
32 pub enum WithOrWithoutJokers {
38 pub fn deck(j: WithOrWithoutJokers) -> Vec<Card> {
40 WithOrWithoutJokers::WithJokers => NUM_CARDS,
41 WithOrWithoutJokers::WithoutJokers => NUM_SUITS * NUM_RANKS,
43 (0..limit).map(Card).collect()
46 #[derive(Clone, Copy)]
47 pub struct PathLength(Rank);
49 #[derive(Clone, Copy, Default)]
50 pub struct PathLengthInfo(u16);
53 pub fn is_showing(&self, i: Rank) -> bool {
54 (self.0 >> i.0) & 1 == 1
56 fn reveal(&mut self, i: Rank) {
59 pub fn reveal_random(&mut self, true_length: PathLength) -> Option<Rank> {
60 let showing = u8::try_from(self.0.count_ones()).expect("There aren't that many bits");
61 let not_showing = NUM_RANKS - showing;
66 let mut show = rand::thread_rng().gen_range(0..not_showing - 1);
67 for i in 0..NUM_RANKS {
69 if !self.is_showing(r) && r != true_length.0 {
86 fn path_length_info_random_reveal() {
87 let length = PathLength(Rank(7));
88 let mut pli = PathLengthInfo::default();
90 let old_pli = PathLengthInfo::clone(&pli);
91 match pli.reveal_random(length) {
92 None => panic!("Nothing revealed?"),
94 assert!(!old_pli.is_showing(r));
95 assert!(pli.is_showing(r));
98 assert_eq!(pli.0.count_ones(), 1 + old_pli.0.count_ones());
100 assert!(pli.reveal_random(length).is_none());
105 use WithOrWithoutJokers::*;
106 let _d = deck(WithoutJokers);
107 let _dj = deck(WithJokers);