diff options
-rw-r--r-- | src/engine/command.rs | 2 | ||||
-rw-r--r-- | src/engine/mod.rs | 60 | ||||
-rw-r--r-- | src/engine/settings.rs | 29 | ||||
-rw-r--r-- | src/json.rs | 47 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/strategy/sample.rs | 4 |
6 files changed, 88 insertions, 56 deletions
diff --git a/src/engine/command.rs b/src/engine/command.rs index eab98c1..b5cf528 100644 --- a/src/engine/command.rs +++ b/src/engine/command.rs @@ -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, } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index be95c03..f05d985 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -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 } } diff --git a/src/engine/settings.rs b/src/engine/settings.rs index a6691d7..b23d6bd 100644 --- a/src/engine/settings.rs +++ b/src/engine/settings.rs @@ -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 + } + } + } diff --git a/src/json.rs b/src/json.rs index 18e13fb..541b479 100644 --- a/src/json.rs +++ b/src/json.rs @@ -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 { diff --git a/src/main.rs b/src/main.rs index 22f698d..7b3a62c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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); } } diff --git a/src/strategy/sample.rs b/src/strategy/sample.rs index bd23916..3a311e0 100644 --- a/src/strategy/sample.rs +++ b/src/strategy/sample.rs @@ -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), |