stochasta/playing_cards/playing_card_deck.rs
1use std::fmt::Display;
2
3use enumset::EnumSet;
4use itertools::Itertools;
5
6use crate::CardDeck;
7
8use super::{
9 playing_card_suit::ALL_SUITS, playing_card_value::ALL_VALUES, PlayingCard, PlayingCardSuit,
10 PlayingCardValue,
11};
12
13/// A builder for quickly creating decks of playing cards.
14///
15/// # Example
16///
17/// ```
18/// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
19///
20/// let deck = PlayingCardDeck::new()
21/// .value_range(PlayingCardValue::Seven, PlayingCardValue::Ace)
22/// .all_suits()
23/// .set_count(2)
24/// .to_deck();
25/// println!("{:?}", deck);
26/// assert_eq!(deck.size(), 64);
27/// ```
28///
29#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct PlayingCardDeck {
32 values: EnumSet<PlayingCardValue>,
33 suits: EnumSet<PlayingCardSuit>,
34 count: u64,
35}
36
37impl PlayingCardDeck {
38 /// Constructs a new empty deck.
39 ///
40 /// # Example
41 ///
42 /// ```
43 /// use stochasta::playing_cards::PlayingCardDeck;
44 ///
45 /// let deck = PlayingCardDeck::new();
46 /// assert!(deck.is_empty())
47 /// ```
48 #[must_use]
49 pub fn new() -> Self {
50 Self {
51 values: EnumSet::new(),
52 suits: EnumSet::new(),
53 count: 1,
54 }
55 }
56
57 /// Sets the values.
58 ///
59 /// # Example
60 ///
61 /// ```
62 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
63 ///
64 /// let deck = PlayingCardDeck::new()
65 /// .set_values([PlayingCardValue::Ten, PlayingCardValue::Ace])
66 /// .set_suits([PlayingCardSuit::Hearts])
67 /// .to_deck();
68 ///
69 /// assert_eq!(deck.size(), 2);
70 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ten, PlayingCardSuit::Hearts)));
71 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ace, PlayingCardSuit::Hearts)));
72 /// ```
73 #[must_use]
74 pub fn set_values<I>(mut self, values: I) -> Self
75 where
76 I: IntoIterator<Item = PlayingCardValue>,
77 {
78 self.values.clear();
79 self.values.extend(values);
80 self
81 }
82
83 /// Sets the suits.
84 ///
85 /// # Example
86 ///
87 /// ```
88 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
89 ///
90 /// let deck = PlayingCardDeck::new()
91 /// .set_values([PlayingCardValue::Ace])
92 /// .set_suits([PlayingCardSuit::Hearts, PlayingCardSuit::Clubs])
93 /// .to_deck();
94 ///
95 /// assert_eq!(deck.size(), 2);
96 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ace, PlayingCardSuit::Hearts)));
97 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ace, PlayingCardSuit::Clubs)));
98 /// ```
99 #[must_use]
100 pub fn set_suits<I>(mut self, suits: I) -> Self
101 where
102 I: IntoIterator<Item = PlayingCardSuit>,
103 {
104 self.suits.clear();
105 self.suits.extend(suits);
106 self
107 }
108
109 /// Sets the value range. (both inclusive)
110 ///
111 /// # Example
112 ///
113 /// ```
114 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
115 ///
116 /// let deck = PlayingCardDeck::new()
117 /// .value_range(PlayingCardValue::Jack, PlayingCardValue::Ace)
118 /// .set_suits([PlayingCardSuit::Hearts])
119 /// .to_deck();
120 ///
121 /// assert_eq!(deck.size(), 4);
122 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Jack, PlayingCardSuit::Hearts)));
123 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Queen, PlayingCardSuit::Hearts)));
124 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::King, PlayingCardSuit::Hearts)));
125 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ace, PlayingCardSuit::Hearts)));
126 /// ```
127 #[must_use]
128 pub fn value_range(mut self, from: PlayingCardValue, to: PlayingCardValue) -> Self {
129 self.values.clear();
130 self.values.extend(arr_from_to(&ALL_VALUES, &from, &to));
131 self
132 }
133
134 /// Sets all `PlayingCardValue`s to be included.
135 ///
136 /// # Example
137 ///
138 /// ```
139 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
140 ///
141 /// let deck = PlayingCardDeck::new()
142 /// .all_values()
143 /// .set_suits([PlayingCardSuit::Hearts])
144 /// .to_deck();
145 ///
146 /// assert_eq!(deck.size(), 13);
147 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Hearts)));
148 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ten, PlayingCardSuit::Hearts)));
149 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Ace, PlayingCardSuit::Hearts)));
150 /// ```
151 #[must_use]
152 pub fn all_values(mut self) -> Self {
153 self.values.extend(ALL_VALUES);
154 self
155 }
156
157 /// Sets all `PlayingCardSuit`s inclusive.
158 ///
159 /// # Example
160 ///
161 /// ```
162 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
163 ///
164 /// let deck = PlayingCardDeck::new()
165 /// .set_values([PlayingCardValue::Two])
166 /// .all_suits()
167 /// .to_deck();
168 ///
169 /// assert_eq!(deck.size(), 4);
170 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Diamonds)));
171 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Hearts)));
172 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Clubs)));
173 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Spades)));
174 /// ```
175 #[must_use]
176 pub fn all_suits(mut self) -> Self {
177 self.suits.extend(ALL_SUITS);
178 self
179 }
180
181 /// Sets the count of each individual card.
182 ///
183 /// # Example
184 ///
185 /// ```
186 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
187 ///
188 /// let deck = PlayingCardDeck::new()
189 /// .set_values([PlayingCardValue::Two])
190 /// .set_suits([PlayingCardSuit::Hearts])
191 /// .set_count(4)
192 /// .to_deck();
193 ///
194 /// assert_eq!(deck.size(), 4);
195 /// assert!(deck.contains(&PlayingCard::new(PlayingCardValue::Two, PlayingCardSuit::Hearts)));
196 /// ```
197 #[must_use]
198 pub fn set_count(mut self, count: u64) -> Self {
199 self.count = count;
200 self
201 }
202
203 /// Converts this to a [`CardDeck`](crate::CardDeck).
204 ///
205 /// # Example
206 ///
207 /// ```
208 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
209 ///
210 /// let deck = PlayingCardDeck::new()
211 /// .all_values()
212 /// .all_suits()
213 /// .set_count(2)
214 /// .to_deck();
215 ///
216 /// assert_eq!(deck.size(), 13 * 4 * 2);
217 /// ```
218 #[must_use]
219 pub fn to_deck(&self) -> CardDeck<PlayingCard> {
220 let mut deck = CardDeck::new();
221 for value in self.values.iter() {
222 for suit in self.suits.iter() {
223 deck.add_times(PlayingCard::new(value, suit), self.count);
224 }
225 }
226 deck
227 }
228
229 /// Returns `true` if deck contains no cards.
230 ///
231 /// # Example
232 ///
233 /// ```
234 /// use stochasta::playing_cards::{PlayingCard, PlayingCardDeck, PlayingCardSuit, PlayingCardValue};
235 ///
236 /// assert!(PlayingCardDeck::new().is_empty());
237 /// ```
238 #[must_use]
239 pub fn is_empty(&self) -> bool {
240 self.count == 0 || self.suits.is_empty() || self.values.is_empty()
241 }
242}
243
244impl Default for PlayingCardDeck {
245 fn default() -> Self {
246 Self::new()
247 }
248}
249
250impl Display for PlayingCardDeck {
251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252 write!(
253 f,
254 "[{}] ({}x)",
255 self.suits
256 .iter()
257 .map(|s| self.values.iter().map(|v| format!("{v}{s}")).join(" "))
258 .join(" "),
259 self.count
260 )
261 }
262}
263
264fn arr_from_to<T>(arr: &[T], from: &T, to: &T) -> Vec<T>
265where
266 T: Eq + Clone,
267{
268 let from_idx = arr.iter().position(|x| x == from).unwrap();
269 let to_idx = arr.iter().position(|x| x == to).unwrap();
270 arr[from_idx..=to_idx].to_vec()
271}
272
273#[cfg(test)]
274mod tests {
275 use super::*;
276
277 #[test]
278 fn display_check() {
279 let deck = PlayingCardDeck::new()
280 .set_suits([PlayingCardSuit::Clubs, PlayingCardSuit::Hearts])
281 .set_values([
282 PlayingCardValue::Jack,
283 PlayingCardValue::Queen,
284 PlayingCardValue::King,
285 ])
286 .set_count(2);
287
288 assert_eq!("[J♣ Q♣ K♣ J♥ Q♥ K♥] (2x)", deck.to_string());
289 }
290}