Finished
[bataille.git] / src / main.rs
1 use std::cmp::{ Ordering, PartialOrd };
2 use rand::{thread_rng, Rng};
3 use rand::distributions::{Distribution, Uniform};
4
5 #[derive(PartialEq, Debug, Clone)]
6 enum Card {
7 As,
8 King,
9 Queen,
10 Jack,
11 Value(u8) // 2 to 10.
12 }
13
14 impl PartialOrd for Card {
15 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
16 if self == other {
17 return Some(Ordering::Equal);
18 }
19
20 let figures = vec![Card::As, Card::King, Card::Queen, Card::Jack];
21
22 for figure in figures {
23 if self == &figure {
24 return Some(Ordering::Greater);
25 }
26 if other == &figure {
27 return Some(Ordering::Less);
28 }
29 }
30
31 match (self, other) {
32 (Card::Value(self_val), Card::Value(other_val)) => self_val.partial_cmp(other_val),
33 _ => None
34 }
35 }
36
37 }
38
39 fn create_deck() -> Vec<Card> {
40 let mut deck: Vec<Card> = vec![];
41 for _ in 0..4 {
42 deck.push(Card::As);
43 deck.push(Card::King);
44 deck.push(Card::Queen);
45 deck.push(Card::Jack);
46 for v in 2 ..= 10 {
47 deck.push(Card::Value(v));
48 }
49 }
50 deck
51 }
52
53 fn shuffle_deck(deck: &mut Vec<Card>) {
54 let mut rng = thread_rng();
55 let n = deck.len();
56
57 let mut new_deck = Vec::<Card>::new();
58
59 for _ in 0 .. n {
60 let deck_range = Uniform::new(0, deck.len());
61 let pos = deck_range.sample(&mut rng);
62 new_deck.push(deck[pos].clone());
63 deck.remove(pos);
64 }
65
66 std::mem::swap(deck, &mut new_deck);
67 }
68
69 struct Player {
70 deck: Vec<Card>,
71 captured: Vec<Card>,
72 }
73
74 impl Player {
75 fn new(deck: &[Card]) -> Self {
76 Player { deck: deck.to_vec(), captured: Vec::new() }
77 }
78
79 fn draw(&mut self) -> Option<Card> {
80 if self.deck.len() == 0 {
81 if self.captured.len() == 0 { return None }
82 std::mem::swap(&mut self.deck, &mut self.captured);
83 shuffle_deck(&mut self.deck);
84 }
85
86 Some(self.deck.pop().unwrap())
87 }
88
89 fn add(&mut self, cards: &[Card]) {
90 self.captured.append(&mut cards.to_vec());
91 }
92 }
93
94 fn play() -> u32 {
95 let mut current_turn = 0u32;
96
97 let mut deck = create_deck();
98 shuffle_deck(&mut deck);
99
100 let mut player1 = Player::new(&deck[0..deck.len() / 2]);
101 let mut player2 = Player::new(&deck[deck.len() / 2 .. deck.len()]);
102
103 let mut face_down = Vec::<Card>::new();
104
105 loop {
106 current_turn += 1;
107
108 /*
109 println!("nb card: {}", player1.deck.len() + player2.deck.len() + player1.captured.len() + player2.captured.len() + face_down.len());
110 println!("Player 1: {}", player1.deck.len() + player1.captured.len());
111 println!("Player 2: {}", player2.deck.len() + player2.captured.len());
112 println!("Face down: {}", face_down.len());
113 println!("---------");
114 */
115
116 match (player1.draw(), player2.draw()) {
117 (Some(c1), Some(c2)) =>
118 if c1 > c2 {
119 player1.add(&vec![c1, c2]);
120 if face_down.len() > 0 {
121 player1.add(&face_down);
122 face_down.clear();
123 }
124 } else if c2 > c1 {
125 player2.add(&vec![c1, c2]);
126 if face_down.len() > 0 {
127 player2.add(&face_down);
128 face_down.clear();
129 }
130 } else {
131 face_down.push(c1);
132 face_down.push(c2);
133 match (player1.draw(), player2.draw()) {
134 (Some(c3), Some(c4)) => {
135 face_down.push(c3);
136 face_down.push(c4);
137 }
138 _ =>
139 return current_turn
140 }
141 }
142
143 _ =>
144 return current_turn
145 }
146 }
147 }
148
149 fn main() {
150 println!("Bataille simulator");
151
152 let n = 10_000;
153 let time_per_turn = 5.0; // [s].
154
155 let mut sum = 0;
156 for _ in 0..n {
157 sum += play();
158 }
159
160 let nb_of_turns = (sum as f64) / (n as f64);
161 println!("Nb turn: {}, time: {} min", nb_of_turns, nb_of_turns * time_per_turn / 60.0);
162 }
163
164 #[cfg(test)]
165 mod tests {
166 use super::*;
167
168 #[test]
169 fn test_card_comparisons() {
170 assert!(Card::As == Card::As);
171 assert!(Card::King == Card::King);
172 assert!(Card::Queen == Card::Queen);
173 assert!(Card::Jack == Card::Jack);
174 assert!(Card::Value(10) == Card::Value(10));
175 assert!(Card::Value(2) == Card::Value(2));
176 assert!(Card::As > Card::King);
177 assert!(Card::As > Card::Queen);
178 assert!(Card::As > Card::Jack);
179 assert!(Card::As > Card::Value(10));
180 assert!(Card::King > Card::Queen);
181 assert!(Card::King > Card::Jack);
182 assert!(Card::King > Card::Value(10));
183 assert!(Card::Queen > Card::Jack);
184 assert!(Card::Queen > Card::Value(10));
185 assert!(Card::Jack > Card::Value(10));
186 assert!(Card::Value(10) > Card::Value(9));
187 }
188 }