diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2019-05-26 00:28:28 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2019-05-26 00:28:28 +0200 |
commit | d37be51f196eebdb8df57c87e8ab5bb684e1dcd9 (patch) | |
tree | 9625bf847698fd4072682839ede1f917c74bebbd /src/game.rs | |
parent | 7b3fe83b4bdb943d3d44ed036150d017279cfe05 (diff) |
Score based MCTS
Diffstat (limited to 'src/game.rs')
-rw-r--r-- | src/game.rs | 177 |
1 files changed, 91 insertions, 86 deletions
diff --git a/src/game.rs b/src/game.rs index 2112076..982c276 100644 --- a/src/game.rs +++ b/src/game.rs @@ -153,8 +153,9 @@ impl GameBoard { // here. I'm treating that as an edge case that I // don't need to handle for now. for player in &mut self.players { - let worm = player.active_worm_mut(); - worm.health = worm.health.saturating_sub(damage); + if let Some(worm) = player.active_worm_mut() { + worm.health = worm.health.saturating_sub(damage); + } player.moves_score += 5; } }, @@ -165,24 +166,24 @@ impl GameBoard { self.players[player_index].moves_score += 5; - let worm = self.players[player_index].active_worm_mut(); - - debug_assert!( - (worm.position.x - p.x).abs() <= 1 && - (worm.position.y - p.y).abs() <= 1, - "Tried to move too far away, ({}, {})", p.x, p.y - ); - - worm.position = p; - - self.powerups.retain(|power| { - if power.position == worm.position { - worm.health += power.value; - false - } else { - true - } - }); + if let Some(worm) = self.players[player_index].active_worm_mut() { + debug_assert!( + (worm.position.x - p.x).abs() <= 1 && + (worm.position.y - p.y).abs() <= 1, + "Tried to move too far away, ({}, {})", p.x, p.y + ); + + worm.position = p; + + self.powerups.retain(|power| { + if power.position == worm.position { + worm.health += power.value; + false + } else { + true + } + }); + } } } } @@ -198,8 +199,8 @@ impl GameBoard { "Tried to dig through air, ({}, {})", p.x, p.y ); debug_assert!{ - (self.players[player_index].active_worm().position.x - p.x).abs() <= 1 && - (self.players[player_index].active_worm().position.y - p.y).abs() <= 1, + (self.players[player_index].active_worm().unwrap().position.x - p.x).abs() <= 1 && + (self.players[player_index].active_worm().unwrap().position.y - p.y).abs() <= 1, "Tried to dig too far away, ({}, {})", p.x, p.y }; @@ -213,57 +214,58 @@ impl GameBoard { fn simulate_shoots(&mut self, moves: [Command; 2]) { 'players_loop: for player_index in 0..moves.len() { if let Command::Shoot(dir) = moves[player_index] { - let (center, weapon_range, weapon_damage) = { - let worm = self.players[player_index].active_worm(); - (worm.position, worm.weapon_range, worm.weapon_damage) - }; - let diff = dir.as_vec(); - - let range = if dir.is_diagonal() { - ((weapon_range as f32 + 1.) / 2f32.sqrt()).floor() as i8 - } else { - weapon_range as i8 - }; - - for distance in 1..=range { - let target = center + diff * distance; - match self.map.at(target) { - Some(false) => { - let target_own_worm: Option<&mut Worm> = self.players[player_index] - .worms.iter_mut() - .find(|w| w.position == target); - - if let Some(target_worm) = target_own_worm { - target_worm.health -= weapon_damage; - if target_worm.health <= 0 { - // TODO: This will probably be changed soon https://github.com/EntelectChallenge/2019-Worms/issues/42 - self.players[player_index].moves_score += 40; - } else { - self.players[player_index].moves_score -= 20; + if let Some(worm) = self.players[player_index].active_worm() { + let (center, weapon_range, weapon_damage) = { + (worm.position, worm.weapon_range, worm.weapon_damage) + }; + let diff = dir.as_vec(); + + let range = if dir.is_diagonal() { + ((weapon_range as f32 + 1.) / 2f32.sqrt()).floor() as i8 + } else { + weapon_range as i8 + }; + + for distance in 1..=range { + let target = center + diff * distance; + match self.map.at(target) { + Some(false) => { + let target_own_worm: Option<&mut Worm> = self.players[player_index] + .worms.iter_mut() + .find(|w| w.position == target); + + if let Some(target_worm) = target_own_worm { + target_worm.health -= weapon_damage; + if target_worm.health <= 0 { + // TODO: This will probably be changed soon https://github.com/EntelectChallenge/2019-Worms/issues/42 + self.players[player_index].moves_score += 40; + } else { + self.players[player_index].moves_score -= 20; + } + continue 'players_loop; } - continue 'players_loop; - } - - let target_opponent_worm: Option<&mut Worm> = self.players[GameBoard::opponent(player_index)] - .worms.iter_mut() - .find(|w| w.position == target); - if let Some(target_worm) = target_opponent_worm { - target_worm.health -= weapon_damage; - if target_worm.health <= 0 { - self.players[player_index].moves_score += 40; - } else { - self.players[player_index].moves_score += 20; + + let target_opponent_worm: Option<&mut Worm> = self.players[GameBoard::opponent(player_index)] + .worms.iter_mut() + .find(|w| w.position == target); + if let Some(target_worm) = target_opponent_worm { + target_worm.health -= weapon_damage; + if target_worm.health <= 0 { + self.players[player_index].moves_score += 40; + } else { + self.players[player_index].moves_score += 20; + } + + continue 'players_loop; } - - continue 'players_loop; - } - }, - _ => break + }, + _ => break + } } - } - // You get here if the shot missed. Hits are an early return. - self.players[player_index].moves_score += 2; + // You get here if the shot missed. Hits are an early return. + self.players[player_index].moves_score += 2; + } } } } @@ -274,23 +276,26 @@ impl GameBoard { pub fn valid_move_commands(&self, player_index: usize) -> ArrayVec<[Command;8]> { - let worm = self.players[player_index].active_worm(); - let taken_positions = self.players.iter() - .flat_map(|p| p.worms.iter()) - .map(|w| w.position) - .collect::<ArrayVec<[Point2d<i8>; 6]>>(); - - Direction::all() - .iter() - .map(Direction::as_vec) - .map(|d| worm.position + d) - .filter(|p| !taken_positions.contains(p)) - .filter_map(|p| match self.map.at(p) { - Some(false) => Some(Command::Move(p)), - Some(true) => Some(Command::Dig(p)), - _ => None, - }) - .collect() + if let Some(worm) = self.players[player_index].active_worm() { + let taken_positions = self.players.iter() + .flat_map(|p| p.worms.iter()) + .map(|w| w.position) + .collect::<ArrayVec<[Point2d<i8>; 6]>>(); + + Direction::all() + .iter() + .map(Direction::as_vec) + .map(|d| worm.position + d) + .filter(|p| !taken_positions.contains(p)) + .filter_map(|p| match self.map.at(p) { + Some(false) => Some(Command::Move(p)), + Some(true) => Some(Command::Dig(p)), + _ => None, + }) + .collect() + } else { + ArrayVec::new() + } } pub fn valid_shoot_commands(&self, player_index: usize, center: Point2d<i8>, weapon_range: u8) -> ArrayVec<[Command;8]> { |