summaryrefslogtreecommitdiff
path: root/src/strategy/minimax.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/strategy/minimax.rs')
-rw-r--r--src/strategy/minimax.rs37
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> {