Skip to main content

games/
deck.rs

1//! Deck of cards
2//!
3//! Cards that implement `DefaultCollection` can use Deck::default
4//! ```
5//! use games::deck::Deck;
6//! use games::cards::StandardCard;
7//! // Usable with cards that implement games::deck::DefaultCollection
8//! let deck: Deck<StandardCard> = Deck::default();
9//! ```
10//! Otherwise use Deck::new
11//! ```
12//! use games::deck::{Deck, DefaultCollection};
13//! use games::cards::StandardCard;
14//! // Cards that don't implement DefaultCollection must use Deck::from
15//! let deck: Deck<StandardCard> = Deck::from(StandardCard::default_collection());
16//! ```
17//! DeckBuilder can also be used to create a deck, with default only being implemented for
18//! `DefaultCollection`
19//! ```
20//! use games::deck::{DeckBuilder, Deck, DefaultCollection};
21//! use games::cards::StandardCard;
22//! let deck: Deck<StandardCard> = DeckBuilder::default().sets(5).build();
23//! // OR
24//! let deck: Deck<StandardCard> = DeckBuilder::from(StandardCard::default_collection()).sets(2).build();
25//! ```
26
27use crate::cards::StandardCard;
28use crate::deck_of_cards::STANDARD_DECK_OF_CARDS;
29use crate::errors::{BASE_DECK_ERROR_CODE, ErrorCode};
30use core::fmt::{self, Debug, Display};
31use rand::RngExt;
32use std::{collections::VecDeque, collections::vec_deque::IntoIter as DequeIntoIter};
33
34/// Create a default collection
35pub trait DefaultCollection: Copy + Clone + Debug + Ord + Display {
36    /// Create a default collection
37    fn default_collection() -> VecDeque<Self>;
38    /// Create n default collections
39    fn multiple_collections(n: usize) -> VecDeque<Self> {
40        let c = Self::default_collection();
41        let set_len = c.len();
42        c.into_iter().cycle().take(set_len * n).collect()
43    }
44    /// Create a deck of Card from default collection
45    fn create_deck() -> Deck<Self> {
46        Deck::default()
47    }
48}
49
50impl DefaultCollection for StandardCard {
51    fn default_collection() -> VecDeque<Self> {
52        STANDARD_DECK_OF_CARDS.iter().copied().collect()
53    }
54    fn multiple_collections(n: usize) -> VecDeque<Self> {
55        STANDARD_DECK_OF_CARDS
56            .iter()
57            .copied()
58            .cycle()
59            .take(52usize * n)
60            .collect()
61    }
62}
63
64/// Standard card deck
65#[repr(C)]
66#[derive(
67    Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Ord, PartialOrd, Hash,
68)]
69pub struct Deck<C: Copy + Clone + Debug + Ord + Display>(pub(crate) VecDeque<C>);
70
71/// Deck error
72#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
73pub enum DeckError {
74    /// No cards left in the deck (6001)
75    NoCard,
76}
77
78impl Display for DeckError {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        match *self {
81            DeckError::NoCard => f.write_str("No Cards are left in the deck"),
82        }
83    }
84}
85
86impl ErrorCode for DeckError {
87    fn error_code(&self) -> i32 {
88        BASE_DECK_ERROR_CODE
89            + match *self {
90                DeckError::NoCard => 1,
91            }
92    }
93}
94impl<C: Copy + Clone + Debug + Ord + Display> Deck<C> {
95    /// Draw a card from the deck at random
96    ///
97    /// # Errors
98    /// Returns an error if the deck is out of cards
99    pub fn draw(&mut self) -> Result<C, DeckError> {
100        self.0.pop_front().ok_or(DeckError::NoCard)
101    }
102    /// Randomly draw a card
103    ///
104    /// # Errors
105    ///
106    /// Errors if there are no cards to draw
107    pub fn draw_random(&mut self) -> Result<C, DeckError> {
108        if self.0.is_empty() {
109            return Err(DeckError::NoCard);
110        }
111
112        let len = self.0.len();
113        if len == 1 {
114            self.0.pop_front().ok_or(DeckError::NoCard)
115        } else {
116            let index = crate::get_rng().random_range(0..len);
117            self.0.remove(index).ok_or(DeckError::NoCard)
118        }
119    }
120    /// Randomly draw up to <count> cards, will stop early if out of cards
121    /// This only shuffles the selected [count,len) range of cards
122    /// For a mores random draw, use .shuffle() then .draw_many()
123    pub fn draw_many_random(&mut self, count: usize) -> Vec<C> {
124        if self.0.is_empty() || count == 0 {
125            return Vec::with_capacity(0);
126        }
127        let len = self.0.len();
128        let mut rng = crate::get_rng();
129        let mid = len.saturating_sub(count);
130        // Shuffle partialy, not sure if I should fully shuffle here
131        for i in (len..mid).rev() {
132            let idx = rng.random_range(0..(i + 1));
133            // invariant: elements with index > i have been locked in place.
134            self.0.swap(i, idx);
135        }
136        self.0.split_off(mid).into()
137    }
138    /// Draw up to <count> cards, will stop early if out of cards
139    pub fn draw_many(&mut self, count: usize) -> Vec<C> {
140        if self.0.is_empty() || count == 0 {
141            return Vec::with_capacity(0);
142        }
143        let len = self.0.len();
144        if count >= len {
145            self.0.drain(..).collect()
146        } else {
147            self.0.split_off(len - count).into()
148        }
149    }
150    /// Draw the rest of the cards
151    pub fn draw_rest(&mut self) -> Vec<C> {
152        self.0.drain(0..).collect()
153    }
154    /// Randomly draw the rest of the cards
155    pub fn draw_rest_random(&mut self) -> Vec<C> {
156        self.shuffle();
157        self.0.drain(0..).collect()
158    }
159    /// Insert a card into the deck
160    pub fn insert(&mut self, card: C) {
161        self.0.push_back(card);
162    }
163    /// Convert the dec into a vector of cards
164    pub fn into_vec(self) -> Vec<C> {
165        self.0.into()
166    }
167    /// Shuffle the deck
168    pub fn shuffle(&mut self) {
169        let mut rng = crate::get_rng();
170        for i in (1..self.len()).rev() {
171            let idx = rng.random_range(0..(i + 1));
172            // invariant: elements with index > i have been locked in place.
173            self.0.swap(i, idx);
174        }
175    }
176    /// Peek at the next card
177    pub fn peek(&self) -> Option<&C> {
178        self.0.front()
179    }
180    /// Create a new deck of cards
181    pub fn from_cards(cards: Vec<C>) -> Self {
182        Self(cards.into())
183    }
184    /// Check if the deck is empty
185    pub fn is_empty(&self) -> bool {
186        self.0.is_empty()
187    }
188    /// Length of the cards in the deck
189    pub fn len(&self) -> usize {
190        self.0.len()
191    }
192    /// Create an empty deck of cards
193    pub fn empty() -> Self {
194        Self(VecDeque::new())
195    }
196}
197impl<C: DefaultCollection> Default for Deck<C> {
198    fn default() -> Deck<C> {
199        Self(C::default_collection())
200    }
201}
202
203impl<C: Copy + Clone + Debug + Ord + Display> Extend<C> for Deck<C> {
204    fn extend<I: IntoIterator<Item = C>>(&mut self, iter: I) {
205        self.0.extend(iter)
206    }
207}
208
209impl<C: Copy + Clone + Debug + Ord + Display> core::iter::FromIterator<C> for Deck<C> {
210    fn from_iter<I: IntoIterator<Item = C>>(iter: I) -> Self {
211        let mut c = Self::empty();
212        c.extend(iter);
213        c
214    }
215}
216
217impl<C: Copy + Clone + Debug + Ord + Display> IntoIterator for Deck<C> {
218    type Item = C;
219    type IntoIter = DequeIntoIter<C>;
220
221    fn into_iter(self) -> Self::IntoIter {
222        self.0.into_iter()
223    }
224}
225
226/// Builder for `games::deck::Deck`
227/// ```
228/// use games::cards::StandardCard;
229/// use games::deck::{Deck,DeckBuilder};
230/// let deck: Deck<StandardCard> = DeckBuilder::default().sets(5).build();
231/// ```
232#[derive(Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
233pub struct DeckBuilder<C: Copy + Clone + Debug + Ord + Display>(Vec<C>);
234impl<C: Copy + Clone + Debug + Ord + Display> DeckBuilder<C> {
235    /// Increase the sets of cause
236    /// NOTE: Using this multiple times will have a multiplicative effect
237    /// EX: sets(5).sets(5) will create 25 sets
238    pub fn sets(mut self, n: usize) -> Self {
239        let set_len = self.0.len();
240        self.0 = self.0.into_iter().cycle().take(set_len * n).collect();
241        self
242    }
243    /// Build the deck of cards
244    pub fn build(self) -> Deck<C> {
245        Deck(self.0.into())
246    }
247}
248impl<C: DefaultCollection> Default for DeckBuilder<C> {
249    fn default() -> DeckBuilder<C> {
250        Self(C::default_collection().into())
251    }
252}
253
254impl<C: Copy + Clone + Debug + Ord + Display> From<Vec<C>> for Deck<C> {
255    fn from(cards: Vec<C>) -> Self {
256        Self(cards.into())
257    }
258}
259
260impl<C: Copy + Clone + Debug + Ord + Display> From<VecDeque<C>> for Deck<C> {
261    fn from(cards: VecDeque<C>) -> Self {
262        Self(cards)
263    }
264}
265
266impl<C: Copy + Clone + Debug + Ord + Display> From<Vec<C>> for DeckBuilder<C> {
267    fn from(cards: Vec<C>) -> Self {
268        Self(cards)
269    }
270}
271impl<C: Copy + Clone + Debug + Ord + Display> From<VecDeque<C>> for DeckBuilder<C> {
272    fn from(cards: VecDeque<C>) -> Self {
273        Self(cards.into())
274    }
275}