summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-08-07 13:37:49 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-08-07 13:37:49 +0200
commit952c8653115483163ce0df38e6c8c1a0d31a84fd (patch)
treeff740aefae37f201b4a538ac7cf4dac8047b8f07
parente8b28dbbcde3d00a9d82637644734b6c7e79b544 (diff)
Added snowballs to valid moves
-rw-r--r--src/constants.rs2
-rw-r--r--src/game.rs59
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<i8>, i32); BOMB_DAMAGED_SPACES] = [
(Vec2d::new(0, -2), 7),
@@ -173,6 +174,7 @@ pub const BOMB_DAMAGES: [(Vec2d<i8>, 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<i8>; 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<Command> {
+ 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<Command> {
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()