card_games/
mod.rs

1#![allow(clippy::new_without_default)]
2
3pub mod card;
4pub mod cho_dai_di;
5pub mod collections;
6pub mod player;
7pub mod rank;
8pub mod suit;
9
10use card::{Card, STANDARD_DECK};
11use once_cell::sync::Lazy;
12use rand::{prelude::*, rngs::SmallRng, SeedableRng};
13use std::{marker::PhantomData, sync::Mutex};
14
15static RNG: Lazy<Mutex<SmallRng>> = Lazy::new(|| Mutex::new(SmallRng::from_entropy()));
16
17pub fn shuffled_deck() -> Vec<Card> {
18    let mut deck = STANDARD_DECK;
19    let mut rng = RNG.lock().unwrap();
20    deck.shuffle(&mut *rng);
21    deck.into()
22}
23
24pub struct Deck<G> {
25    cards: Vec<Card>,
26    _game: PhantomData<G>,
27}
28
29impl<G> Deck<G> {
30    pub fn len(&self) -> usize {
31        self.cards.len()
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.cards.is_empty()
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::shuffled_deck;
42    use crate::{
43        cho_dai_di::{ChoDaiDi, FOUR_PLAYERS},
44        Deck,
45    };
46
47    #[test]
48    fn test_shuffled_deck() {
49        let deck = shuffled_deck();
50        assert_eq!(deck.len(), 52);
51    }
52
53    #[test]
54    fn test_cho_dai_di_draw_starting_hands() {
55        let mut deck = Deck::<ChoDaiDi<FOUR_PLAYERS>>::new();
56        let hands = deck.draw_starting_hands();
57
58        for hand in hands {
59            assert_eq!(hand.len(), 13);
60        }
61    }
62}