summaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-05-26 00:28:28 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-05-26 00:28:28 +0200
commitd37be51f196eebdb8df57c87e8ab5bb684e1dcd9 (patch)
tree9625bf847698fd4072682839ede1f917c74bebbd /src/game.rs
parent7b3fe83b4bdb943d3d44ed036150d017279cfe05 (diff)
Score based MCTS
Diffstat (limited to 'src/game.rs')
-rw-r--r--src/game.rs177
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]> {