Skip to main content

deckofcards/
deck.rs

1use std::result::Result;
2use std::vec::Vec;
3
4use super::*;
5
6/// The `Deck` represents a deck of zero or more cards. A default deck is 52 playing cards.
7/// Internally the deck consists of two stacks consisting of dealt and undealt cards. The dealt stack
8/// receives cards as they are dealt from the undealt stack.
9///
10/// The deck may be `reset()` to return it to its original state. A deck may be `shuffle()`'d to randomize
11/// its order. Shuffling uses a Knuth shuffle.
12///
13/// A deck can contain more than one card with the same rank / suit combination although by default
14/// it does not.
15///
16/// A deck cannot have more cards added or removed to it once it is created.
17///
18#[derive(Clone)]
19pub struct Deck {
20    /// A deck contains zero or more cards
21    cards: Vec<Card>,
22    /// Dealt cards are cards which have been dealt in calls but are still members of the deck
23    /// they remain dealt until the deck is reshuffled or reset.
24    dealt_cards: Vec<Card>,
25}
26
27impl Cards for Deck {
28    fn cards(&self) -> &[Card] {
29        self.cards.as_slice()
30    }
31
32    fn mut_cards(&mut self) -> &mut [Card] {
33        self.cards.as_mut_slice()
34    }
35}
36
37impl Deck {
38    /// Creates a new `Deck` containing the standard set of 52 cards
39    pub fn new() -> Deck {
40        Deck::from_cards(Card::all_cards())
41    }
42
43    /// Creates a new `Deck` containing the specified cards
44    pub fn from_cards(cards: &[Card]) -> Deck {
45        Deck {
46            cards: cards.to_vec(),
47            dealt_cards: Vec::with_capacity(cards.len()),
48        }
49    }
50
51    /// Returns the number of remaining undealt cards in the `Deck`
52    pub fn undealt_count(&self) -> usize {
53        self.cards.len()
54    }
55
56    /// Returns the number of dealt cards in the `Deck`
57    pub fn dealt_count(&self) -> usize {
58        self.dealt_cards.len()
59    }
60
61    /// Returns the number of cards, dealt or undealt, within the `Deck`
62    pub fn count(&self) -> usize {
63        self.undealt_count() + self.dealt_count()
64    }
65
66    /// Returns the collection of dealt cards
67    pub fn dealt_cards(&self) -> &[Card] {
68        self.dealt_cards.as_slice()
69    }
70
71    /// Tells you the top card (very next to be drawn) in the undealt deck
72    /// without dealing it.
73    pub fn top_card(&self) -> Option<Card> {
74        self.cards().last().map(|card| *card)
75    }
76
77    /// Tells you the bottom card (very last to be drawn) in the undealt deck
78    /// without dealing it.
79    pub fn bottom_card(&self) -> Option<Card> {
80        self.cards().first().map(|card| *card)
81    }
82
83    /// Deals the card from the undealt pile. If there are no cards left, the function
84    /// will return an error.
85    pub fn deal_one(&mut self) -> Result<Card, &'static str> {
86        if let Some(card) = self.cards.pop() {
87            self.dealt_cards.push(card);
88            Ok(card)
89        } else {
90            Err("No cards left")
91        }
92    }
93
94    /// Deals one or more card from the undealt pile and returns them as an array.
95    pub fn deal(&mut self, numcards: usize) -> Vec<Card> {
96        let mut result: Vec<Card> = Vec::with_capacity(numcards as usize);
97        for _ in 0..numcards {
98            if let Ok(card) = self.deal_one() {
99                result.push(card);
100            } else {
101                // No cards so no point continuing
102                break;
103            }
104        }
105        result
106    }
107
108    /// Deals one or more card straight to the `Hand`. Returns the number of cards dealt.
109    pub fn deal_to_hand(&mut self, hand: &mut Hand, numcards: usize) -> usize {
110        let mut dealt: usize = 0;
111        for _ in 0..numcards {
112            if let Ok(card) = self.deal_one() {
113                dealt += 1;
114                hand.push_card(card);
115            } else {
116                // No cards so no point continuing
117                break;
118            }
119        }
120        dealt
121    }
122
123    /// Return the dealt cards back to the end of the undealt pile. Order is preserved according
124    /// to the default order or the last shuffle.
125    pub fn reset(&mut self) {
126        // Put cards back into undealt deck in reverse order
127        self.cards.extend(self.dealt_cards.iter().rev());
128        self.dealt_cards.clear();
129    }
130
131    /// Resets and shuffles the deck
132    pub fn reset_shuffle(&mut self) {
133        self.reset();
134        self.shuffle();
135    }
136}