summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2018-05-12 21:48:42 +0200
committerJustin Worthe <justin@worthe-it.co.za>2018-05-12 21:48:42 +0200
commitd14ec12e30852f8a93f310f5c53fce6ab6f1c6c5 (patch)
tree75703f32ab2ab5bb06fd8ef94982f3d300241e6a /src
parent97880f6a368085e9a409f1fb0030791a4a65005c (diff)
Debugged and fixed the errors that had the monte carlo not working
Monte carlo now beats sample bot, if given plenty of time. I still need to put the max time tracking and enforcement in.
Diffstat (limited to 'src')
-rw-r--r--src/engine/mod.rs18
-rw-r--r--src/strategy/monte_carlo.rs50
2 files changed, 40 insertions, 28 deletions
diff --git a/src/engine/mod.rs b/src/engine/mod.rs
index a1a85ce..41acb23 100644
--- a/src/engine/mod.rs
+++ b/src/engine/mod.rs
@@ -168,11 +168,11 @@ impl GameState {
fn update_status(state: &mut GameState) {
let player_dead = state.player.health == 0;
- let opponent_dead = state.player.health == 0;
+ let opponent_dead = state.opponent.health == 0;
state.status = match (player_dead, opponent_dead) {
(true, true) => GameStatus::Draw,
- (true, false) => GameStatus::PlayerWon,
- (false, true) => GameStatus::OpponentWon,
+ (false, true) => GameStatus::PlayerWon,
+ (true, false) => GameStatus::OpponentWon,
(false, false) => GameStatus::Continue,
};
}
@@ -262,14 +262,4 @@ impl Building {
}
}
-#[test]
-fn how_big() {
- use std::mem;
- assert_eq!(4, mem::size_of::<Player>());
- assert_eq!(12, mem::size_of::<Building>());
- assert_eq!(6, mem::size_of::<Missile>());
- assert_eq!(112, mem::size_of::<GameState>());
- assert_eq!(24, mem::size_of::<Vec<Building>>());
- assert_eq!(24, mem::size_of::<Vec<Missile>>());
-
-}
+
diff --git a/src/strategy/monte_carlo.rs b/src/strategy/monte_carlo.rs
index 8fbf0a3..ba66d48 100644
--- a/src/strategy/monte_carlo.rs
+++ b/src/strategy/monte_carlo.rs
@@ -3,7 +3,7 @@ use engine::command::*;
use engine::{GameState, GameStatus};
use rand::{thread_rng, Rng};
-
+use std::process;
const MAX_MOVES: u16 = 400;
// TODO Round start time here
@@ -16,14 +16,11 @@ pub fn choose_move(settings: &GameSettings, state: &GameState) -> Command {
// TODO Repeat this until time is out
for _ in 0..1000 {
for mut score in &mut command_scores {
- if simulate_to_endstate(settings, state, score.command, &mut rng) {
- score.add_victory();
- } else {
- score.add_defeat();
- }
+ simulate_to_endstate(score, settings, state, &mut rng);
}
}
+ println!("{:?}", command_scores);
let command = command_scores.iter().max_by_key(|&c| c.win_ratio());
match command {
@@ -32,22 +29,30 @@ pub fn choose_move(settings: &GameSettings, state: &GameState) -> Command {
}
}
-fn simulate_to_endstate<R: Rng>(settings: &GameSettings, state: &GameState, command: Command, rng: &mut R) -> bool {
+fn simulate_to_endstate<R: Rng>(command_score: &mut CommandScore, settings: &GameSettings, state: &GameState, rng: &mut R) {
let opponent_first = random_opponent_move(settings, state, rng);
- let mut state_mut = state.simulate(settings, command, opponent_first);
+ let mut state_mut = state.simulate(settings, command_score.command, opponent_first);
for _ in 0..MAX_MOVES {
if state_mut.status != GameStatus::Continue {
break;
}
- let player_command = random_player_move(settings, state, rng);
- let opponent_command = random_opponent_move(settings, state, rng);
+ let player_command = random_player_move(settings, &state_mut, rng);
+ let opponent_command = random_opponent_move(settings, &state_mut, rng);
state_mut.simulate_mut(settings, player_command, opponent_command);
-
}
-
- state_mut.status == GameStatus::PlayerWon
+
+ match state_mut.status {
+ GameStatus::PlayerWon => command_score.add_victory(),
+ GameStatus::OpponentWon => command_score.add_defeat(),
+ GameStatus::Continue => command_score.add_stalemate(),
+ GameStatus::Draw => command_score.add_draw(),
+ GameStatus::InvalidMove => {
+ println!("Invalid move made while performing simulation");
+ process::exit(0);
+ }
+ }
}
fn random_player_move<R: Rng>(settings: &GameSettings, state: &GameState, rng: &mut R) -> Command {
@@ -59,10 +64,13 @@ fn random_opponent_move<R: Rng>(settings: &GameSettings, state: &GameState, rng:
rng.choose(&all_commands).cloned().unwrap_or(Command::Nothing)
}
-
+#[derive(Debug)]
struct CommandScore {
command: Command,
victories: u32,
+ defeats: u32,
+ draws: u32,
+ stalemates: u32,
attempts: u32
}
@@ -71,6 +79,9 @@ impl CommandScore {
CommandScore {
command: command,
victories: 0,
+ defeats: 0,
+ draws: 0,
+ stalemates: 0,
attempts: 0
}
}
@@ -81,6 +92,17 @@ impl CommandScore {
}
fn add_defeat(&mut self) {
+ self.defeats += 1;
+ self.attempts += 1;
+ }
+
+ fn add_draw(&mut self) {
+ self.draws += 1;
+ self.attempts += 1;
+ }
+
+ fn add_stalemate(&mut self) {
+ self.stalemates += 1;
self.attempts += 1;
}