From 6917ffc2a3c571782c8a3b473e02d5ccf39cd7c0 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sun, 26 May 2019 18:24:16 +0200 Subject: A bit faster through caching set of occupied spots --- src/game.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/game.rs b/src/game.rs index 982c276..18731a2 100644 --- a/src/game.rs +++ b/src/game.rs @@ -12,6 +12,7 @@ mod map; use map::*; use arrayvec::ArrayVec; +use fnv::FnvHashSet; #[derive(Debug, PartialEq, Eq, Clone)] pub struct GameBoard { @@ -20,6 +21,7 @@ pub struct GameBoard { pub players: [Player; 2], pub powerups: ArrayVec<[Powerup; 2]>, pub map: Map, + pub occupied_cells: FnvHashSet>, pub outcome: SimulationOutcome } @@ -65,11 +67,17 @@ impl GameBoard { map.set(Point2d::new(cell.x, cell.y)) } } + + let players = [player, opponent]; + let occupied_cells = players.iter() + .flat_map(|p| p.worms.iter()) + .map(|w| w.position) + .collect(); GameBoard { round: json.current_round, max_rounds: json.max_rounds, - players: [player, opponent], + players, powerups: json.map.iter().flatten().filter_map(|c| { c.powerup.as_ref().map(|p| Powerup { position: Point2d::new(c.x, c.y), @@ -77,6 +85,7 @@ impl GameBoard { }) }).collect(), map, + occupied_cells, outcome: SimulationOutcome::Continue } } @@ -119,6 +128,11 @@ impl GameBoard { self.round += 1; debug_assert_eq!(json.current_round, self.round); + + self.occupied_cells = self.players.iter() + .flat_map(|p| p.worms.iter()) + .map(|w| w.position) + .collect(); } pub fn simulate(&mut self, moves: [Command; 2]) { @@ -173,6 +187,9 @@ impl GameBoard { "Tried to move too far away, ({}, {})", p.x, p.y ); + self.occupied_cells.remove(&worm.position); + self.occupied_cells.insert(p); + worm.position = p; self.powerups.retain(|power| { @@ -239,6 +256,7 @@ impl GameBoard { 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; + self.occupied_cells.remove(&target_worm.position); } else { self.players[player_index].moves_score -= 20; } @@ -252,6 +270,7 @@ impl GameBoard { target_worm.health -= weapon_damage; if target_worm.health <= 0 { self.players[player_index].moves_score += 40; + self.occupied_cells.remove(&target_worm.position); } else { self.players[player_index].moves_score += 20; } @@ -274,19 +293,13 @@ impl GameBoard { (player_index + 1)%2 } - pub fn valid_move_commands(&self, player_index: usize) -> ArrayVec<[Command;8]> { 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::; 6]>>(); - Direction::all() .iter() .map(Direction::as_vec) .map(|d| worm.position + d) - .filter(|p| !taken_positions.contains(p)) + .filter(|p| !self.occupied_cells.contains(p)) .filter_map(|p| match self.map.at(p) { Some(false) => Some(Command::Move(p)), Some(true) => Some(Command::Dig(p)), -- cgit v1.2.3