Added new building specifications
authorJustin Worthe <justin@worthe-it.co.za>
Sat, 12 May 2018 13:10:35 +0000 (15:10 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Sat, 12 May 2018 13:10:35 +0000 (15:10 +0200)
src/engine/command.rs
src/engine/mod.rs
src/engine/settings.rs
src/json.rs
src/main.rs
src/strategy/sample.rs

index eab98c1..b5cf528 100644 (file)
@@ -19,7 +19,7 @@ impl fmt::Display for Command {
 #[repr(u8)]
 #[derive(Debug, Clone, Copy)]
 pub enum BuildingType {
-    Defense = 0,
+    Defence = 0,
     Attack = 1,
     Energy = 2,
 }
index be95c03..f05d985 100644 (file)
@@ -2,9 +2,9 @@ pub mod command;
 pub mod geometry;
 pub mod settings;
 
-use self::command::{BuildingType, Command};
+use self::command::Command;
 use self::geometry::Point;
-use self::settings::GameSettings;
+use self::settings::{GameSettings, BuildingSettings};
 
 use std::ops::Fn;
 use std::cmp;
@@ -61,8 +61,8 @@ impl GameState {
         }
         
         let mut state = self.clone();
-        let player_valid = GameState::perform_command(&mut state.player_buildings, player_command, &settings.size);
-        let opponent_valid = GameState::perform_command(&mut state.opponent_buildings, opponent_command, &settings.size);
+        let player_valid = GameState::perform_command(&mut state.player_buildings, settings, player_command, &settings.size);
+        let opponent_valid = GameState::perform_command(&mut state.opponent_buildings, settings, opponent_command, &settings.size);
 
         if !player_valid || !opponent_valid {
             state.status = GameStatus::InvalidMove;
@@ -87,13 +87,13 @@ impl GameState {
         state
     }
 
-    fn perform_command(buildings: &mut Vec<Building>, command: Command, size: &Point) -> bool {
+    fn perform_command(buildings: &mut Vec<Building>, settings: &GameSettings, command: Command, size: &Point) -> bool {
         match command {
             Command::Nothing => { true },
             Command::Build(p, b) => {
                 let occupied = buildings.iter().any(|b| b.pos == p);
                 let in_range = p.x < size.x && p.y < size.y;
-                buildings.push(Building::new(p, b));
+                buildings.push(Building::new(p, settings.building_settings(b)));
                 !occupied && in_range
             },
         }
@@ -194,50 +194,28 @@ impl Player {
     }
 
     pub fn can_afford_attack_buildings(&self, settings: &GameSettings) -> bool {
-        self.energy >= settings.attack_price
+        self.energy >= settings.attack.price
     }
     pub fn can_afford_defence_buildings(&self, settings: &GameSettings) -> bool {
-        self.energy >= settings.defence_price
+        self.energy >= settings.defence.price
     }
     pub fn can_afford_energy_buildings(&self, settings: &GameSettings) -> bool {
-        self.energy >= settings.energy_price
+        self.energy >= settings.energy.price
     }
 
 }
 
 impl Building {
-    fn new(pos: Point, building: BuildingType) -> Building {
-        match building {
-            BuildingType::Defense => Building {
-                pos: pos,
-                health: 20,
-                construction_time_left: 3,
-                weapon_damage: 0,
-                weapon_speed: 0,
-                weapon_cooldown_time_left: 0,
-                weapon_cooldown_period: 0,
-                energy_generated_per_turn: 0
-            },
-            BuildingType::Attack => Building {
-                pos: pos,
-                health: 5,
-                construction_time_left: 1,
-                weapon_damage: 5,
-                weapon_speed: 1,
-                weapon_cooldown_time_left: 0,
-                weapon_cooldown_period: 3,
-                energy_generated_per_turn: 0
-            },
-            BuildingType::Energy => Building {
-                pos: pos,
-                health: 5,
-                construction_time_left: 1,
-                weapon_damage: 0,
-                weapon_speed: 0,
-                weapon_cooldown_time_left: 0,
-                weapon_cooldown_period: 0,
-                energy_generated_per_turn: 3
-            }
+    fn new(pos: Point, blueprint: &BuildingSettings) -> Building {
+        Building {
+            pos: pos,
+            health: blueprint.health,
+            construction_time_left: blueprint.construction_time,
+            weapon_damage: blueprint.weapon_damage,
+            weapon_speed: blueprint.weapon_speed,
+            weapon_cooldown_time_left: 0,
+            weapon_cooldown_period: blueprint.weapon_cooldown_period,
+            energy_generated_per_turn: blueprint.energy_generated_per_turn
         }
     }
 
index a6691d7..b23d6bd 100644 (file)
@@ -1,10 +1,33 @@
 use super::geometry::Point;
+use super::command::BuildingType;
 
 #[derive(Debug)]
 pub struct GameSettings {
     pub size: Point,
     pub energy_income: u16,
-    pub energy_price: u16,
-    pub defence_price: u16,
-    pub attack_price: u16
+    pub energy: BuildingSettings,
+    pub defence: BuildingSettings,
+    pub attack: BuildingSettings
+}
+
+#[derive(Debug)]
+pub struct BuildingSettings {
+    pub price: u16,
+    pub health: u16,
+    pub construction_time: u8,
+    pub weapon_damage: u16,
+    pub weapon_speed: u8,
+    pub weapon_cooldown_period: u8,
+    pub energy_generated_per_turn: u16
+}
+
+impl GameSettings {
+    pub fn building_settings(&self, building: BuildingType) -> &BuildingSettings {
+        match building {
+            BuildingType::Defence => &self.defence,
+            BuildingType::Attack => &self.attack,
+            BuildingType::Energy => &self.energy
+        }
+    }
+    
 }
index 18e13fb..541b479 100644 (file)
@@ -29,15 +29,30 @@ struct GameDetails {
     //round: u32,
     map_width: u8,
     map_height: u8,
-    building_prices: BuildingPrices
+    round_income_energy: u16,
+    building_stats: BuildingStats
 }
 
 #[derive(Deserialize)]
 #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
-struct BuildingPrices {
-    energy: u16,
-    defense: u16,
-    attack: u16
+struct BuildingStats {
+    energy: BuildingBlueprint,
+    defense: BuildingBlueprint,
+    attack: BuildingBlueprint
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct BuildingBlueprint {
+    price: u16,
+    health: u16,
+    construction_time: u8,
+    weapon_damage: u16,
+    weapon_speed: u8,
+    weapon_cooldown_period: u8,
+    energy_generated_per_turn: u16,
+//    destroy_multiplier: u16,
+//    construction_score: u16
 }
 
 #[derive(Deserialize)]
@@ -94,10 +109,10 @@ impl State {
     fn to_engine_settings(&self) -> engine::settings::GameSettings {
         engine::settings::GameSettings {
             size: engine::geometry::Point::new(self.game_details.map_width, self.game_details.map_height),
-            energy_income: 5,
-            energy_price: self.game_details.building_prices.energy,
-            defence_price: self.game_details.building_prices.defense,
-            attack_price: self.game_details.building_prices.attack,
+            energy_income: self.game_details.round_income_energy,
+            energy: self.game_details.building_stats.energy.to_engine(),
+            defence: self.game_details.building_stats.defense.to_engine(),
+            attack: self.game_details.building_stats.attack.to_engine(),
         }
     }
     
@@ -150,6 +165,20 @@ impl State {
     }
 }
 
+impl BuildingBlueprint {
+    fn to_engine(&self) -> engine::settings::BuildingSettings {
+        engine::settings::BuildingSettings {
+            price: self.price,
+            health: self.health,
+            construction_time: self.construction_time,
+            weapon_damage: self.weapon_damage,
+            weapon_speed: self.weapon_speed,
+            weapon_cooldown_period: self.weapon_cooldown_period,
+            energy_generated_per_turn: self.energy_generated_per_turn,
+        }
+    }
+}
+
 impl Player {
     fn to_engine(&self) -> engine::Player {
         engine::Player {
index 22f698d..7b3a62c 100644 (file)
@@ -28,6 +28,7 @@ fn main() {
     let (settings, state) = match json::read_state_from_file(STATE_PATH) {
         Ok(ok) => ok,
         Err(error) => {
+            eprintln!("Error while parsing JSON file: {}", error);
             process::exit(1);
         }
     };
@@ -36,6 +37,7 @@ fn main() {
     match write_command(COMMAND_PATH, command) {
         Ok(()) => {}
         Err(error) => {
+            eprintln!("Error while writing command file: {}", error);
             process::exit(1);
         }
     }
index bd23916..3a311e0 100644 (file)
@@ -8,7 +8,7 @@ pub fn choose_move(settings: &engine::settings::GameSettings, state: &engine::Ga
             if is_under_attack(state, y) {
                 let p_options = state.unoccupied_player_cells_in_row(settings, y);
                 if let Some(&p) = p_options.first() {
-                    return Command::Build(p, BuildingType::Defense);
+                    return Command::Build(p, BuildingType::Defence);
                 }
             }
         }
@@ -17,7 +17,7 @@ pub fn choose_move(settings: &engine::settings::GameSettings, state: &engine::Ga
     if state.player.can_afford_all_buildings(settings) {
         let options = state.unoccupied_player_cells(settings);
         let option = options.first();
-        let buildings = [BuildingType::Attack, BuildingType::Defense, BuildingType::Energy];
+        let buildings = [BuildingType::Attack, BuildingType::Defence, BuildingType::Energy];
         let building = buildings.first();
         match (option, building) {
             (Some(&p), Some(&building)) => Command::Build(p, building),