summaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.rs')
-rw-r--r--src/game.rs72
1 files changed, 69 insertions, 3 deletions
diff --git a/src/game.rs b/src/game.rs
index fca740d..7ab7725 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -129,15 +129,36 @@ impl GameBoard {
worm.health = w.health;
worm.position = Point2d::new(w.position.x, w.position.y);
worm.bombs = w.banana_bombs.as_ref().map(|b| b.count).unwrap_or(0);
+ worm.snowballs = w.snowballs.as_ref().map(|b| b.count).unwrap_or(0);
}
}
for w in json.opponents.iter().flat_map(|o| &o.worms) {
if let Some(worm) = self.players[1].find_worm_mut(w.id) {
worm.health = w.health;
worm.position = Point2d::new(w.position.x, w.position.y);
- // TODO: Update number of bombs / snowballs based on previous move
}
}
+
+ // TODO: Good enough for now, but what if these worms are frozen?
+ if json
+ .opponents
+ .iter()
+ .any(|o| o.previous_command.starts_with("banana"))
+ {
+ for worm in &mut self.players[1].worms {
+ worm.bombs = worm.bombs.saturating_sub(1);
+ }
+ }
+ if json
+ .opponents
+ .iter()
+ .any(|o| o.previous_command.starts_with("snowball"))
+ {
+ for worm in &mut self.players[1].worms {
+ worm.snowballs = worm.snowballs.saturating_sub(1);
+ }
+ }
+
self.players[0].moves_score = json.my_player.score - json.my_player.health_score();
self.players[1].moves_score = json.opponents[0].score - json.opponents[0].health_score();
@@ -184,6 +205,7 @@ impl GameBoard {
pub fn simulate(&mut self, moves: [Command; 2]) {
self.simulate_worms_on_lava();
self.simulate_tick_frozen_timers();
+
self.simulate_select(moves);
let actions = self.identify_actions(moves);
@@ -193,6 +215,9 @@ impl GameBoard {
self.simulate_bombs(actions);
// TODO: Question order of actions on the forums
self.simulate_snowballs(actions);
+ // This check needs to happen again because the worm may have
+ // been frozen on the previous command.
+ let actions = self.identify_actions(moves);
self.simulate_shoots(actions);
for player in &mut self.players {
@@ -248,6 +273,7 @@ impl GameBoard {
moves
.iter()
.zip(self.players.iter_mut())
+ .filter(|(_m, player)| !player.active_worm_is_frozen())
.for_each(|(m, player)| {
if let Some(worm) = m.worm {
debug_assert!(
@@ -351,7 +377,7 @@ impl GameBoard {
fn simulate_bombs(&mut self, actions: [Action; 2]) {
// NB: Damage radius has the cell distance rounded UP, throwing range has the cell distance rounded DOWN
- let map_clone = self.map.clone();
+ let map_clone: Map = self.map;
for player_index in 0..actions.len() {
if let Action::Bomb(p) = actions[player_index] {
@@ -408,7 +434,47 @@ impl GameBoard {
}
pub fn simulate_snowballs(&mut self, actions: [Action; 2]) {
- // TODO: simulalte snowballs
+ let map_clone: Map = self.map;
+
+ for player_index in 0..actions.len() {
+ if let Action::Snowball(p) = actions[player_index] {
+ if self.map.at(p).is_some() {
+ if let Some(worm) = self.players[player_index].active_worm_mut() {
+ debug_assert!(
+ worm.snowballs > 0,
+ "Worm is throwing a snowball it doesn't have"
+ );
+ debug_assert!((worm.position - p).magnitude_squared() < 6 * 6); // max range is 5, but it's 5 after rounding down
+
+ worm.snowballs = worm.snowballs.saturating_sub(1);
+
+ for &freeze_offset in SNOWBALL_FREEZES.iter() {
+ let target = p + freeze_offset;
+
+ 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.rounds_until_unfrozen = FREEZE_DURATION;
+ self.players[player_index].moves_score -= FREEZE_SCORE;
+ }
+
+ 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.rounds_until_unfrozen = FREEZE_DURATION;
+ self.players[player_index].moves_score += FREEZE_SCORE;
+ }
+ }
+ }
+ }
+ }
+ }
}
fn simulate_shoots(&mut self, actions: [Action; 2]) {