From b7e5273627c1b6db9faf8e29e2445bdbba802453 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 26 Jun 2019 20:31:04 +0200 Subject: Passing bomb count through from the json --- src/game.rs | 35 ++++++++++++++++++++++++++++++----- src/game/player.rs | 33 ++++++++++++++++++++++----------- src/json.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 17 deletions(-) diff --git a/src/game.rs b/src/game.rs index ffa8cb9..a08fff2 100644 --- a/src/game.rs +++ b/src/game.rs @@ -14,6 +14,7 @@ use map::*; use arrayvec::ArrayVec; use fnv::FnvHashSet; +// TODO: How much sense does it actually make to split the worms between the players? #[derive(Debug, PartialEq, Eq, Clone)] pub struct GameBoard { pub round: u16, @@ -47,6 +48,7 @@ impl GameBoard { position: Point2d::new(w.position.x, w.position.y), weapon_damage: commando_damage, weapon_range: commando_range, + bombs: w.banana_bombs.as_ref().map(|b| b.count).unwrap_or(0) }).collect(), }; @@ -59,7 +61,8 @@ impl GameBoard { health: w.health, position: Point2d::new(w.position.x, w.position.y), weapon_damage: commando_damage, - weapon_range: commando_range + weapon_range: commando_range, + bombs: if w.health == 100 { 3 } else { 0 } // TODO: parse and check worm type rather, move these out to constants }).collect() }; @@ -143,7 +146,7 @@ impl GameBoard { self.simulate_select(moves); self.simulate_moves(actions); self.simulate_digs(actions); - // TODO: simulate_bombs + self.simulate_bombs(actions); self.simulate_shoots(actions); for player in &mut self.players { @@ -244,6 +247,28 @@ 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 + + for player_index in 0..actions.len() { + if let Action::Bomb(p) = actions[player_index] { + if let Some(worm) = self.players[player_index].active_worm_mut() { + debug_assert!(worm.bombs > 0, "Worm is throwing a bomb 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.bombs = worm.bombs.saturating_sub(1); + + let damage_radius = 2; + // damage as per https://forum.entelect.co.za/uploads/default/original/2X/8/89e6e6cf35791a0448b5a6bbeb63c558ce41804a.jpeg + + // TODO: Clear up dirt and give points + // TODO: Hurt all worm and give / remove points + } + } + } + + } fn simulate_shoots(&mut self, actions: [Action; 2]) { 'players_loop: for player_index in 0..actions.len() { @@ -255,7 +280,7 @@ impl GameBoard { let diff = dir.as_vec(); let range = if dir.is_diagonal() { - ((weapon_range as f32 + 1.) / 2f32.sqrt()).floor() as i8 + ((f32::from(weapon_range) + 1.) / 2f32.sqrt()).floor() as i8 } else { weapon_range as i8 }; @@ -271,10 +296,10 @@ impl GameBoard { if let Some(target_worm) = target_own_worm { target_worm.health -= weapon_damage; 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.players[player_index].moves_score -= 40; self.occupied_cells.remove(&target_worm.position); } else { + // TODO: Review these points self.players[player_index].moves_score -= 20; } continue 'players_loop; diff --git a/src/game/player.rs b/src/game/player.rs index 32e45bf..38d78d0 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -16,6 +16,7 @@ pub struct Worm { pub position: Point2d, pub weapon_damage: i32, pub weapon_range: u8, + pub bombs: u8 } impl Player { @@ -94,21 +95,24 @@ mod test { health: 50, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 2, health: 10, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 3, health: -2, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); let mut player = Player { active_worm: 1, @@ -134,21 +138,24 @@ mod test { health: 0, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 2, health: 10, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 3, health: 2, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); let mut player = Player { active_worm: 1, @@ -174,27 +181,30 @@ mod test { health: 0, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 2, health: 10, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); worms.push(Worm { id: 3, health: 2, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); let mut player = Player { active_worm: 0, moves_score: 0, worms, - select_moves: 0, + select_moves: 0 }; player.clear_dead_worms(); @@ -214,7 +224,8 @@ mod test { health: -10, position: Point2d::new(0, 0), weapon_damage: 5, - weapon_range: 5 + weapon_range: 5, + bombs: 0 }); let mut player = Player { active_worm: 0, diff --git a/src/json.rs b/src/json.rs index 252481c..798c567 100644 --- a/src/json.rs +++ b/src/json.rs @@ -53,6 +53,7 @@ pub struct PlayerWorm { pub digging_range: u32, pub movement_range: u32, pub weapon: Weapon, + pub banana_bombs: Option } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] @@ -152,6 +153,15 @@ pub struct Weapon { pub range: u8, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Bomb { + pub damage: i32, + pub range: u8, + pub count: u8, + pub damage_radius: u8 +} + impl State { pub fn active_worm_index(&self) -> Option { self.my_player @@ -193,8 +203,30 @@ mod test { "damage": 1, "range": 3 }, + "bananaBombs": { + "damage": 20, + "range": 5, + "count": 3, + "damageRadius": 2 + }, + "diggingRange": 1, + "movementRange": 1, + "profession": "Agent" + }, + { + "id": 2, + "health": 150, + "position": { + "x": 1, + "y": 16 + }, + "weapon": { + "damage": 1, + "range": 3 + }, "diggingRange": 1, - "movementRange": 1 + "movementRange": 1, + "profession": "Commando" } ] }, @@ -306,6 +338,23 @@ mod test { }, digging_range: 1, movement_range: 1, + banana_bombs: Some(Bomb { + damage: 20, + range: 5, + count: 3, + damage_radius: 2 + }), + }, PlayerWorm { + id: 2, + health: 150, + position: Position { x: 1, y: 16 }, + weapon: Weapon { + damage: 1, + range: 3, + }, + digging_range: 1, + movement_range: 1, + banana_bombs: None, }], }, opponents: vec![Opponent { -- cgit v1.2.3