diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2019-06-28 21:20:37 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2019-06-28 21:20:37 +0200 |
commit | a07cbfd67849b98a881f930e12e07c429e604ac4 (patch) | |
tree | 4b4ad859c169d6366ca2e6e91d0ef09e5986396f /src/strategy.rs | |
parent | e20e7f0a9029d33c67869951371cc03965127b31 (diff) |
updated active worm in update
This might change weirdly because of the select move.
Diffstat (limited to 'src/strategy.rs')
-rw-r--r-- | src/strategy.rs | 79 |
1 files changed, 45 insertions, 34 deletions
diff --git a/src/strategy.rs b/src/strategy.rs index 502e9f2..e2bf71d 100644 --- a/src/strategy.rs +++ b/src/strategy.rs @@ -1,4 +1,4 @@ -use crate::command::{Command, Action}; +use crate::command::{Action, Command}; use crate::game::{GameBoard, SimulationOutcome}; use std::cmp; @@ -9,7 +9,12 @@ use time::{Duration, PreciseTime}; use rand; use rand::prelude::*; -pub fn choose_move(state: &GameBoard, previous_root: Option<Node>, start_time: &PreciseTime, max_time: Duration) -> (Command, Node) { +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(), @@ -18,21 +23,21 @@ pub fn choose_move(state: &GameBoard, previous_root: Option<Node>, start_time: & 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(), - } - }) - } + 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 { @@ -51,8 +56,10 @@ pub fn choose_move(state: &GameBoard, previous_root: Option<Node>, start_time: & let chosen_command = best_player_move(&root_node); - root_node.children.retain(|[c1, _], _| *c1 == chosen_command); - + root_node + .children + .retain(|[c1, _], _| *c1 == chosen_command); + (chosen_command, root_node) } @@ -162,9 +169,9 @@ fn mcts(node: &mut Node) -> Score { fn mcts_move_combo(state: &GameBoard) -> Vec<[Command; 2]> { let player_moves = valid_moves(state, 0); let opponent_moves = valid_moves(state, 1); - debug_assert!(player_moves.len() > 0, "No player moves"); - debug_assert!(player_moves.len() > 0, "No opponent moves"); - + debug_assert!(!player_moves.is_empty(), "No player moves"); + debug_assert!(!opponent_moves.is_empty(), "No opponent moves"); + let mut result = Vec::with_capacity(player_moves.len() * opponent_moves.len()); for p in &player_moves { for o in &opponent_moves { @@ -189,7 +196,7 @@ fn score(state: &GameBoard) -> Score { SimulationOutcome::PlayerWon(0) => 500., SimulationOutcome::PlayerWon(1) => -500., _ => (state.players[0].score() - state.players[1].score()) as f32, - } + }, } } @@ -245,26 +252,30 @@ fn update(node: &mut Node, commands: [Command; 2], score: Score) { fn rollout_moves(state: &GameBoard, player_index: usize) -> Vec<Command> { // TODO: Have this return one move, chosen randomly? - // TODO: Allow new select / bomb moves - if let Some(worm) = state.players[player_index].active_worm() { + // TODO: Heuristic based move + valid_moves(state, player_index) + // + // if let Some(worm) = state.players[player_index].active_worm() { - let shoots = state.sensible_shoot_commands(player_index, worm.position, worm.weapon_range); + // let shoots = state.sensible_shoot_commands(player_index, worm.position, worm.weapon_range); - if !shoots.is_empty() { - return shoots.into_iter().collect(); - } + // if !shoots.is_empty() { + // return shoots.into_iter().collect(); + // } - state.valid_move_commands(player_index).into_iter().collect() - } else { - [Command::new(Action::DoNothing)].into_iter().cloned().collect() - } + // state.valid_move_commands(player_index).into_iter().collect() + // } else { + // [Command::new(Action::DoNothing)].into_iter().cloned().collect() + // } } fn valid_moves(state: &GameBoard, player_index: usize) -> Vec<Command> { - state.valid_shoot_commands(player_index) + state + .valid_shoot_commands(player_index) .iter() .chain(state.valid_move_commands(player_index).iter()) .chain(state.valid_bomb_commands(player_index).iter()) + .chain([Command::new(Action::DoNothing)].iter()) .cloned() .collect() } |