From 8263d02a433c87fbfa246cdc80aa26a4dadb78f2 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sun, 8 Jul 2018 13:23:18 +0200 Subject: Started moving constants to a constants file --- src/engine/bitwise_engine.rs | 41 ++++++++++++------------------- src/engine/constants.rs | 10 ++++++++ src/engine/geometry.rs | 30 +++++++++++----------- src/engine/mod.rs | 1 + src/input/json.rs | 6 ++--- tests/expressive_to_bitwise_comparison.rs | 24 +++++++++--------- 6 files changed, 58 insertions(+), 54 deletions(-) create mode 100644 src/engine/constants.rs diff --git a/src/engine/bitwise_engine.rs b/src/engine/bitwise_engine.rs index c9bae0f..486f2f5 100644 --- a/src/engine/bitwise_engine.rs +++ b/src/engine/bitwise_engine.rs @@ -1,18 +1,9 @@ use engine::command::{Command, BuildingType}; use engine::geometry::Point; use engine::settings::{GameSettings}; +use engine::constants::*; use engine::{GameStatus, Player, GameState}; -const FULL_MAP_WIDTH: u8 = 16; -const SINGLE_MAP_WIDTH: u8 = FULL_MAP_WIDTH/2; -const MAX_CONCURRENT_MISSILES: usize = SINGLE_MAP_WIDTH as usize / 2; - -const MISSILE_COOLDOWN: usize = 3; - -const DEFENCE_HEALTH: usize = 4; // '20' health is 4 hits - -const MAX_TESLAS: usize = 2; - const LEFT_COL_MASK: u64 = 0x0101010101010101; const RIGHT_COL_MASK: u64 = 0x8080808080808080; @@ -34,7 +25,7 @@ pub struct PlayerBuildings { pub energy_towers: u64, pub missile_towers: [u64; MISSILE_COOLDOWN+1], - pub missiles: [(u64, u64); MAX_CONCURRENT_MISSILES], + pub missiles: [(u64, u64); MISSILE_MAX_SINGLE_CELL], pub tesla_cooldowns: [TeslaCooldown; MAX_TESLAS] } @@ -86,13 +77,13 @@ impl GameState for BitwiseGameState { fn location_of_unoccupied_player_cell(&self, i: usize) -> Point { let bit = find_bit_index_from_rank(self.player_buildings.occupied, i as u64); let point = Point::new(bit%SINGLE_MAP_WIDTH, bit/SINGLE_MAP_WIDTH); - debug_assert!(point.to_either_bitfield(SINGLE_MAP_WIDTH) & self.player_buildings.occupied == 0); + debug_assert!(point.to_either_bitfield() & self.player_buildings.occupied == 0); point } fn location_of_unoccupied_opponent_cell(&self, i: usize) -> Point { let bit = find_bit_index_from_rank(self.opponent_buildings.occupied, i as u64); let point = Point::new(bit%SINGLE_MAP_WIDTH+SINGLE_MAP_WIDTH, bit/SINGLE_MAP_WIDTH); - debug_assert!(point.to_either_bitfield(SINGLE_MAP_WIDTH) & self.opponent_buildings.occupied == 0); + debug_assert!(point.to_either_bitfield() & self.opponent_buildings.occupied == 0); point } } @@ -145,8 +136,8 @@ impl BitwiseGameState { * engine. */ pub fn sort(&mut self) { - for i in 0..MAX_CONCURRENT_MISSILES { - for j in i+1..MAX_CONCURRENT_MISSILES { + for i in 0..MISSILE_MAX_SINGLE_CELL { + for j in i+1..MISSILE_MAX_SINGLE_CELL { let move_down1 = !self.player_buildings.missiles[i].0 & self.player_buildings.missiles[j].0; self.player_buildings.missiles[i].0 |= move_down1; self.player_buildings.missiles[j].0 &= !move_down1; @@ -196,7 +187,7 @@ impl BitwiseGameState { Command::Nothing => {}, Command::Build(p, b) => { let blueprint = settings.building_settings(b); - let bitfield = p.to_either_bitfield(SINGLE_MAP_WIDTH); + let bitfield = p.to_either_bitfield(); // This is used internally. I should not be making // invalid moves! @@ -216,7 +207,7 @@ impl BitwiseGameState { }, Command::Deconstruct(p) => { let unconstructed_to_remove_index = player_buildings.unconstructed.iter().position(|ref b| b.pos == p); - let deconstruct_mask = !(p.to_either_bitfield(SINGLE_MAP_WIDTH) & player_buildings.buildings[0]); + let deconstruct_mask = !(p.to_either_bitfield() & player_buildings.buildings[0]); debug_assert!(deconstruct_mask != 0 || unconstructed_to_remove_index.is_some()); @@ -250,7 +241,7 @@ impl BitwiseGameState { let building_type = player_buildings.unconstructed[i].building_type; let blueprint = settings.building_settings(building_type); let pos = player_buildings.unconstructed[i].pos; - let bitfield = pos.to_either_bitfield(SINGLE_MAP_WIDTH); + let bitfield = pos.to_either_bitfield(); for health_tier in 0..4 { if blueprint.health > health_tier*5 { @@ -372,9 +363,9 @@ impl BitwiseGameState { } - fn move_left_and_collide_missiles(settings: &GameSettings, opponent: &mut Player, opponent_buildings: &mut PlayerBuildings, player_missiles: &mut [(u64, u64); MAX_CONCURRENT_MISSILES]) { - for _ in 0..settings.attack.weapon_speed { - for i in 0..player_missiles.len() { + fn move_left_and_collide_missiles(settings: &GameSettings, opponent: &mut Player, opponent_buildings: &mut PlayerBuildings, player_missiles: &mut [(u64, u64); MISSILE_MAX_SINGLE_CELL]) { + for _ in 0..MISSILE_SPEED { + for i in 0..MISSILE_MAX_SINGLE_CELL { let about_to_hit_opponent = player_missiles[i].0 & LEFT_COL_MASK; let damage = about_to_hit_opponent.count_ones() as u8 * settings.attack.weapon_damage; opponent.health = opponent.health.saturating_sub(damage); @@ -398,9 +389,9 @@ impl BitwiseGameState { } } - fn move_right_and_collide_missiles(settings: &GameSettings, opponent: &mut Player, opponent_buildings: &mut PlayerBuildings, player_missiles: &mut [(u64, u64); MAX_CONCURRENT_MISSILES]) { - for _ in 0..settings.attack.weapon_speed { - for i in 0..player_missiles.len() { + fn move_right_and_collide_missiles(settings: &GameSettings, opponent: &mut Player, opponent_buildings: &mut PlayerBuildings, player_missiles: &mut [(u64, u64); MISSILE_MAX_SINGLE_CELL]) { + for _ in 0..MISSILE_SPEED { + for i in 0..MISSILE_MAX_SINGLE_CELL { let about_to_hit_opponent = player_missiles[i].1 & RIGHT_COL_MASK; let damage = about_to_hit_opponent.count_ones() as u8 * settings.attack.weapon_damage; opponent.health = opponent.health.saturating_sub(damage); @@ -439,7 +430,7 @@ impl BitwiseGameState { fn update_tesla_activity(buildings: &mut PlayerBuildings) { for tesla in buildings.tesla_cooldowns.iter_mut().filter(|t| t.active) { - tesla.active = (tesla.pos.to_either_bitfield(SINGLE_MAP_WIDTH) & buildings.occupied) != 0; + tesla.active = (tesla.pos.to_either_bitfield() & buildings.occupied) != 0; } } diff --git a/src/engine/constants.rs b/src/engine/constants.rs new file mode 100644 index 0000000..5e1b9f3 --- /dev/null +++ b/src/engine/constants.rs @@ -0,0 +1,10 @@ +pub const FULL_MAP_WIDTH: u8 = 16; +pub const SINGLE_MAP_WIDTH: u8 = FULL_MAP_WIDTH/2; + +pub const MISSILE_COOLDOWN: usize = 3; +pub const MISSILE_SPEED: usize = 2; +pub const MISSILE_MAX_SINGLE_CELL: usize = SINGLE_MAP_WIDTH as usize / MISSILE_SPEED; + +pub const DEFENCE_HEALTH: usize = 4; // '20' health is 4 hits + +pub const MAX_TESLAS: usize = 2; diff --git a/src/engine/geometry.rs b/src/engine/geometry.rs index af91b19..293ffce 100644 --- a/src/engine/geometry.rs +++ b/src/engine/geometry.rs @@ -1,3 +1,5 @@ +use engine::constants::*; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Point { pub x: u8, @@ -32,40 +34,40 @@ impl Point { self.x = self.x.wrapping_add(1); } - pub fn to_bitfield(&self, width: u8) -> (u64, u64) { - if self.x >= width { - let index = self.y * width + self.x - width; + pub fn to_bitfield(&self) -> (u64, u64) { + if self.x >= SINGLE_MAP_WIDTH { + let index = self.y * SINGLE_MAP_WIDTH + self.x - SINGLE_MAP_WIDTH; (0, 1 << index) } else { - let index = self.y * width + self.x; + let index = self.y * SINGLE_MAP_WIDTH + self.x; (1 << index, 0) } } - pub fn to_left_bitfield(&self, width: u8) -> u64 { - if self.x >= width { + pub fn to_left_bitfield(&self) -> u64 { + if self.x >= SINGLE_MAP_WIDTH { 0 } else { - let index = self.y * width + self.x; + let index = self.y * SINGLE_MAP_WIDTH + self.x; 1 << index } } - pub fn to_right_bitfield(&self, width: u8) -> u64 { - if self.x < width { + pub fn to_right_bitfield(&self) -> u64 { + if self.x < SINGLE_MAP_WIDTH { 0 } else { - let index = self.y * width + self.x - width; + let index = self.y * SINGLE_MAP_WIDTH + self.x - SINGLE_MAP_WIDTH; 1 << index } } - pub fn to_either_bitfield(&self, width: u8) -> u64 { - if self.x >= width { - let index = self.y * width + self.x - width; + pub fn to_either_bitfield(&self) -> u64 { + if self.x >= SINGLE_MAP_WIDTH { + let index = self.y * SINGLE_MAP_WIDTH + self.x - SINGLE_MAP_WIDTH; 1 << index } else { - let index = self.y * width + self.x; + let index = self.y * SINGLE_MAP_WIDTH + self.x; 1 << index } } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index d36d0e9..a444059 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -3,6 +3,7 @@ pub mod geometry; pub mod settings; pub mod expressive_engine; pub mod bitwise_engine; +pub mod constants; use self::command::{Command}; use self::geometry::Point; diff --git a/src/input/json.rs b/src/input/json.rs index 6f0d5e8..c032f48 100644 --- a/src/input/json.rs +++ b/src/input/json.rs @@ -162,9 +162,9 @@ impl State { let building_type = building.convert_building_type(); let (mut engine_player, mut bitwise_buildings, bitfield) = if building.player_type == 'A' { - (&mut player, &mut player_buildings, point.to_left_bitfield(8)) + (&mut player, &mut player_buildings, point.to_left_bitfield()) } else { - (&mut opponent, &mut opponent_buildings, point.to_right_bitfield(8)) + (&mut opponent, &mut opponent_buildings, point.to_right_bitfield()) }; bitwise_buildings.occupied |= bitfield; @@ -205,7 +205,7 @@ impl State { } else { &mut opponent_buildings }; - let (mut left, mut right) = point.to_bitfield(8); + let (mut left, mut right) = point.to_bitfield(); for mut tier in bitwise_buildings.missiles.iter_mut() { let setting = (!tier.0 & left, !tier.1 & right); diff --git a/tests/expressive_to_bitwise_comparison.rs b/tests/expressive_to_bitwise_comparison.rs index 95f867e..bdc4a19 100644 --- a/tests/expressive_to_bitwise_comparison.rs +++ b/tests/expressive_to_bitwise_comparison.rs @@ -118,48 +118,48 @@ fn build_bitwise_from_expressive(expressive: &expressive_engine::ExpressiveGameS let player_energy = expressive.player_buildings.iter() .filter(|b| identify_building_type(b.weapon_damage, b.energy_generated_per_turn) == BuildingType::Energy) - .fold(0, |acc, next| acc | next.pos.to_left_bitfield(8)); + .fold(0, |acc, next| acc | next.pos.to_left_bitfield()); let opponent_energy = expressive.opponent_buildings.iter() .filter(|b| identify_building_type(b.weapon_damage, b.energy_generated_per_turn) == BuildingType::Energy) - .fold(0, |acc, next| acc | next.pos.to_right_bitfield(8)); + .fold(0, |acc, next| acc | next.pos.to_right_bitfield()); let mut player_buildings_iter = (0..4) .map(|i| expressive.player_buildings.iter() .filter(|b| b.health > i*5) - .fold(0, |acc, next| acc | next.pos.to_left_bitfield(8)) + .fold(0, |acc, next| acc | next.pos.to_left_bitfield()) ); let mut opponent_buildings_iter = (0..4) .map(|i| expressive.opponent_buildings.iter() .filter(|b| b.health > i*5) - .fold(0, |acc, next| acc | next.pos.to_right_bitfield(8)) + .fold(0, |acc, next| acc | next.pos.to_right_bitfield()) ); let player_occupied = expressive.player_buildings.iter() - .fold(0, |acc, next| acc | next.pos.to_left_bitfield(8)) | + .fold(0, |acc, next| acc | next.pos.to_left_bitfield()) | expressive.player_unconstructed_buildings.iter() - .fold(0, |acc, next| acc | next.pos.to_left_bitfield(8)); + .fold(0, |acc, next| acc | next.pos.to_left_bitfield()); let opponent_occupied = expressive.opponent_buildings.iter() - .fold(0, |acc, next| acc | next.pos.to_right_bitfield(8)) | + .fold(0, |acc, next| acc | next.pos.to_right_bitfield()) | expressive.opponent_unconstructed_buildings.iter() - .fold(0, |acc, next| acc | next.pos.to_right_bitfield(8)); + .fold(0, |acc, next| acc | next.pos.to_right_bitfield()); let mut player_attack_iter = (0..4) .map(|i| expressive.player_buildings.iter() .filter(|b| identify_building_type(b.weapon_damage, b.energy_generated_per_turn) == BuildingType::Attack) .filter(|b| b.weapon_cooldown_time_left == i) - .fold(0, |acc, next| acc | next.pos.to_left_bitfield(8)) + .fold(0, |acc, next| acc | next.pos.to_left_bitfield()) ); let mut opponent_attack_iter = (0..4) .map(|i| expressive.opponent_buildings.iter() .filter(|b| identify_building_type(b.weapon_damage, b.energy_generated_per_turn) == BuildingType::Attack) .filter(|b| b.weapon_cooldown_time_left == i) - .fold(0, |acc, next| acc | next.pos.to_right_bitfield(8)) + .fold(0, |acc, next| acc | next.pos.to_right_bitfield()) ); let empty_missiles: [(u64,u64);4] = [(0,0),(0,0),(0,0),(0,0)]; let player_missiles = expressive.player_missiles.iter() .fold(empty_missiles, |acc, m| { - let (mut left, mut right) = m.pos.to_bitfield(8); + let (mut left, mut right) = m.pos.to_bitfield(); let mut res = acc.clone(); for mut tier in res.iter_mut() { let setting = (!tier.0 & left, !tier.1 & right); @@ -172,7 +172,7 @@ fn build_bitwise_from_expressive(expressive: &expressive_engine::ExpressiveGameS }); let opponent_missiles = expressive.opponent_missiles.iter() .fold(empty_missiles, |acc, m| { - let (mut left, mut right) = m.pos.to_bitfield(8); + let (mut left, mut right) = m.pos.to_bitfield(); let mut res = acc.clone(); for mut tier in res.iter_mut() { let setting = (!tier.0 & left, !tier.1 & right); -- cgit v1.2.3