From 05cd604ed4090664c0f7522e34c19de76e1c6b27 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Tue, 6 Aug 2019 15:06:43 +0200 Subject: Frozen worms --- src/game.rs | 47 +++++++++++++++++++++++++----- src/game/player.rs | 85 ++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 93 insertions(+), 39 deletions(-) diff --git a/src/game.rs b/src/game.rs index b3cfc62..4e07e2f 100644 --- a/src/game.rs +++ b/src/game.rs @@ -52,7 +52,9 @@ impl GameBoard { position: Point2d::new(w.position.x, w.position.y), weapon_damage: commando_damage, weapon_range: commando_range, + rounds_until_unfrozen: w.rounds_until_unfrozen, bombs: w.banana_bombs.as_ref().map(|b| b.count).unwrap_or(0), + snowballs: w.snowballs.as_ref().map(|b| b.count).unwrap_or(0), }) .collect(), }; @@ -71,11 +73,17 @@ impl GameBoard { position: Point2d::new(w.position.x, w.position.y), weapon_damage: commando_damage, weapon_range: commando_range, + rounds_until_unfrozen: w.rounds_until_unfrozen, bombs: if w.profession == json::WormType::Agent { STARTING_BOMBS } else { 0 }, + snowballs: if w.profession == json::WormType::Technologist { + STARTING_SNOWBALLS + } else { + 0 + }, }) .collect(), }; @@ -169,20 +177,22 @@ impl GameBoard { .flat_map(|p| p.worms.iter()) .map(|w| w.position) .collect(); + + // TODO: Do some asssertions about the state of lava } pub fn simulate(&mut self, moves: [Command; 2]) { - let actions = [moves[0].action, moves[1].action]; - - // TODO: move lava in - // TODO: hurt worms that are standing on lava - // TODO: tick frozen timers - + self.simulate_worms_on_lava(); + self.simulate_tick_frozen_timers(); self.simulate_select(moves); + + let actions = self.identify_actions(moves); + // TODO: Simulate frozen worms (nullify their actions) self.simulate_moves(actions); self.simulate_digs(actions); self.simulate_bombs(actions); - // TODO: simulalte snowballs (question order on forums?) + // TODO: Question order of actions on the forums + self.simulate_snowballs(actions); self.simulate_shoots(actions); for player in &mut self.players { @@ -205,6 +215,25 @@ impl GameBoard { }; } + fn simulate_worms_on_lava(&mut self) { + // TODO + } + + fn simulate_tick_frozen_timers(&mut self) { + // TODO + } + + fn identify_actions(&self, moves: [Command; 2]) -> [Action; 2] { + let mut it = self.players.iter().zip(moves.iter()).map(|(p, m)| { + if p.active_worm_is_frozen() { + Action::DoNothing + } else { + m.action + } + }); + [it.next().unwrap(), it.next().unwrap()] + } + fn simulate_select(&mut self, moves: [Command; 2]) { moves .iter() @@ -368,6 +397,10 @@ impl GameBoard { } } + pub fn simulate_snowballs(&mut self, actions: [Action; 2]) { + // TODO: simulalte snowballs + } + fn simulate_shoots(&mut self, actions: [Action; 2]) { 'players_loop: for player_index in 0..actions.len() { if let Action::Shoot(dir) = actions[player_index] { diff --git a/src/game/player.rs b/src/game/player.rs index 38d78d0..be9d515 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -1,5 +1,5 @@ -use arrayvec::ArrayVec; use crate::geometry::*; +use arrayvec::ArrayVec; #[derive(Debug, PartialEq, Eq, Clone)] pub struct Player { @@ -16,26 +16,22 @@ pub struct Worm { pub position: Point2d, pub weapon_damage: i32, pub weapon_range: u8, - pub bombs: u8 + pub bombs: u8, + pub snowballs: u8, + pub rounds_until_unfrozen: u8, } impl Player { pub fn find_worm_position(&self, id: i32) -> Option { - self.worms - .iter() - .position(|w| w.id == id) + self.worms.iter().position(|w| w.id == id) } - + pub fn find_worm(&self, id: i32) -> Option<&Worm> { - self.worms - .iter() - .find(|w| w.id == id) + self.worms.iter().find(|w| w.id == id) } pub fn find_worm_mut(&mut self, id: i32) -> Option<&mut Worm> { - self.worms - .iter_mut() - .find(|w| w.id == id) + self.worms.iter_mut().find(|w| w.id == id) } pub fn active_worm(&self) -> Option<&Worm> { @@ -47,10 +43,7 @@ impl Player { } pub fn health(&self) -> i32 { - self.worms - .iter() - .map(|w| w.health) - .sum() + self.worms.iter().map(|w| w.health).sum() } pub fn clear_dead_worms(&mut self) { @@ -61,7 +54,7 @@ impl Player { self.active_worm = if self.active_worm > 0 { self.active_worm - 1 } else if self.worms.len() > 0 { - self.worms.len() - 1 + self.worms.len() - 1 } else { 0 }; @@ -71,7 +64,9 @@ impl Player { } pub fn next_active_worm(&mut self) { - self.active_worm = (self.active_worm + 1).checked_rem(self.worms.len()).unwrap_or(0); + self.active_worm = (self.active_worm + 1) + .checked_rem(self.worms.len()) + .unwrap_or(0); } fn health_score(&self) -> i32 { @@ -81,12 +76,18 @@ impl Player { pub fn score(&self) -> i32 { self.moves_score + self.health_score() } + + pub fn active_worm_is_frozen(&self) -> bool { + self.active_worm() + .map(|worm| worm.rounds_until_unfrozen > 0) + .unwrap_or(false) + } } #[cfg(test)] mod test { use super::*; - + #[test] fn clear_dead_worms_after_active_worm() { let mut worms = ArrayVec::new(); @@ -96,7 +97,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 2, @@ -104,7 +107,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 3, @@ -112,13 +117,15 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); let mut player = Player { active_worm: 1, moves_score: 0, select_moves: 0, - worms + worms, }; player.clear_dead_worms(); @@ -139,7 +146,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 2, @@ -147,7 +156,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 3, @@ -155,7 +166,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); let mut player = Player { active_worm: 1, @@ -182,7 +195,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 2, @@ -190,7 +205,9 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); worms.push(Worm { id: 3, @@ -198,13 +215,15 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); let mut player = Player { active_worm: 0, moves_score: 0, worms, - select_moves: 0 + select_moves: 0, }; player.clear_dead_worms(); @@ -225,13 +244,15 @@ mod test { position: Point2d::new(0, 0), weapon_damage: 5, weapon_range: 5, - bombs: 0 + rounds_until_unfrozen: 0, + bombs: 0, + snowballs: 0, }); let mut player = Player { active_worm: 0, moves_score: 0, worms, - select_moves: 0 + select_moves: 0, }; player.clear_dead_worms(); -- cgit v1.2.3