cribbage_core/
deck.rs

1use rand::prelude::SliceRandom;
2use rand::thread_rng;
3
4use crate::card::{Card, Rank, Suit};
5use crate::CribbageCoreError;
6
7pub struct Deck {
8    cards_drawn: usize,
9    cards: Vec<Card>,
10}
11
12impl Deck {
13    pub fn new() -> Deck {
14        Deck::default()
15    }
16
17    pub fn draw(&mut self) -> Result<Card, CribbageCoreError> {
18        let card = match self.cards.get(self.cards_drawn) {
19            Some(card) => {
20                self.cards_drawn += 1;
21                card
22            }
23            None => return Err(CribbageCoreError::NotEnoughCards),
24        };
25
26        Ok(*card)
27    }
28
29    pub fn draw_n(&mut self, n: usize) -> Result<Vec<Card>, CribbageCoreError> {
30        let start = self.cards_drawn;
31        let end = self.cards_drawn + n;
32        if end > self.cards.len() {
33            return Err(CribbageCoreError::NotEnoughCards);
34        }
35
36        self.cards_drawn = end;
37        Ok(self.cards[start..end].to_vec())
38    }
39
40    pub fn shuffle(&mut self) {
41        self.cards_drawn = 0;
42        self.cards.shuffle(&mut thread_rng());
43    }
44}
45
46impl Default for Deck {
47    fn default() -> Deck {
48        let cards = vec![
49            Card::new(Rank::Ace, Suit::Hearts),
50            Card::new(Rank::Two, Suit::Hearts),
51            Card::new(Rank::Three, Suit::Hearts),
52            Card::new(Rank::Four, Suit::Hearts),
53            Card::new(Rank::Five, Suit::Hearts),
54            Card::new(Rank::Six, Suit::Hearts),
55            Card::new(Rank::Seven, Suit::Hearts),
56            Card::new(Rank::Eight, Suit::Hearts),
57            Card::new(Rank::Nine, Suit::Hearts),
58            Card::new(Rank::Ten, Suit::Hearts),
59            Card::new(Rank::Jack, Suit::Hearts),
60            Card::new(Rank::Queen, Suit::Hearts),
61            Card::new(Rank::King, Suit::Hearts),
62            Card::new(Rank::Ace, Suit::Clubs),
63            Card::new(Rank::Two, Suit::Clubs),
64            Card::new(Rank::Three, Suit::Clubs),
65            Card::new(Rank::Four, Suit::Clubs),
66            Card::new(Rank::Five, Suit::Clubs),
67            Card::new(Rank::Six, Suit::Clubs),
68            Card::new(Rank::Seven, Suit::Clubs),
69            Card::new(Rank::Eight, Suit::Clubs),
70            Card::new(Rank::Nine, Suit::Clubs),
71            Card::new(Rank::Ten, Suit::Clubs),
72            Card::new(Rank::Jack, Suit::Clubs),
73            Card::new(Rank::Queen, Suit::Clubs),
74            Card::new(Rank::King, Suit::Clubs),
75            Card::new(Rank::King, Suit::Diamonds),
76            Card::new(Rank::Queen, Suit::Diamonds),
77            Card::new(Rank::Jack, Suit::Diamonds),
78            Card::new(Rank::Ten, Suit::Diamonds),
79            Card::new(Rank::Nine, Suit::Diamonds),
80            Card::new(Rank::Eight, Suit::Diamonds),
81            Card::new(Rank::Seven, Suit::Diamonds),
82            Card::new(Rank::Six, Suit::Diamonds),
83            Card::new(Rank::Five, Suit::Diamonds),
84            Card::new(Rank::Four, Suit::Diamonds),
85            Card::new(Rank::Three, Suit::Diamonds),
86            Card::new(Rank::Two, Suit::Diamonds),
87            Card::new(Rank::Ace, Suit::Diamonds),
88            Card::new(Rank::King, Suit::Spades),
89            Card::new(Rank::Queen, Suit::Spades),
90            Card::new(Rank::Jack, Suit::Spades),
91            Card::new(Rank::Ten, Suit::Spades),
92            Card::new(Rank::Nine, Suit::Spades),
93            Card::new(Rank::Eight, Suit::Spades),
94            Card::new(Rank::Seven, Suit::Spades),
95            Card::new(Rank::Six, Suit::Spades),
96            Card::new(Rank::Five, Suit::Spades),
97            Card::new(Rank::Four, Suit::Spades),
98            Card::new(Rank::Three, Suit::Spades),
99            Card::new(Rank::Two, Suit::Spades),
100            Card::new(Rank::Ace, Suit::Spades),
101        ];
102
103        Deck {
104            cards_drawn: 0,
105            cards,
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use crate::card::{Card, Rank, Suit};
113    use crate::deck::Deck;
114    use crate::CribbageCoreError;
115
116    #[test]
117    fn test_new() {
118        let deck = Deck::new();
119        assert_eq!(deck.cards_drawn, 0);
120        assert_eq!(deck.cards.len(), 52);
121    }
122
123    #[test]
124    fn test_new_shuffle() {
125        let mut deck = Deck::new();
126        deck.shuffle();
127        assert_ne!(deck.cards, Deck::new().cards);
128    }
129
130    #[test]
131    pub fn test_draw() {
132        let mut deck = Deck::new();
133        assert_eq!(deck.cards_drawn, 0);
134
135        assert_eq!(deck.draw().unwrap(), Card::new(Rank::Ace, Suit::Hearts));
136        assert_eq!(deck.cards_drawn, 1);
137
138        for _ in 0..51 {
139            deck.draw().unwrap();
140        }
141
142        assert_eq!(deck.cards_drawn, 52);
143
144        assert_eq!(deck.draw(), Err(CribbageCoreError::NotEnoughCards));
145        assert_eq!(deck.cards_drawn, 52);
146    }
147
148    #[test]
149    pub fn test_draw_n() {
150        let mut deck = Deck::new();
151        assert_eq!(deck.draw_n(0).unwrap(), Vec::new());
152        assert_eq!(deck.cards_drawn, 0);
153
154        assert_eq!(
155            deck.draw_n(1).unwrap(),
156            vec![Card::new(Rank::Ace, Suit::Hearts)]
157        );
158        assert_eq!(deck.cards_drawn, 1);
159
160        deck = Deck::new();
161        assert_eq!(deck.draw_n(52).unwrap(), Deck::new().cards);
162        assert_eq!(deck.cards_drawn, 52);
163
164        assert_eq!(deck.draw_n(0).unwrap(), Vec::new());
165        assert_eq!(deck.cards_drawn, 52);
166
167        assert_eq!(deck.draw_n(1), Err(CribbageCoreError::NotEnoughCards));
168        assert_eq!(deck.cards_drawn, 52);
169
170        assert_eq!(deck.draw_n(52), Err(CribbageCoreError::NotEnoughCards));
171        assert_eq!(deck.cards_drawn, 52);
172    }
173
174    #[test]
175    pub fn test_shuffle() {
176        let mut deck = Deck::new();
177        deck.shuffle();
178        assert_ne!(deck.cards, Deck::new().cards);
179
180        deck.draw().unwrap();
181        assert_eq!(deck.cards_drawn, 1);
182
183        deck.shuffle();
184        assert_eq!(deck.cards_drawn, 0);
185
186        deck.draw_n(52).unwrap();
187        assert_eq!(deck.cards_drawn, 52);
188
189        deck.shuffle();
190        assert_eq!(deck.cards_drawn, 0);
191    }
192}