From fe3fbbdd7b4c4cb243f859db63a0cc6070179839 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sat, 11 Aug 2018 23:02:35 +0200 Subject: Implemented most of the iron curtain changes Still need to - set it active - make the random move selection choose it - test against real engine --- src/engine/bitwise_engine.rs | 30 +++++++++++++++++++++++++++--- src/engine/command.rs | 4 +++- src/engine/constants.rs | 6 +++++- src/input/json.rs | 24 ++++++++++++++++++++++-- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/engine/bitwise_engine.rs b/src/engine/bitwise_engine.rs index 3dbd7fb..e9c1b0a 100644 --- a/src/engine/bitwise_engine.rs +++ b/src/engine/bitwise_engine.rs @@ -35,7 +35,10 @@ pub struct PlayerBuildings { pub firing_tower: usize, pub missiles: [(u64, u64); MISSILE_MAX_SINGLE_CELL], - pub tesla_cooldowns: ArrayVec<[TeslaCooldown; TESLA_MAX]> + pub tesla_cooldowns: ArrayVec<[TeslaCooldown; TESLA_MAX]>, + + pub iron_curtain_available: bool, + pub iron_curtain_remaining: u8, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -60,6 +63,9 @@ impl BitwiseGameState { BitwiseGameState::update_construction(&mut self.player_buildings); BitwiseGameState::update_construction(&mut self.opponent_buildings); + + BitwiseGameState::update_iron_curtain(&mut self.player_buildings); + BitwiseGameState::update_iron_curtain(&mut self.opponent_buildings); BitwiseGameState::fire_teslas(&mut self.player, &mut self.player_buildings, &mut self.opponent, &mut self.opponent_buildings); @@ -255,6 +261,14 @@ impl BitwiseGameState { } player_buildings.tesla_cooldowns.retain(|t| t.pos != p); player_buildings.occupied &= deconstruct_mask; + }, + Command::IronCurtain => { + debug_assert!(player_buildings.iron_curtain_available); + debug_assert!(player.energy >= IRON_CURTAIN_PRICE); + + player.energy -= IRON_CURTAIN_PRICE; + player_buildings.iron_curtain_available = false; + player_buildings.iron_curtain_remaining = IRON_CURTAIN_DURATION; } } } @@ -295,6 +309,11 @@ impl BitwiseGameState { player_buildings.unconstructed.truncate(buildings_len); } + fn update_iron_curtain(player_buildings: &mut PlayerBuildings) { + //TODO: Get in current round and set available to true + player_buildings.iron_curtain_remaining -= 1; + } + fn fire_teslas(player: &mut Player, player_buildings: &mut PlayerBuildings, opponent: &mut Player, opponent_buildings: &mut PlayerBuildings) { BitwiseGameState::fire_single_players_teslas_without_cleanup(player, player_buildings, opponent, opponent_buildings); BitwiseGameState::fire_single_players_teslas_without_cleanup(opponent, opponent_buildings, player, player_buildings); @@ -309,6 +328,9 @@ impl BitwiseGameState { tesla.age += 1; if tesla.cooldown > 0 { tesla.cooldown -= 1; + } else if player.energy >= TESLA_FIRING_ENERGY && opponent_buildings.iron_curtain_remaining > 0 { + player.energy -= TESLA_FIRING_ENERGY; + tesla.cooldown = TESLA_COOLDOWN; } else if player.energy >= TESLA_FIRING_ENERGY { player.energy -= TESLA_FIRING_ENERGY; tesla.cooldown = TESLA_COOLDOWN; @@ -351,7 +373,7 @@ impl BitwiseGameState { let mut damaging = 0; for _ in 0..MISSILE_SPEED { for missile in player_missiles.iter_mut() { - let swapping_sides = missile.0 & RIGHT_COL_MASK; + let swapping_sides = if opponent_buildings.iron_curtain_remaining > 0 { 0 } else { missile.0 & RIGHT_COL_MASK }; let about_to_hit_opponent = missile.1 & LEFT_COL_MASK; missile.0 = (missile.0 & !RIGHT_COL_MASK) << 1; @@ -426,7 +448,9 @@ impl PlayerBuildings { missile_towers: [0; MISSILE_COOLDOWN_STATES], firing_tower: 0, missiles: [(0,0); MISSILE_MAX_SINGLE_CELL], - tesla_cooldowns: ArrayVec::new() + tesla_cooldowns: ArrayVec::new(), + iron_curtain_available: false, + iron_curtain_remaining: 0 } } diff --git a/src/engine/command.rs b/src/engine/command.rs index da7e1e0..e6dbedf 100644 --- a/src/engine/command.rs +++ b/src/engine/command.rs @@ -5,7 +5,8 @@ use super::geometry::Point; pub enum Command { Nothing, Build(Point, BuildingType), - Deconstruct(Point) + Deconstruct(Point), + IronCurtain } impl fmt::Display for Command { @@ -14,6 +15,7 @@ impl fmt::Display for Command { Command::Nothing => write!(f, ""), Command::Build(p, b) => write!(f, "{},{},{}", p.x(), p.y(), b as u8), Command::Deconstruct(p) => write!(f, "{},{},3", p.x(), p.y()), + Command::IronCurtain => write!(f, "0,0,5") } } } diff --git a/src/engine/constants.rs b/src/engine/constants.rs index 458251f..11afa29 100644 --- a/src/engine/constants.rs +++ b/src/engine/constants.rs @@ -18,7 +18,7 @@ pub const TESLA_MAX: usize = 2; pub const TESLA_COOLDOWN: u8 = 10; pub const TESLA_FIRING_ENERGY: u16 = 100; pub const TESLA_DAMAGE: u8 = 20; -pub const TESLA_PRICE: u16 = 300; +pub const TESLA_PRICE: u16 = 100; pub const TESLA_CONSTRUCTION_TIME: u8 = 10; pub const ENERGY_GENERATED_BASE: u16 = 5; @@ -26,6 +26,10 @@ pub const ENERGY_GENERATED_TOWER: u16 = 3; pub const ENERGY_PRICE: u16 = 20; pub const ENERGY_CONSTRUCTION_TIME: u8 = 1; +pub const IRON_CURTAIN_PRICE: u16 = 100; +pub const IRON_CURTAIN_UNLOCK_INTERVAL: u8 = 30; +pub const IRON_CURTAIN_DURATION: u8 = 6; + pub const DECONSTRUCT_ENERGY: u16 = 5; pub const MAX_CONCURRENT_CONSTRUCTION: usize = 6; //2 teslas, and 3 of anything else, 1 extra because it's push here then update construction times diff --git a/src/input/json.rs b/src/input/json.rs index 4aebcfa..32f98d0 100644 --- a/src/input/json.rs +++ b/src/input/json.rs @@ -31,6 +31,8 @@ struct Player { player_type: char, energy: u16, health: u8, + iron_curtain_available: bool, + active_iron_curtain_lifetime: i16 } #[derive(Deserialize)] @@ -63,10 +65,28 @@ struct MissileState { impl State { fn to_bitwise_engine(&self) -> bitwise_engine::BitwiseGameState { - let player = self.player().to_bitwise_engine(); - let opponent = self.opponent().to_bitwise_engine(); + let json_player = self.player(); + let player = json_player.to_bitwise_engine(); + let json_opponent = self.opponent(); + let opponent = json_opponent.to_bitwise_engine(); let mut player_buildings = bitwise_engine::PlayerBuildings::empty(); let mut opponent_buildings = bitwise_engine::PlayerBuildings::empty(); + + // TODO roll the player into the playerbuildings and remove this duplication + player_buildings.iron_curtain_available = json_player.iron_curtain_available; + player_buildings.iron_curtain_remaining = if json_player.active_iron_curtain_lifetime < 0 { + 0 + } else { + json_player.active_iron_curtain_lifetime as u8 + }; + opponent_buildings.iron_curtain_available = json_opponent.iron_curtain_available; + opponent_buildings.iron_curtain_remaining = if json_opponent.active_iron_curtain_lifetime < 0 { + 0 + } else { + json_opponent.active_iron_curtain_lifetime as u8 + }; + + for row in &self.game_map { for cell in row { let point = engine::geometry::Point::new(cell.x, cell.y); -- cgit v1.2.3