From 088f0aeb23789ace5e9b77e75d5c23f5442e4cdc Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sat, 9 Jun 2018 10:27:29 +0200 Subject: Added pruning of buying energy buildings behind a feature flag --- src/engine/mod.rs | 59 +++++++++++++++++++++------------------------ src/strategy/mod.rs | 1 - src/strategy/monte_carlo.rs | 6 ++--- src/strategy/sample.rs | 40 ------------------------------ 4 files changed, 31 insertions(+), 75 deletions(-) delete mode 100644 src/strategy/sample.rs (limited to 'src') diff --git a/src/engine/mod.rs b/src/engine/mod.rs index a649453..28583a1 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -8,6 +8,9 @@ use self::settings::{GameSettings, BuildingSettings}; use std::ops::FnMut; +#[cfg(feature = "energy-cutoff")] pub const ENERGY_PRODUCTION_CUTOFF: f32 = 2.; +#[cfg(feature = "energy-cutoff")] pub const ENERGY_STORAGE_CUTOFF: u16 = 10; + #[derive(Debug, Clone, PartialEq)] pub struct GameState { pub status: GameStatus, @@ -259,24 +262,6 @@ impl GameState { } result } - - pub fn player_affordable_buildings(&self, settings: &GameSettings) -> Vec { - GameState::affordable_buildings(self.player.energy, settings) - } - - pub fn opponent_affordable_buildings(&self, settings: &GameSettings) -> Vec { - GameState::affordable_buildings(self.opponent.energy, settings) - } - - fn affordable_buildings(energy: u16, settings: &GameSettings) -> Vec { - let mut result = Vec::with_capacity(3); - for b in BuildingType::all().iter() { - if settings.building_settings(*b).price <= energy { - result.push(*b); - } - } - result - } } impl GameStatus { @@ -293,21 +278,33 @@ impl Player { energy_generated: settings.energy_income + buildings.iter().map(|b| b.energy_generated_per_turn).sum::() } } - - pub fn can_afford_all_buildings(&self, settings: &GameSettings) -> bool { - self.can_afford_attack_buildings(settings) && - self.can_afford_defence_buildings(settings) && - self.can_afford_energy_buildings(settings) - } - pub fn can_afford_attack_buildings(&self, settings: &GameSettings) -> bool { - self.energy >= settings.attack.price - } - pub fn can_afford_defence_buildings(&self, settings: &GameSettings) -> bool { - self.energy >= settings.defence.price + #[cfg(not(feature = "energy-cutoff"))] + pub fn sensible_buildings(&self, settings: &GameSettings) -> Vec { + let mut result = Vec::with_capacity(3); + for b in BuildingType::all().iter() { + if settings.building_settings(*b).price <= self.energy { + result.push(*b); + } + } + result } - pub fn can_afford_energy_buildings(&self, settings: &GameSettings) -> bool { - self.energy >= settings.energy.price + + #[cfg(feature = "energy-cutoff")] + pub fn sensible_buildings(&self, settings: &GameSettings) -> Vec { + let mut result = Vec::with_capacity(3); + let needs_energy = self.energy_generated as f32 >= ENERGY_PRODUCTION_CUTOFF * settings.max_building_price as f32 && + self.energy >= ENERGY_STORAGE_CUTOFF * settings.max_building_price; + + for b in BuildingType::all().iter() { + let building_setting = settings.building_settings(*b); + let affordable = building_setting.price <= self.energy; + let energy_producing = building_setting.energy_generated_per_turn > 0; + if affordable && (!energy_producing || needs_energy) { + result.push(*b); + } + } + result } } diff --git a/src/strategy/mod.rs b/src/strategy/mod.rs index 9630c48..5b6e779 100644 --- a/src/strategy/mod.rs +++ b/src/strategy/mod.rs @@ -1,2 +1 @@ -pub mod sample; pub mod monte_carlo; diff --git a/src/strategy/monte_carlo.rs b/src/strategy/monte_carlo.rs index c2f3561..0d813d3 100644 --- a/src/strategy/monte_carlo.rs +++ b/src/strategy/monte_carlo.rs @@ -75,12 +75,12 @@ fn simulate_to_endstate(command_score: &mut CommandScore, settings: &Gam } fn random_player_move(settings: &GameSettings, state: &GameState, rng: &mut R) -> Command { - let all_buildings = state.player_affordable_buildings(settings); + let all_buildings = state.player.sensible_buildings(settings); random_move(&state.unoccupied_player_cells, &all_buildings, rng) } fn random_opponent_move(settings: &GameSettings, state: &GameState, rng: &mut R) -> Command { - let all_buildings = state.opponent_affordable_buildings(settings); + let all_buildings = state.opponent.sensible_buildings(settings); random_move(&state.unoccupied_opponent_cells, &all_buildings, rng) } @@ -151,7 +151,7 @@ impl CommandScore { } fn init_command_scores(settings: &GameSettings, state: &GameState) -> Vec { - let all_buildings = state.player_affordable_buildings(settings); + let all_buildings = state.player.sensible_buildings(settings); let mut commands = Vec::with_capacity(state.unoccupied_player_cells.len()*all_buildings.len()+1); commands.push(CommandScore::new(Command::Nothing)); diff --git a/src/strategy/sample.rs b/src/strategy/sample.rs deleted file mode 100644 index 370df2f..0000000 --- a/src/strategy/sample.rs +++ /dev/null @@ -1,40 +0,0 @@ -use engine; -use engine::command::*; - -use rand::{thread_rng, Rng}; - -pub fn choose_move(settings: &engine::settings::GameSettings, state: &engine::GameState) -> Command { - let mut rng = thread_rng(); - - if state.player.can_afford_defence_buildings(settings) { - for y in 0..settings.size.y { - if is_under_attack(state, y) { - let p_options = state.unoccupied_player_cells_in_row(y); - if let Some(&p) = rng.choose(&p_options) { - return Command::Build(p, BuildingType::Defence); - } - } - } - } - - if state.player.can_afford_all_buildings(settings) { - let option = rng.choose(&state.unoccupied_player_cells); - let buildings = [BuildingType::Attack, BuildingType::Defence, BuildingType::Energy]; - let building = rng.choose(&buildings); - match (option, building) { - (Some(&p), Some(&building)) => Command::Build(p, building), - _ => Command::Nothing - } - } - else { - Command::Nothing - } -} - -fn is_under_attack(state: &engine::GameState, y: u8) -> bool { - let attack = state.opponent_buildings.iter() - .any(|b| b.pos.y == y && b.weapon_damage > 0); - let defences = state.player_buildings.iter() - .any(|b| b.pos.y == y && b.health > 5); - attack && !defences -} -- cgit v1.2.3