Started moving constants to a constants file
authorJustin Worthe <justin@worthe-it.co.za>
Sun, 8 Jul 2018 11:23:18 +0000 (13:23 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Sun, 8 Jul 2018 11:23:18 +0000 (13:23 +0200)
src/engine/bitwise_engine.rs
src/engine/constants.rs [new file with mode: 0644]
src/engine/geometry.rs
src/engine/mod.rs
src/input/json.rs
tests/expressive_to_bitwise_comparison.rs

index c9bae0f..486f2f5 100644 (file)
@@ -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 (file)
index 0000000..5e1b9f3
--- /dev/null
@@ -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;
index af91b19..293ffce 100644 (file)
@@ -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
         }
     }
index d36d0e9..a444059 100644 (file)
@@ -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;
index 6f0d5e8..c032f48 100644 (file)
@@ -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);
index 95f867e..bdc4a19 100644 (file)
@@ -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);