summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-05-22 20:38:47 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-05-22 20:38:47 +0200
commite9a514409565c17a4a86e8c6402be8d7a4f399ae (patch)
tree839dc6e223014ef519fe4d2d020aea996b562e44
parent63da94f7f1b25eddeb9ffd379f37c1a32e750fdb (diff)
Added a strategy cache for reusing previous round data
-rw-r--r--src/bin/benchmark.rs2
-rw-r--r--src/game.rs12
-rw-r--r--src/main.rs8
-rw-r--r--src/strategy.rs39
4 files changed, 43 insertions, 18 deletions
diff --git a/src/bin/benchmark.rs b/src/bin/benchmark.rs
index 794ba4e..20f74d0 100644
--- a/src/bin/benchmark.rs
+++ b/src/bin/benchmark.rs
@@ -13,7 +13,7 @@ fn main() {
match json::read_state_from_json_file(&Path::new(&format!("./tests/example-state.json"))) {
Ok(json_state) => {
let new_board = game::GameBoard::new(json_state);
- let _ = choose_move(&new_board, &start_time, max_time);
+ let _ = choose_move(&new_board, None, &start_time, max_time);
},
Err(e) => {
eprintln!("WARN: State file could not be parsed: {}", e);
diff --git a/src/game.rs b/src/game.rs
index e3fb5c0..fe54f40 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -80,7 +80,7 @@ impl GameBoard {
}
pub fn update(&mut self, json: json::State) {
- for w in json.my_player.worms {
+ for w in &json.my_player.worms {
if let Some(worm) = self.players[0].find_worm_mut(w.id) {
worm.health = w.health;
worm.position = Point2d::new(w.position.x, w.position.y);
@@ -105,15 +105,15 @@ impl GameBoard {
self.map.clear(Point2d::new(cell.x, cell.y))
}
}
-
- self.round += 1;
- debug_assert_eq!(json.current_round, self.round);
-
- // Remove dead worms and update active worm
+
for player in &mut self.players {
player.clear_dead_worms();
player.next_active_worm();
}
+ debug_assert_eq!(json.active_worm_index().unwrap(), self.players[0].active_worm);
+
+ self.round += 1;
+ debug_assert_eq!(json.current_round, self.round);
}
pub fn simulate(&mut self, moves: [Command; 2]) {
diff --git a/src/main.rs b/src/main.rs
index c24565a..b898fb5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,6 +12,7 @@ use steam_powered_wyrm::game;
fn main() {
let max_time = Duration::milliseconds(950);
let mut game_board = None;
+ let mut strategy_cache = None;
for line in stdin().lock().lines() {
let start_time = PreciseTime::now();
@@ -23,13 +24,16 @@ fn main() {
match &mut game_board {
None => {
let new_board = game::GameBoard::new(json_state);
- let command = choose_move(&new_board, &start_time, max_time);
+ let (command, cache) = choose_move(&new_board, strategy_cache, &start_time, max_time);
+ strategy_cache = Some(cache);
game_board = Some(new_board);
command
},
Some(game_board) => {
game_board.update(json_state);
- choose_move(&game_board, &start_time, max_time)
+ let (command, cache) = choose_move(&game_board, strategy_cache, &start_time, max_time);
+ strategy_cache = Some(cache);
+ command
}
}
},
diff --git a/src/strategy.rs b/src/strategy.rs
index 8d2eea5..39bbe66 100644
--- a/src/strategy.rs
+++ b/src/strategy.rs
@@ -11,13 +11,30 @@ use rand;
use rand::prelude::*;
use arrayvec::ArrayVec;
-pub fn choose_move(state: &GameBoard, start_time: &PreciseTime, max_time: Duration) -> Command {
- let mut root_node = Node {
- state: state.clone(),
- score_sum: ScoreSum::new(),
- player_score_sums: [HashMap::new(), HashMap::new()],
- unexplored: mcts_move_combo(state),
- children: HashMap::new(),
+pub fn choose_move(state: &GameBoard, previous_root: Option<Node>, start_time: &PreciseTime, max_time: Duration) -> (Command, Node) {
+ let mut root_node = match previous_root {
+ None => Node {
+ state: state.clone(),
+ score_sum: ScoreSum::new(),
+ player_score_sums: [HashMap::new(), HashMap::new()],
+ unexplored: mcts_move_combo(state),
+ children: HashMap::new(),
+ },
+ Some(mut node) => {
+ node.children.drain()
+ .map(|(_k, n)| n)
+ .find(|n| n.state == *state)
+ .unwrap_or_else(|| {
+ eprintln!("Previous round did not appear in the cache");
+ Node {
+ state: state.clone(),
+ score_sum: ScoreSum::new(),
+ player_score_sums: [HashMap::new(), HashMap::new()],
+ unexplored: mcts_move_combo(state),
+ children: HashMap::new(),
+ }
+ })
+ }
};
while start_time.to(PreciseTime::now()) < max_time {
@@ -34,10 +51,14 @@ pub fn choose_move(state: &GameBoard, start_time: &PreciseTime, max_time: Durati
);
}
- best_player_move(&root_node)
+ let chosen_command = best_player_move(&root_node);
+
+ root_node.children.retain(|[c1, _], _| *c1 == chosen_command);
+
+ (chosen_command, root_node)
}
-struct Node {
+pub struct Node {
state: GameBoard,
score_sum: ScoreSum,
player_score_sums: [HashMap<Command, ScoreSum>; 2],