From 770f14609849552d965b4e9101bfb5c0870c08d0 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Mon, 8 Jul 2019 22:31:41 +0200 Subject: Command filtering to avoid wasting the selects --- src/game.rs | 4 ++-- src/geometry/direction.rs | 25 +++++++++++-------------- src/strategy.rs | 7 ++++--- src/strategy/minimax.rs | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/game.rs b/src/game.rs index 4e074ea..c31f64f 100644 --- a/src/game.rs +++ b/src/game.rs @@ -458,7 +458,7 @@ impl GameBoard { } pub fn valid_moves_for_worm(&self, worm: &Worm) -> ArrayVec<[Action; 8]> { - Direction::all() + Direction::ALL .iter() .map(Direction::as_vec) .map(|d| worm.position + d) @@ -491,7 +491,7 @@ impl GameBoard { } pub fn valid_shoot_commands(&self, player_index: usize) -> ArrayVec<[Command; 24]> { - let all_dirs = Direction::all(); + let all_dirs = Direction::ALL; let no_select = all_dirs.iter().map(|d| Command::new(Action::Shoot(*d))); self.valid_selects(player_index) diff --git a/src/geometry/direction.rs b/src/geometry/direction.rs index 737bd00..d3f3b20 100644 --- a/src/geometry/direction.rs +++ b/src/geometry/direction.rs @@ -1,5 +1,5 @@ -use std::fmt; use crate::geometry::vec::Vec2d; +use std::fmt; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Direction { @@ -54,17 +54,14 @@ impl Direction { } } - pub fn all() -> [Direction; 8] { - use Direction::*; - [ - North, - NorthEast, - East, - SouthEast, - South, - SouthWest, - West, - NorthWest, - ] - } + pub const ALL: [Direction; 8] = [ + Direction::North, + Direction::NorthEast, + Direction::East, + Direction::SouthEast, + Direction::South, + Direction::SouthWest, + Direction::West, + Direction::NorthWest, + ]; } diff --git a/src/strategy.rs b/src/strategy.rs index 9c79d60..b6069a1 100644 --- a/src/strategy.rs +++ b/src/strategy.rs @@ -1,4 +1,5 @@ -mod mcts; -mod minimax; +//mod mcts; +//pub use mcts::{choose_move, Node}; -pub use mcts::{choose_move, Node}; +mod minimax; +pub use minimax::{choose_move, Node}; diff --git a/src/strategy/minimax.rs b/src/strategy/minimax.rs index 2ed84b2..31e58a0 100644 --- a/src/strategy/minimax.rs +++ b/src/strategy/minimax.rs @@ -23,7 +23,7 @@ pub fn choose_move( .children .drain() .map(|(_k, n)| n) - .find(|n| false) // TODO: Identify the last opponent move to use this cache + .find(|_n| false) // TODO: Identify the last opponent move to use this cache .unwrap_or_else(|| { eprintln!("Previous round did not appear in the cache"); Node { @@ -227,14 +227,37 @@ fn update(node: &mut Node, commands: [Command; 2], score: Score) { } fn pruned_moves(state: &GameBoard, player_index: usize) -> Vec { - // TODO: Play one move into the future and make sure this doesn't - // hurt me or do something dumb? Should I rather specialize this - // to each type of move? + let sim_with_idle_opponent = |cmd| { + let mut idle_commands = [ + Command::new(Action::DoNothing), + Command::new(Action::DoNothing), + ]; + idle_commands[player_index] = cmd; + let mut state_cpy = state.clone(); + state_cpy.simulate(idle_commands); + state_cpy + }; + + let opponent_index = GameBoard::opponent(player_index); + let my_starting_health = state.players[player_index].health(); + let opponent_starting_health = state.players[opponent_index].health(); - // TODO: Ensure that there are at least some moves left here. If - // there's nothing, at least return a vector that contains a - // nothing move. valid_moves(state, player_index) + .into_iter() + .filter(|command| { + //NB: These rules should pass for doing nothing, otherwise + // we need some other mechanism for sticking in a do + // nothing option + + let idle_opponent_state = sim_with_idle_opponent(*command); + let hurt_self = idle_opponent_state.players[player_index].health() < my_starting_health; + let hurt_opponent = + idle_opponent_state.players[opponent_index].health() < opponent_starting_health; + let is_select = command.worm.is_some(); + + !hurt_self && (!is_select || hurt_opponent) + }) + .collect() } fn valid_moves(state: &GameBoard, player_index: usize) -> Vec { -- cgit v1.2.3