diff options
Diffstat (limited to 'src/strategy/minimax.rs')
-rw-r--r-- | src/strategy/minimax.rs | 37 |
1 files changed, 30 insertions, 7 deletions
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<Command> { - // 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<Command> { |