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 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}