Finished master
authorGreg Burri <greg.burri@gmail.com>
Wed, 3 Jun 2020 22:00:50 +0000 (00:00 +0200)
committerGreg Burri <greg.burri@gmail.com>
Wed, 3 Jun 2020 22:00:50 +0000 (00:00 +0200)
src/main.rs

index cb0e1ec..2ccfbb6 100644 (file)
@@ -38,12 +38,12 @@ impl PartialOrd for Card {
 
 fn create_deck() -> Vec<Card> {
     let mut deck: Vec<Card> = vec![];
-    for i in 0..4 {
+    for _ in 0..4 {
         deck.push(Card::As);
         deck.push(Card::King);
         deck.push(Card::Queen);
         deck.push(Card::Jack);
-        for v in 2..=10 {
+        for v in 2 ..= 10 {
             deck.push(Card::Value(v));
         }
     }
@@ -52,20 +52,43 @@ fn create_deck() -> Vec<Card> {
 
 fn shuffle_deck(deck: &mut Vec<Card>) {
     let mut rng = thread_rng();
-    let deck_range = Uniform::new(0, deck.len());
+    let n = deck.len();
 
-    for _ in 0 .. deck.len() * 100 {
-        let a = deck_range.sample(&mut rng);
-        let b = deck_range.sample(&mut rng);
-        if a != b {
-            deck.swap(a, b);
-        }
+    let mut new_deck = Vec::<Card>::new();
+
+    for _ in 0 .. n {
+        let deck_range = Uniform::new(0, deck.len());
+        let pos = deck_range.sample(&mut rng);
+        new_deck.push(deck[pos].clone());
+        deck.remove(pos);
     }
+
+    std::mem::swap(deck, &mut new_deck);
 }
 
-struct Deck {
-    main: Vec<Card>,
-    captured: Vec<Card>
+struct Player {
+    deck: Vec<Card>,
+    captured: Vec<Card>,
+}
+
+impl Player {
+    fn new(deck: &[Card]) -> Self {
+        Player { deck: deck.to_vec(), captured: Vec::new() }
+    }
+
+    fn draw(&mut self) -> Option<Card> {
+        if self.deck.len() == 0 {
+            if self.captured.len() == 0 { return None }
+            std::mem::swap(&mut self.deck, &mut self.captured);
+            shuffle_deck(&mut self.deck);
+        }
+
+        Some(self.deck.pop().unwrap())
+    }
+
+    fn add(&mut self, cards: &[Card]) {
+        self.captured.append(&mut cards.to_vec());
+    }
 }
 
 fn play() -> u32 {
@@ -74,51 +97,69 @@ fn play() -> u32 {
     let mut deck = create_deck();
     shuffle_deck(&mut deck);
 
-    let mut player1_deck = deck[0..deck.len() / 2].to_vec();
-    let mut player1_captured = Vec::<Card>::new();
+    let mut player1 = Player::new(&deck[0..deck.len() / 2]);
+    let mut player2 = Player::new(&deck[deck.len() / 2 .. deck.len()]);
 
-    let mut player2_deck = deck[deck.len() / 2 .. deck.len()].to_vec();
-    let mut player2_captured = Vec::<Card>::new();
+    let mut face_down = Vec::<Card>::new();
 
-    while player1_deck.len() + player1_captured.len() > 0 && player2_deck.len() + player2_captured.len() > 0 {
+    loop {
         current_turn += 1;
 
-        if player1_deck.len() == 0 {
-            player1_deck.clone_from_slice(&player1_captured);
-            shuffle_deck(&mut player1_deck);
-            player1_captured.clear();
-        }
-
-        if player2_deck.len() == 0 {
-            player2_deck.clone_from_slice(&player2_captured);
-            shuffle_deck(&mut player2_deck);
-            player2_captured.clear();
+        /*
+        println!("nb card: {}", player1.deck.len() + player2.deck.len() + player1.captured.len() + player2.captured.len() + face_down.len());
+        println!("Player 1: {}", player1.deck.len() + player1.captured.len());
+        println!("Player 2: {}", player2.deck.len() + player2.captured.len());
+        println!("Face down: {}", face_down.len());
+        println!("---------");
+        */
+
+        match (player1.draw(), player2.draw()) {
+            (Some(c1), Some(c2)) =>
+                if c1 > c2 {
+                    player1.add(&vec![c1, c2]);
+                    if face_down.len() > 0 {
+                        player1.add(&face_down);
+                        face_down.clear();
+                    }
+                } else if c2 > c1 {
+                    player2.add(&vec![c1, c2]);
+                    if face_down.len() > 0 {
+                        player2.add(&face_down);
+                        face_down.clear();
+                    }
+                } else {
+                    face_down.push(c1);
+                    face_down.push(c2);
+                    match (player1.draw(), player2.draw()) {
+                        (Some(c3), Some(c4)) => {
+                            face_down.push(c3);
+                            face_down.push(c4);
+                        }
+                        _ =>
+                            return current_turn
+                    }
+                }
+
+            _ =>
+                return current_turn
         }
-
-        let c1 = player1_deck.pop().unwrap()
-        let c2 = player1_deck.pop().unwrap()
-
-/*
-        if  {
-            return current_turn;
-        }*/
     }
-
-    //dbg!(deck);
-
-    current_turn
 }
 
 fn main() {
     println!("Bataille simulator");
 
-    let n = 1;
-    for i in 0..n {
-        let nb_of_turns = play();
-        dbg!(nb_of_turns);
+    let n = 10_000;
+    let time_per_turn = 5.0; // [s].
+
+    let mut sum = 0;
+    for _ in 0..n {
+        sum += play();
     }
-}
 
+    let nb_of_turns = (sum as f64) / (n as f64);
+    println!("Nb turn: {}, time: {} min", nb_of_turns, nb_of_turns * time_per_turn / 60.0);
+}
 
 #[cfg(test)]
 mod tests {