diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2019-07-08 22:31:41 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2019-07-08 22:31:41 +0200 |
commit | 770f14609849552d965b4e9101bfb5c0870c08d0 (patch) | |
tree | 170ebb08b86ccc5027752f37bf0dda4be516a2b7 /src/strategy | |
parent | 2d4647a618234ef496899d875f75d57b5af1a6e5 (diff) |
Command filtering to avoid wasting the selects
Diffstat (limited to 'src/strategy')
-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> { |