std_deck/
lib.rs

1pub mod deck {
2    use rand::prelude::*;
3
4    #[derive(Copy, Clone)]
5    pub enum Suit {
6        Club,
7        Spade,
8        Heart,
9        Diamond,
10    }
11
12    impl Suit {
13        pub fn to_char(&self) -> char {
14            match *self {
15                Suit::Club    => { 'C' },
16                Suit::Spade   => { 'S' },
17                Suit::Heart   => { 'H' },
18                Suit::Diamond => { 'D' },
19            }
20        }
21
22        pub fn from_char(input: char) -> Result<Suit, &'static str> {
23            match input.to_ascii_lowercase() {
24                'c' => { Ok(Suit::Club) },
25                's' => { Ok(Suit::Spade) },
26                'h' => { Ok(Suit::Heart) },
27                'd' => { Ok(Suit::Diamond) },
28                _   => { Err("Invalid Suit Character") }  
29            }
30        }
31
32        pub fn index(&self) -> usize {
33            match *self {
34                Suit::Club    => { 0 },
35                Suit::Spade   => { 1 },
36                Suit::Heart   => { 2 },
37                Suit::Diamond => { 3 },
38            }
39        }
40
41        pub fn from_index(index: usize) -> Result<Suit, &'static str> {
42            match index {
43                0  => { Ok(Suit::Club) },
44                1  => { Ok(Suit::Spade) },
45                2  => { Ok(Suit::Heart) },
46                3  => { Ok(Suit::Diamond) },
47                _  => { Err("Invalid Suit Index") }
48            }
49        }
50    }
51
52    #[derive(Copy, Clone)]
53    pub enum Rank {
54        Ace,
55        Two,
56        Three,
57        Four,
58        Five,
59        Six,
60        Seven,
61        Eight,
62        Nine,
63        Ten,
64        Jack,
65        Queen,
66        King,
67    }
68
69    impl Rank {
70        pub fn to_char(&self) -> char {
71            match *self {
72                Rank::Ace   => { 'A' },
73                Rank::Two   => { '2' },
74                Rank::Three => { '3' },
75                Rank::Four  => { '4' },
76                Rank::Five  => { '5' },
77                Rank::Six   => { '6' },
78                Rank::Seven => { '7' },
79                Rank::Eight => { '8' },
80                Rank::Nine  => { '9' },
81                Rank::Ten   => { 'T' },
82                Rank::Jack  => { 'J' },
83                Rank::Queen => { 'Q' },
84                Rank::King  => { 'K' },
85            }
86        }
87
88        pub fn from_char(input: char) -> Result<Rank, &'static str> {
89            match input.to_ascii_lowercase() {
90                'A' => { Ok(Rank::Ace  ) },
91                '2' => { Ok(Rank::Two  ) },
92                '3' => { Ok(Rank::Three) },
93                '4' => { Ok(Rank::Four ) },
94                '5' => { Ok(Rank::Five ) },
95                '6' => { Ok(Rank::Six  ) },
96                '7' => { Ok(Rank::Seven) },
97                '8' => { Ok(Rank::Eight) },
98                '9' => { Ok(Rank::Nine ) },
99                'T' => { Ok(Rank::Ten  ) },
100                'J' => { Ok(Rank::Jack ) },
101                'Q' => { Ok(Rank::Queen) },
102                'K' => { Ok(Rank::King ) },
103                _   => { Err("Invalid Rank Character") }
104            }
105        }
106
107        pub fn index(&self) -> usize {
108            match *self {
109                Rank::Ace   => { 0 },
110                Rank::Two   => { 1 },
111                Rank::Three => { 2 },
112                Rank::Four  => { 3 },
113                Rank::Five  => { 4 },
114                Rank::Six   => { 5 },
115                Rank::Seven => { 6 },
116                Rank::Eight => { 7 },
117                Rank::Nine  => { 8 },
118                Rank::Ten   => { 9 },
119                Rank::Jack  => { 10 },
120                Rank::Queen => { 11 },
121                Rank::King  => { 12 },
122            }
123        }
124
125        pub fn from_index(index: usize) -> Result<Rank, &'static str> {
126            match index {
127                0  => { Ok(Rank::Ace  ) },
128                1  => { Ok(Rank::Two  ) },
129                2  => { Ok(Rank::Three) },
130                3  => { Ok(Rank::Four ) },
131                4  => { Ok(Rank::Five ) },
132                5  => { Ok(Rank::Six  ) },
133                6  => { Ok(Rank::Seven) },
134                7  => { Ok(Rank::Eight) },
135                8  => { Ok(Rank::Nine ) },
136                9  => { Ok(Rank::Ten  ) },
137                10 => { Ok(Rank::Jack ) },
138                11 => { Ok(Rank::Queen) },
139                12 => { Ok(Rank::King ) },
140                _  => { Err("Invalid Rank Index") }
141            }
142        }
143    }
144
145    #[derive(Copy, Clone)]
146    pub struct Card {
147        pub suit: Suit,
148        pub rank: Rank
149    }
150
151    impl Card {
152        pub fn index(&self) -> usize {
153            self.suit.index() * 13 + self.rank.index()
154        }
155    }
156
157    impl Default for Card {
158        fn default() -> Card {
159            Card {
160                suit: Suit::Spade,
161                rank: Rank::Ace,
162            }
163        }
164    }
165
166    pub struct Deck {
167        pub cards: Vec<Card>,
168        pub in_play: [bool; 52]
169    }
170
171    impl Default for Deck {
172        //Initialize deck to a default 52 size pack of cards
173        fn default() -> Deck {
174            let mut temp_cards = Vec::new();
175            for i in 0..4 {
176                for j in 0..13 {
177                    temp_cards.push(Card {
178                            suit:  Suit::from_index(i).unwrap(),
179                            rank:  Rank::from_index(j).unwrap(),
180                    });
181                }
182            }
183
184            println!("Default length: {}", temp_cards.len());
185
186            Deck {
187                cards: temp_cards,
188                in_play: [false; 52]
189            }
190        }
191    }
192
193    impl Deck {
194        pub fn size(&self) -> usize {
195            self.cards.len()
196        }
197
198        pub fn draw_shuffled(&mut self) -> Option<Card> {
199            if self.cards.len() > 0 {
200                let mut rng = rand::thread_rng();
201                let mut num: i32 = rng.gen_range(0..self.cards.len() as i32);
202                
203                while self.in_play[self.cards[num as usize].index()] {
204                    num = rng.gen_range(0..self.cards.len() as i32);
205                }
206
207                self.in_play[self.cards[num as usize].index()] = true;
208                return Some(self.cards.remove(num as usize));
209            }
210            None
211        }
212
213        pub fn draw_unshuffled(&mut self) -> Option<Card> {
214            self.in_play[self.cards.len()-1] = true;    
215            self.cards.pop()
216        }
217        
218        pub fn return_card(&mut self, card: Card){
219            self.in_play[card.index()] = false;
220            self.cards.push(card);  
221        }
222
223        pub fn reset(&mut self) {
224            for i in 0..51 {
225                self.in_play[i] = false;
226            }
227        }
228    }
229
230    #[test]
231    fn shuffle_draw() {
232        let mut deck = Deck::default();
233        println!("Shuffle Draw: {}", deck.size());
234        for _i in 0..52 {
235            match deck.draw_shuffled() {
236                Some(c) => {
237                    deck.in_play[c.index()] = true;
238                },
239                None => { panic!("Error"); }
240            };
241        }
242
243        for i in 0..52 {
244            if !deck.in_play[i] {
245                panic!("Index: {} wasn't drawn", i);
246            }
247        }
248    }
249
250    #[test]
251    fn unshuffled_draw() {
252        let mut deck = Deck::default();
253
254        for _i in 0..52 {
255            match deck.draw_unshuffled() {
256                Some(_c) => {},
257                None => { panic!("Couldn't Draw Card"); }
258            };
259        }
260
261        for i in 0..52 {
262            if !deck.in_play[i] {
263                panic!("Index: {} wasn't drawn", i);
264            }
265        }
266    }
267
268    #[test]
269    fn card_return_unshuffled_test() {
270        let mut deck  = Deck::default();
271        let mut cards: Vec<Card> = Vec::new();
272
273        for _i in 0..51 {
274            match deck.draw_unshuffled() {
275                Some(c) => {cards.push(c);},
276                None => {panic!("Couldn't Draw Card");}
277            }
278        }
279
280        for i in cards {
281            deck.return_card(i);
282        }
283
284        assert!(deck.size() == 52);
285    }
286
287    #[test]
288    #[should_panic]
289    fn overdraw_shuffled() {
290        let mut deck = Deck::default();
291
292        for _i in 0..53 {
293            match deck.draw_shuffled() {
294                Some(_c) => {},
295                None => {panic!("");}
296            }
297        }
298    }
299
300    #[test]
301    #[should_panic]
302    fn overdraw_unshuffled() {
303        let mut deck = Deck::default();
304
305        for _i in 0..53 {
306            match deck.draw_unshuffled() {
307                Some(_c) => {},
308                None => {panic!("");}
309            }
310        }
311    }
312}