From 952c8653115483163ce0df38e6c8c1a0d31a84fd Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 7 Aug 2019 13:37:49 +0200 Subject: Added snowballs to valid moves --- src/constants.rs | 2 ++ src/game.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index d796e57..1c2b8a1 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -156,6 +156,7 @@ impl MapRow { } } +pub const BOMB_RANGE: i8 = 5; pub const BOMB_DAMAGED_SPACES: usize = 13; pub const BOMB_DAMAGES: [(Vec2d, i32); BOMB_DAMAGED_SPACES] = [ (Vec2d::new(0, -2), 7), @@ -173,6 +174,7 @@ pub const BOMB_DAMAGES: [(Vec2d, i32); BOMB_DAMAGED_SPACES] = [ (Vec2d::new(0, 0), 20), ]; +pub const SNOWBALL_RANGE: i8 = 5; pub const SNOWBALL_FREEZES_SPACES: usize = 9; pub const SNOWBALL_FREEZES: [Vec2d; SNOWBALL_FREEZES_SPACES] = [ Vec2d::new(-1, -1), diff --git a/src/game.rs b/src/game.rs index f49f582..6b7897d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -619,12 +619,15 @@ impl GameBoard { }; if select.is_none() || self.players[player_index].select_moves > 0 { - let mut result = Vec::with_capacity(11 * 11 - 12); + let mut result = Vec::with_capacity((BOMB_RANGE * 2 + 1).pow(2) as usize - 12); - for y in worm.position.y - 5..=worm.position.y + 5 { - for x in worm.position.x - 5..=worm.position.x + 5 { + for y in worm.position.y - BOMB_RANGE..=worm.position.y + BOMB_RANGE { + for x in worm.position.x - BOMB_RANGE..=worm.position.x + BOMB_RANGE { let target = Point2d::new(x, y); - if (worm.position - target).magnitude_squared() < 36 { + if self.map.at(target).is_some() + && (worm.position - target).magnitude_squared() + < (BOMB_RANGE + 1).pow(2) + { result.push(Command { worm: select, action: Action::Bomb(target), @@ -642,6 +645,50 @@ impl GameBoard { } } + pub fn valid_snowball_commands(&self, player_index: usize) -> Vec { + let tech_worm = self.players[player_index] + .worms + .iter() + .enumerate() + .find(|(_p, w)| w.snowballs > 0); + match tech_worm { + Some((worm_i, worm)) => { + let select = if worm_i == self.players[player_index].active_worm { + None + } else { + Some(worm.id) + }; + + if select.is_none() || self.players[player_index].select_moves > 0 { + let mut result = + Vec::with_capacity((SNOWBALL_RANGE * 2 + 1).pow(2) as usize - 12); // -12 is from 3 on each corner + + // TODO: Extract to share with bomb throwing + for y in worm.position.y - SNOWBALL_RANGE..=worm.position.y + SNOWBALL_RANGE { + for x in worm.position.x - SNOWBALL_RANGE..=worm.position.x + SNOWBALL_RANGE + { + let target = Point2d::new(x, y); + if self.map.at(target).is_some() + && (worm.position - target).magnitude_squared() + < (SNOWBALL_RANGE + 1).pow(2) + { + result.push(Command { + worm: select, + action: Action::Snowball(target), + }); + } + } + } + + result + } else { + Vec::new() + } + } + None => Vec::new(), + } + } + pub fn sensible_shoot_commands( &self, player_index: usize, @@ -696,12 +743,14 @@ impl GameBoard { .collect() } - // TODO: Include snowball commands + // TODO: If worm is frozen, there's only one option :( + // TODO: If all of this can be iterators, I can pass in the final filter to this function and only collect once. pub fn valid_moves(&self, player_index: usize) -> Vec { self.valid_shoot_commands(player_index) .iter() .chain(self.valid_move_commands(player_index).iter()) .chain(self.valid_bomb_commands(player_index).iter()) + .chain(self.valid_snowball_commands(player_index).iter()) .chain([Command::new(Action::DoNothing)].iter()) .cloned() .collect() -- cgit v1.2.3