summaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-05-26 18:24:16 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-05-26 18:24:16 +0200
commit6917ffc2a3c571782c8a3b473e02d5ccf39cd7c0 (patch)
treeeb96be9d981e66aae639f69ff1eeeae08ecf51b3 /src/game.rs
parent9450ab5a6bf6b2aa57c1ebbd0be0a88c1110e140 (diff)
A bit faster through caching set of occupied spots
Diffstat (limited to 'src/game.rs')
-rw-r--r--src/game.rs29
1 files changed, 21 insertions, 8 deletions
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<Point2d<i8>>,
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::<ArrayVec<[Point2d<i8>; 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)),