diff --git a/src/ai/contexts.cpp b/src/ai/contexts.cpp index e7118a881833..17e387213df7 100644 --- a/src/ai/contexts.cpp +++ b/src/ai/contexts.cpp @@ -21,45 +21,43 @@ #include "ai/contexts.hpp" #include "actions/attack.hpp" - -#include "ai/actions.hpp" // for actions -#include "ai/composite/aspect.hpp" // for typesafe_aspect, aspect, etc -#include "ai/composite/engine.hpp" // for engine, engine_factory, etc -#include "ai/composite/goal.hpp" // for goal -#include "ai/composite/stage.hpp" // for ministage -#include "ai/game_info.hpp" // for typesafe_aspect_ptr, etc +#include "ai/actions.hpp" // for actions +#include "ai/composite/aspect.hpp" // for typesafe_aspect, aspect, etc +#include "ai/composite/engine.hpp" // for engine, engine_factory, etc +#include "ai/composite/goal.hpp" // for goal +#include "ai/composite/stage.hpp" // for ministage +#include "ai/game_info.hpp" // for typesafe_aspect_ptr, etc #include "ai/lua/aspect_advancements.hpp" -#include "ai/manager.hpp" // for manager - -#include "chat_events.hpp" // for chat_handler, etc -#include "config.hpp" // for config, etc +#include "ai/manager.hpp" // for manager +#include "chat_events.hpp" // for chat_handler, etc +#include "config.hpp" // for config, etc #include "display_chat_manager.hpp" -#include "game_board.hpp" // for game_board -#include "game_config.hpp" // for debug -#include "game_display.hpp" // for game_display -#include "log.hpp" // for LOG_STREAM, logger, etc -#include "map/map.hpp" // for gamemap -#include "pathfind/pathfind.hpp" // for paths::dest_vect, paths, etc -#include "recall_list_manager.hpp" // for recall_list_manager -#include "resources.hpp" // for units, gameboard, etc -#include "serialization/string_utils.hpp" // for split, etc -#include "team.hpp" // for team -#include "terrain/filter.hpp" // for terrain_filter -#include "terrain/translation.hpp" // for terrain_code -#include "time_of_day.hpp" // for time_of_day -#include "tod_manager.hpp" // for tod_manager -#include "units/unit.hpp" // for unit -#include "units/map.hpp" // for unit_map::iterator_base, etc -#include "units/ptr.hpp" // for unit_ptr -#include "units/types.hpp" // for attack_type, unit_type, etc -#include "formula/variant.hpp" // for variant - -#include // for find, count, max, fill_n -#include // for sqrt -#include // for abs -#include // for time -#include // for back_inserter -#include // for operator<<, basic_ostream, etc +#include "formula/variant.hpp" // for variant +#include "game_board.hpp" // for game_board +#include "game_config.hpp" // for debug +#include "game_display.hpp" // for game_display +#include "log.hpp" // for LOG_STREAM, logger, etc +#include "map/map.hpp" // for gamemap +#include "pathfind/pathfind.hpp" // for paths::dest_vect, paths, etc +#include "recall_list_manager.hpp" // for recall_list_manager +#include "resources.hpp" // for units, gameboard, etc +#include "serialization/string_utils.hpp" // for split, etc +#include "team.hpp" // for team +#include "terrain/filter.hpp" // for terrain_filter +#include "terrain/translation.hpp" // for terrain_code +#include "time_of_day.hpp" // for time_of_day +#include "tod_manager.hpp" // for tod_manager +#include "units/map.hpp" // for unit_map::iterator_base, etc +#include "units/ptr.hpp" // for unit_ptr +#include "units/types.hpp" // for attack_type, unit_type, etc +#include "units/unit.hpp" // for unit + +#include // for find, count, max, fill_n +#include // for sqrt +#include // for abs +#include // for time +#include // for back_inserter +#include // for operator<<, basic_ostream, etc static lg::log_domain log_ai("ai/general"); #define DBG_AI LOG_STREAM(debug, log_ai) @@ -70,213 +68,225 @@ static lg::log_domain log_ai("ai/general"); // ======================================================================= // // ======================================================================= -namespace ai { - +namespace ai +{ int side_context_impl::get_recursion_count() const { return recursion_counter_.get_count(); } - int readonly_context_impl::get_recursion_count() const { return recursion_counter_.get_count(); } - int readwrite_context_impl::get_recursion_count() const { return recursion_counter_.get_count(); } - void readonly_context_impl::raise_user_interact() const { manager::get_singleton().raise_user_interact(); } - void readwrite_context_impl::raise_gamestate_changed() const { manager::get_singleton().raise_gamestate_changed(); } - team& readwrite_context_impl::current_team_w() { return resources::gameboard->get_team(get_side()); } -attack_result_ptr readwrite_context_impl::execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){ +attack_result_ptr readwrite_context_impl::execute_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) +{ unit_map::iterator i = resources::gameboard->units().find(attacker_loc); double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression(); const unit_advancements_aspect& m_advancements = get_advancements(); - return actions::execute_attack_action(get_side(),true,attacker_loc,defender_loc,attacker_weapon, m_aggression, m_advancements); -} + return actions::execute_attack_action( + get_side(), true, attacker_loc, defender_loc, attacker_weapon, m_aggression, m_advancements); +} -attack_result_ptr readonly_context_impl::check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){ +attack_result_ptr readonly_context_impl::check_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) +{ unit_map::iterator i = resources::gameboard->units().find(attacker_loc); double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression(); const unit_advancements_aspect& m_advancements = get_advancements(); - return actions::execute_attack_action(get_side(),false,attacker_loc,defender_loc,attacker_weapon, m_aggression, m_advancements); -} - -move_result_ptr readwrite_context_impl::execute_move_action(const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok){ - return actions::execute_move_action(get_side(),true,from,to,remove_movement,unreach_is_ok); + return actions::execute_attack_action( + get_side(), false, attacker_loc, defender_loc, attacker_weapon, m_aggression, m_advancements); } - -move_result_ptr readonly_context_impl::check_move_action(const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok){ - return actions::execute_move_action(get_side(),false,from,to,remove_movement,unreach_is_ok); +move_result_ptr readwrite_context_impl::execute_move_action( + const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok) +{ + return actions::execute_move_action(get_side(), true, from, to, remove_movement, unreach_is_ok); } - -recall_result_ptr readwrite_context_impl::execute_recall_action(const std::string& id, const map_location &where, const map_location &from){ - return actions::execute_recall_action(get_side(),true,id,where,from); +move_result_ptr readonly_context_impl::check_move_action( + const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok) +{ + return actions::execute_move_action(get_side(), false, from, to, remove_movement, unreach_is_ok); } - -recruit_result_ptr readwrite_context_impl::execute_recruit_action(const std::string& unit_name, const map_location &where, const map_location &from){ - return actions::execute_recruit_action(get_side(),true,unit_name,where,from); +recall_result_ptr readwrite_context_impl::execute_recall_action( + const std::string& id, const map_location& where, const map_location& from) +{ + return actions::execute_recall_action(get_side(), true, id, where, from); } - -recall_result_ptr readonly_context_impl::check_recall_action(const std::string& id, const map_location &where, const map_location &from){ - return actions::execute_recall_action(get_side(),false,id,where,from); +recruit_result_ptr readwrite_context_impl::execute_recruit_action( + const std::string& unit_name, const map_location& where, const map_location& from) +{ + return actions::execute_recruit_action(get_side(), true, unit_name, where, from); } - -recruit_result_ptr readonly_context_impl::check_recruit_action(const std::string& unit_name, const map_location &where, const map_location &from){ - return actions::execute_recruit_action(get_side(),false,unit_name,where,from); +recall_result_ptr readonly_context_impl::check_recall_action( + const std::string& id, const map_location& where, const map_location& from) +{ + return actions::execute_recall_action(get_side(), false, id, where, from); } - -stopunit_result_ptr readwrite_context_impl::execute_stopunit_action(const map_location& unit_location, bool remove_movement, bool remove_attacks){ - return actions::execute_stopunit_action(get_side(),true,unit_location,remove_movement,remove_attacks); +recruit_result_ptr readonly_context_impl::check_recruit_action( + const std::string& unit_name, const map_location& where, const map_location& from) +{ + return actions::execute_recruit_action(get_side(), false, unit_name, where, from); } - -stopunit_result_ptr readonly_context_impl::check_stopunit_action(const map_location& unit_location, bool remove_movement, bool remove_attacks){ - return actions::execute_stopunit_action(get_side(),false,unit_location,remove_movement,remove_attacks); +stopunit_result_ptr readwrite_context_impl::execute_stopunit_action( + const map_location& unit_location, bool remove_movement, bool remove_attacks) +{ + return actions::execute_stopunit_action(get_side(), true, unit_location, remove_movement, remove_attacks); } - -synced_command_result_ptr readwrite_context_impl::execute_synced_command_action(const std::string& lua_code, const map_location& location){ - return actions::execute_synced_command_action(get_side(),true,lua_code,location); +stopunit_result_ptr readonly_context_impl::check_stopunit_action( + const map_location& unit_location, bool remove_movement, bool remove_attacks) +{ + return actions::execute_stopunit_action(get_side(), false, unit_location, remove_movement, remove_attacks); } - -synced_command_result_ptr readonly_context_impl::check_synced_command_action(const std::string& lua_code, const map_location& location){ - return actions::execute_synced_command_action(get_side(),false,lua_code,location); +synced_command_result_ptr readwrite_context_impl::execute_synced_command_action( + const std::string& lua_code, const map_location& location) +{ + return actions::execute_synced_command_action(get_side(), true, lua_code, location); } +synced_command_result_ptr readonly_context_impl::check_synced_command_action( + const std::string& lua_code, const map_location& location) +{ + return actions::execute_synced_command_action(get_side(), false, lua_code, location); +} template -void readonly_context_impl::add_known_aspect(const std::string &name, typesafe_aspect_ptr& where) -{ - std::shared_ptr< typesafe_known_aspect > ka_ptr(new typesafe_known_aspect(name,where,aspects_)); - known_aspects_.emplace(name,ka_ptr); -} - -readonly_context_impl::readonly_context_impl(side_context &context, const config &cfg) - : cfg_(cfg), - engines_(), - known_aspects_(), - advancements_(), - aggression_(), - attack_depth_(), - aspects_(), - attacks_(), - avoid_(), - caution_(), - defensive_position_cache_(), - dstsrc_(),enemy_dstsrc_(), - enemy_possible_moves_(), - enemy_srcdst_(), - grouping_(), - goals_(), - keeps_(), - leader_aggression_(), - leader_goal_(), - leader_ignores_keep_(), - leader_value_(), - move_maps_enemy_valid_(false), - move_maps_valid_(false), - dst_src_valid_lua_(false), - dst_src_enemy_valid_lua_(false), - src_dst_valid_lua_(false), - src_dst_enemy_valid_lua_(false), - passive_leader_(), - passive_leader_shares_keep_(), - possible_moves_(), - recruitment_diversity_(), - recruitment_instructions_(), - recruitment_more_(), - recruitment_pattern_(), - recruitment_randomness_(), - recruitment_save_gold_(), - recursion_counter_(context.get_recursion_count()), - scout_village_targeting_(), - simple_targeting_(), - srcdst_(), - support_villages_(), - unit_stats_cache_(), - village_value_(), - villages_per_scout_() - { - init_side_context_proxy(context); - manager::get_singleton().add_gamestate_observer(this); - - add_known_aspect("advancements", advancements_); - add_known_aspect("aggression",aggression_); - add_known_aspect("attack_depth",attack_depth_); - add_known_aspect("attacks",attacks_); - add_known_aspect("avoid",avoid_); - add_known_aspect("caution",caution_); - add_known_aspect("grouping",grouping_); - add_known_aspect("leader_aggression",leader_aggression_); - add_known_aspect("leader_goal",leader_goal_); - add_known_aspect("leader_ignores_keep",leader_ignores_keep_); - add_known_aspect("leader_value",leader_value_); - add_known_aspect("passive_leader",passive_leader_); - add_known_aspect("passive_leader_shares_keep",passive_leader_shares_keep_); - add_known_aspect("recruitment_diversity",recruitment_diversity_); - add_known_aspect("recruitment_instructions",recruitment_instructions_); - add_known_aspect("recruitment_more",recruitment_more_); - add_known_aspect("recruitment_pattern",recruitment_pattern_); - add_known_aspect("recruitment_randomness",recruitment_randomness_); - add_known_aspect("recruitment_save_gold",recruitment_save_gold_); - add_known_aspect("scout_village_targeting",scout_village_targeting_); - add_known_aspect("simple_targeting",simple_targeting_); - add_known_aspect("support_villages",support_villages_); - add_known_aspect("village_value",village_value_); - add_known_aspect("villages_per_scout",villages_per_scout_); - keeps_.init(resources::gameboard->map()); - - } - -void readonly_context_impl::on_readonly_context_create() { - //init the composite ai engines - for(const config &cfg_element : cfg_.child_range("engine")) { - engine::parse_engine_from_config(*this,cfg_element,std::back_inserter(engines_)); +void readonly_context_impl::add_known_aspect(const std::string& name, typesafe_aspect_ptr& where) +{ + std::shared_ptr> ka_ptr(new typesafe_known_aspect(name, where, aspects_)); + known_aspects_.emplace(name, ka_ptr); +} + +readonly_context_impl::readonly_context_impl(side_context& context, const config& cfg) + : cfg_(cfg) + , engines_() + , known_aspects_() + , advancements_() + , aggression_() + , attack_depth_() + , aspects_() + , attacks_() + , avoid_() + , caution_() + , defensive_position_cache_() + , dstsrc_() + , enemy_dstsrc_() + , enemy_possible_moves_() + , enemy_srcdst_() + , grouping_() + , goals_() + , keeps_() + , leader_aggression_() + , leader_goal_() + , leader_ignores_keep_() + , leader_value_() + , move_maps_enemy_valid_(false) + , move_maps_valid_(false) + , dst_src_valid_lua_(false) + , dst_src_enemy_valid_lua_(false) + , src_dst_valid_lua_(false) + , src_dst_enemy_valid_lua_(false) + , passive_leader_() + , passive_leader_shares_keep_() + , possible_moves_() + , recruitment_diversity_() + , recruitment_instructions_() + , recruitment_more_() + , recruitment_pattern_() + , recruitment_randomness_() + , recruitment_save_gold_() + , recursion_counter_(context.get_recursion_count()) + , scout_village_targeting_() + , simple_targeting_() + , srcdst_() + , support_villages_() + , unit_stats_cache_() + , village_value_() + , villages_per_scout_() +{ + init_side_context_proxy(context); + manager::get_singleton().add_gamestate_observer(this); + + add_known_aspect("advancements", advancements_); + add_known_aspect("aggression", aggression_); + add_known_aspect("attack_depth", attack_depth_); + add_known_aspect("attacks", attacks_); + add_known_aspect("avoid", avoid_); + add_known_aspect("caution", caution_); + add_known_aspect("grouping", grouping_); + add_known_aspect("leader_aggression", leader_aggression_); + add_known_aspect("leader_goal", leader_goal_); + add_known_aspect("leader_ignores_keep", leader_ignores_keep_); + add_known_aspect("leader_value", leader_value_); + add_known_aspect("passive_leader", passive_leader_); + add_known_aspect("passive_leader_shares_keep", passive_leader_shares_keep_); + add_known_aspect("recruitment_diversity", recruitment_diversity_); + add_known_aspect("recruitment_instructions", recruitment_instructions_); + add_known_aspect("recruitment_more", recruitment_more_); + add_known_aspect("recruitment_pattern", recruitment_pattern_); + add_known_aspect("recruitment_randomness", recruitment_randomness_); + add_known_aspect("recruitment_save_gold", recruitment_save_gold_); + add_known_aspect("scout_village_targeting", scout_village_targeting_); + add_known_aspect("simple_targeting", simple_targeting_); + add_known_aspect("support_villages", support_villages_); + add_known_aspect("village_value", village_value_); + add_known_aspect("villages_per_scout", villages_per_scout_); + + keeps_.init(resources::gameboard->map()); +} + +void readonly_context_impl::on_readonly_context_create() +{ + // init the composite ai engines + for(const config& cfg_element : cfg_.child_range("engine")) { + engine::parse_engine_from_config(*this, cfg_element, std::back_inserter(engines_)); } // init the composite ai aspects - for(const config &cfg_element : cfg_.child_range("aspect")) { + for(const config& cfg_element : cfg_.child_range("aspect")) { std::vector aspects; - engine::parse_aspect_from_config(*this,cfg_element,cfg_element["id"],std::back_inserter(aspects)); + engine::parse_aspect_from_config(*this, cfg_element, cfg_element["id"], std::back_inserter(aspects)); add_aspects(aspects); } // init the composite ai goals - for(const config &cfg_element : cfg_.child_range("goal")) { - engine::parse_goal_from_config(*this,cfg_element,std::back_inserter(get_goals())); + for(const config& cfg_element : cfg_.child_range("goal")) { + engine::parse_goal_from_config(*this, cfg_element, std::back_inserter(get_goals())); } } - config side_context_impl::to_side_context_config() const { return config(); @@ -287,19 +297,21 @@ config readwrite_context_impl::to_readwrite_context_config() const return config(); } - config readonly_context_impl::to_readonly_context_config() const { config cfg; for(const engine_ptr e : engines_) { - cfg.add_child("engine",e->to_config()); + cfg.add_child("engine", e->to_config()); } + for(const aspect_map::value_type a : aspects_) { - cfg.add_child("aspect",a.second->to_config()); + cfg.add_child("aspect", a.second->to_config()); } + for(const goal_ptr g : goals_) { - cfg.add_child("goal",g->to_config()); + cfg.add_child("goal", g->to_config()); } + return cfg; } @@ -313,13 +325,13 @@ void readonly_context_impl::handle_generic_event(const std::string& /*event_name invalidate_move_maps(); } - -const game_info& readonly_context_impl::get_info() const{ +const game_info& readonly_context_impl::get_info() const +{ return manager::get_singleton().get_active_ai_info_for_side(get_side()); } - -game_info& readwrite_context_impl::get_info_w(){ +game_info& readwrite_context_impl::get_info_w() +{ return manager::get_singleton().get_active_ai_info_for_side(get_side()); } @@ -330,64 +342,70 @@ void readonly_context_impl::diagnostic(const std::string& msg) } } - const team& readonly_context_impl::current_team() const { return resources::gameboard->get_team(get_side()); } - void readonly_context_impl::log_message(const std::string& msg) { if(game_config::debug) { - game_display::get_singleton()->get_chat_manager().add_chat_message(time(nullptr), "ai", get_side(), msg, - events::chat_handler::MESSAGE_PUBLIC, false); + game_display::get_singleton()->get_chat_manager().add_chat_message( + time(nullptr), "ai", get_side(), msg, events::chat_handler::MESSAGE_PUBLIC, false); } } - -void readonly_context_impl::calculate_possible_moves(std::map& res, move_map& srcdst, - move_map& dstsrc, bool enemy, bool assume_full_movement, +void readonly_context_impl::calculate_possible_moves(std::map& res, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement, const terrain_filter* remove_destinations) const { - calculate_moves(resources::gameboard->units(),res,srcdst,dstsrc,enemy,assume_full_movement,remove_destinations); + calculate_moves( + resources::gameboard->units(), res, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations); } -void readonly_context_impl::calculate_moves(const unit_map& units, std::map& res, move_map& srcdst, - move_map& dstsrc, bool enemy, bool assume_full_movement, +void readonly_context_impl::calculate_moves(const unit_map& units, + std::map& res, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement, const terrain_filter* remove_destinations, - bool see_all - ) const + bool see_all) const { - for(unit_map::const_iterator un_it = units.begin(); un_it != units.end(); ++un_it) { // If we are looking for the movement of enemies, then this unit must be an enemy unit. // If we are looking for movement of our own units, it must be on our side. // If we are assuming full movement, then it may be a unit on our side, or allied. - if ((enemy && current_team().is_enemy(un_it->side()) == false) || - (!enemy && !assume_full_movement && un_it->side() != get_side()) || - (!enemy && assume_full_movement && current_team().is_enemy(un_it->side()))) { + if((enemy && current_team().is_enemy(un_it->side()) == false) + || (!enemy && !assume_full_movement && un_it->side() != get_side()) + || (!enemy && assume_full_movement && current_team().is_enemy(un_it->side())) + ) { continue; } + // Discount incapacitated units - if (un_it->incapacitated() || - (!assume_full_movement && un_it->movement_left() == 0)) { + if(un_it->incapacitated() || (!assume_full_movement && un_it->movement_left() == 0)) { continue; } // We can't see where invisible enemy units might move. - if (enemy && un_it->invisible(un_it->get_location()) && !see_all) { + if(enemy && un_it->invisible(un_it->get_location()) && !see_all) { continue; } + // If it's an enemy unit, reset its moves while we do the calculations. - const unit_movement_resetter move_resetter(*un_it,enemy || assume_full_movement); + const unit_movement_resetter move_resetter(*un_it, enemy || assume_full_movement); // Insert the trivial moves of staying on the same map location. - if (un_it->movement_left() > 0) { - std::pair trivial_mv(un_it->get_location(), un_it->get_location()); + if(un_it->movement_left() > 0) { + std::pair trivial_mv(un_it->get_location(), un_it->get_location()); srcdst.insert(trivial_mv); dstsrc.insert(trivial_mv); } + /** * @todo This is where support for a speculative unit map is incomplete. * There are several places (deep) within the paths constructor @@ -409,9 +427,8 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::map::iterator m = res.begin(); m != res.end(); ++m) { - for(const pathfind::paths::step &dest : m->second.destinations) - { + for(std::map::iterator m = res.begin(); m != res.end(); ++m) { + for(const pathfind::paths::step& dest : m->second.destinations) { const map_location& src = m->first; const map_location& dst = dest.curr; @@ -426,7 +443,7 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::mapteams().size(); ++n) { if(resources::gameboard->teams()[n].owns_village(dst)) { int side = n + 1; - if (get_side() != side && !current_team().is_enemy(side)) { + if(get_side() != side && !current_team().is_enemy(side)) { friend_owns = true; } @@ -439,7 +456,7 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::mapfind_visible_unit(dst, current_team()) == resources::gameboard->units().end()) ) { + if(src != dst && (resources::gameboard->find_visible_unit(dst, current_team()) == resources::gameboard->units().end())) { srcdst.emplace(src, dst); dstsrc.emplace(dst, src); } @@ -447,32 +464,32 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::map &aspects ) +void readonly_context_impl::add_aspects(std::vector& aspects) { for(aspect_ptr a : aspects) { const std::string id = a->get_id(); known_aspect_map::iterator i = known_aspects_.find(id); - if (i != known_aspects_.end()) { + + if(i != known_aspects_.end()) { i->second->set(a); } else { - ERR_AI << "when adding aspects, unknown aspect id["<second->add_facet(cfg); } else { - ERR_AI << "when adding aspects, unknown aspect id["<units().find(loc); if(itor == resources::gameboard->units().end()) { @@ -482,8 +499,7 @@ const defensive_position& readonly_context_impl::best_defensive_position(const m return pos; } - const std::map::const_iterator position = - defensive_position_cache_.find(loc); + const std::map::const_iterator position = defensive_position_cache_.find(loc); if(position != defensive_position_cache_.end()) { return position->second; @@ -495,15 +511,16 @@ const defensive_position& readonly_context_impl::best_defensive_position(const m pos.support = 0.0; typedef move_map::const_iterator Itor; - const std::pair itors = srcdst.equal_range(loc); + const std::pair itors = srcdst.equal_range(loc); + for(Itor i = itors.first; i != itors.second; ++i) { const int defense = itor->defense_modifier(resources::gameboard->map().get_terrain(i->second)); if(defense > pos.chance_to_hit) { continue; } - const double vulnerability = power_projection(i->second,enemy_dstsrc); - const double support = power_projection(i->second,dstsrc); + const double vulnerability = power_projection(i->second, enemy_dstsrc); + const double support = power_projection(i->second, dstsrc); if(defense < pos.chance_to_hit || support - vulnerability > pos.support - pos.vulnerability) { pos.loc = i->second; @@ -517,16 +534,14 @@ const defensive_position& readonly_context_impl::best_defensive_position(const m return defensive_position_cache_[loc]; } - -std::map& readonly_context_impl::defensive_position_cache() const +std::map& readonly_context_impl::defensive_position_cache() const { return defensive_position_cache_; } - const unit_advancements_aspect& readonly_context_impl::get_advancements() const { - if (advancements_) { + if(advancements_) { return advancements_->get(); } @@ -534,361 +549,351 @@ const unit_advancements_aspect& readonly_context_impl::get_advancements() const return uaa; } - double readonly_context_impl::get_aggression() const { - if (aggression_) { + if(aggression_) { return aggression_->get(); } + return 0; } - int readonly_context_impl::get_attack_depth() const { - if (attack_depth_) { - return std::max(1,attack_depth_->get()); ///@todo 1.9: add validators, such as minmax filters to aspects + if(attack_depth_) { + return std::max(1, attack_depth_->get()); ///@todo 1.9: add validators, such as minmax filters to aspects } + return 1; } - const aspect_map& readonly_context_impl::get_aspects() const { return aspects_; } - aspect_map& readonly_context_impl::get_aspects() { return aspects_; } - const attacks_vector& readonly_context_impl::get_attacks() const { - if (attacks_) { + if(attacks_) { return attacks_->get(); } + static attacks_vector av; return av; } - const wfl::variant& readonly_context_impl::get_attacks_as_variant() const { - if (attacks_) { + if(attacks_) { return attacks_->get_variant(); } - static wfl::variant v;///@todo 1.9: replace with variant::null_variant; + + static wfl::variant v; ///@todo 1.9: replace with variant::null_variant; return v; } const terrain_filter& readonly_context_impl::get_avoid() const { - if (avoid_) { + if(avoid_) { return avoid_->get(); } + config cfg; cfg.add_child("not"); static terrain_filter tf(vconfig(cfg, true), resources::filter_con); return tf; } - double readonly_context_impl::get_caution() const { - if (caution_) { + if(caution_) { return caution_->get(); } + return 0; } const move_map& readonly_context_impl::get_dstsrc() const { - if (!move_maps_valid_) { + if(!move_maps_valid_) { recalculate_move_maps(); } + return dstsrc_; } - const move_map& readonly_context_impl::get_enemy_dstsrc() const { - if (!move_maps_enemy_valid_) { + if(!move_maps_enemy_valid_) { recalculate_move_maps_enemy(); } return enemy_dstsrc_; } - const moves_map& readonly_context_impl::get_enemy_possible_moves() const { - if (!move_maps_enemy_valid_) { + if(!move_maps_enemy_valid_) { recalculate_move_maps_enemy(); } + return enemy_possible_moves_; } - const move_map& readonly_context_impl::get_enemy_srcdst() const { - if (!move_maps_enemy_valid_) { + if(!move_maps_enemy_valid_) { recalculate_move_maps_enemy(); } + return enemy_srcdst_; } - engine_ptr readonly_context_impl::get_engine_by_cfg(const config& cfg) { std::string engine_name = cfg["engine"]; - if (engine_name.empty()) { - engine_name="cpp";//default engine + if(engine_name.empty()) { + engine_name = "cpp"; // default engine } std::vector::iterator en = engines_.begin(); - while (en!=engines_.end() && ((*en)->get_name()!=engine_name) && ((*en)->get_id()!=engine_name)) { + while(en != engines_.end() && ((*en)->get_name() != engine_name) && ((*en)->get_id() != engine_name)) { ++en; } - if (en != engines_.end()){ + if(en != engines_.end()) { return *en; } - //TODO: fix, removing some code duplication + // TODO: fix, removing some code duplication engine_factory::factory_map::iterator eng = engine_factory::get_list().find(engine_name); - if (eng == engine_factory::get_list().end()){ - ERR_AI << "side "<second->get_new_instance(*this,engine_name); - if (!new_engine) { - ERR_AI << "side "<second->get_new_instance(*this, engine_name); + if(!new_engine) { + ERR_AI << "side " << get_side() << " : UNABLE TO CREATE engine[" << engine_name << "] " << std::endl; DBG_AI << "config snippet contains: " << std::endl << cfg << std::endl; return engine_ptr(); } + engines_.push_back(new_engine); return engines_.back(); } - const std::vector& readonly_context_impl::get_engines() const { return engines_; } - std::vector& readonly_context_impl::get_engines() { return engines_; } - std::string readonly_context_impl::get_grouping() const { - if (grouping_) { + if(grouping_) { return grouping_->get(); } return std::string(); } - const std::vector& readonly_context_impl::get_goals() const { return goals_; } - std::vector& readonly_context_impl::get_goals() { return goals_; } - - double readonly_context_impl::get_leader_aggression() const { - if (leader_aggression_) { + if(leader_aggression_) { return leader_aggression_->get(); } + return 0; } - config readonly_context_impl::get_leader_goal() const { - if (leader_goal_) { + if(leader_goal_) { return leader_goal_->get(); } + return config(); } - bool readonly_context_impl::get_leader_ignores_keep() const { - if (leader_ignores_keep_) { + if(leader_ignores_keep_) { return leader_ignores_keep_->get(); } + return false; } - double readonly_context_impl::get_leader_value() const { - if (leader_value_) { + if(leader_value_) { return leader_value_->get(); } + return 0; } - bool readonly_context_impl::get_passive_leader() const { - if (passive_leader_) { + if(passive_leader_) { return passive_leader_->get(); } + return false; } - bool readonly_context_impl::get_passive_leader_shares_keep() const { - if (passive_leader_shares_keep_) { + if(passive_leader_shares_keep_) { return passive_leader_shares_keep_->get(); } + return false; } - const moves_map& readonly_context_impl::get_possible_moves() const { - if (!move_maps_valid_) { + if(!move_maps_valid_) { recalculate_move_maps(); } + return possible_moves_; } - const std::vector& readonly_context_impl::get_recall_list() const { ///@todo 1.9: check for (level_["disallow_recall"])) - return current_team().recall_list().recall_list_; //TODO: Refactor ai so that friend of ai context is not required of recall_list_manager at this line + // TODO: Refactor ai so that friend of ai context is not required + // of recall_list_manager at this line + return current_team().recall_list().recall_list_; } - double readonly_context_impl::get_recruitment_diversity() const { - if (recruitment_diversity_) { + if(recruitment_diversity_) { return recruitment_diversity_->get(); } + return 0.; } - const config readonly_context_impl::get_recruitment_instructions() const { - if (recruitment_instructions_) { + if(recruitment_instructions_) { return recruitment_instructions_->get(); } + return config(); } - const std::vector readonly_context_impl::get_recruitment_more() const { - if (recruitment_more_) { + if(recruitment_more_) { return recruitment_more_->get(); } + return std::vector(); } - const std::vector readonly_context_impl::get_recruitment_pattern() const { - if (recruitment_pattern_) { + if(recruitment_pattern_) { return recruitment_pattern_->get(); } + return std::vector(); } - int readonly_context_impl::get_recruitment_randomness() const { - if (recruitment_randomness_) { + if(recruitment_randomness_) { return recruitment_randomness_->get(); } + return 0; } - const config readonly_context_impl::get_recruitment_save_gold() const { - if (recruitment_save_gold_) { + if(recruitment_save_gold_) { return recruitment_save_gold_->get(); } + return config(); } - double readonly_context_impl::get_scout_village_targeting() const { - if (scout_village_targeting_) { + if(scout_village_targeting_) { return scout_village_targeting_->get(); } + return 1; } - bool readonly_context_impl::get_simple_targeting() const { - if (simple_targeting_) { + if(simple_targeting_) { return simple_targeting_->get(); } + return false; } - const move_map& readonly_context_impl::get_srcdst() const { - if (!move_maps_valid_) { + if(!move_maps_valid_) { recalculate_move_maps(); } return srcdst_; } - bool readonly_context_impl::get_support_villages() const { - if (support_villages_) { + if(support_villages_) { return support_villages_->get(); } + return false; } - double readonly_context_impl::get_village_value() const { - if (village_value_) { + if(village_value_) { return village_value_->get(); } + return 0; } - int readonly_context_impl::get_villages_per_scout() const { - if (villages_per_scout_) { + if(villages_per_scout_) { return villages_per_scout_->get(); } + return 0; } - bool readonly_context_impl::is_dst_src_valid_lua() const { return dst_src_valid_lua_; @@ -914,19 +919,16 @@ void readonly_context_impl::invalidate_defensive_position_cache() const defensive_position_cache_.clear(); } - void readonly_context_impl::invalidate_keeps_cache() const { keeps_.clear(); } - -void keeps_cache::handle_generic_event(const std::string &/*event_name*/) +void keeps_cache::handle_generic_event(const std::string& /*event_name*/) { clear(); } - void readonly_context_impl::invalidate_move_maps() const { move_maps_valid_ = false; @@ -939,13 +941,11 @@ void readonly_context_impl::invalidate_move_maps() const src_dst_enemy_valid_lua_ = false; } - const std::set& readonly_context_impl::keeps() const { return keeps_.get(); } - keeps_cache::keeps_cache() : map_(nullptr) , keeps_() @@ -954,7 +954,6 @@ keeps_cache::keeps_cache() ai::manager::get_singleton().add_map_changed_observer(this); } - keeps_cache::~keeps_cache() { ai::manager::get_singleton().remove_turn_started_observer(this); @@ -966,8 +965,7 @@ void keeps_cache::clear() keeps_.clear(); } - -void keeps_cache::init(const gamemap &map) +void keeps_cache::init(const gamemap& map) { map_ = ↦ } @@ -979,10 +977,10 @@ const std::set& keeps_cache::get() // iterate over the entire map and find all keeps. for(int x = 0; x != map_->w(); ++x) { for(int y = 0; y != map_->h(); ++y) { - const map_location loc(x,y); + const map_location loc(x, y); if(map_->is_keep(loc)) { adjacent_loc_array_t adj; - get_adjacent_tiles(loc,adj.data()); + get_adjacent_tiles(loc, adj.data()); for(std::size_t n = 0; n < adj.size(); ++n) { if(map_->is_castle(adj[n])) { keeps_.insert(loc); @@ -997,7 +995,6 @@ const std::set& keeps_cache::get() return keeps_; } - bool readonly_context_impl::leader_can_reach_keep() const { const unit_map::iterator leader = resources::gameboard->units().find_leader(get_side()); @@ -1005,12 +1002,12 @@ bool readonly_context_impl::leader_can_reach_keep() const return false; } - const map_location &start_pos = nearest_keep(leader->get_location()); + const map_location& start_pos = nearest_keep(leader->get_location()); if(start_pos.valid() == false) { return false; } - if (leader->get_location() == start_pos) { + if(leader->get_location() == start_pos) { return true; } @@ -1020,7 +1017,6 @@ bool readonly_context_impl::leader_can_reach_keep() const return leader_paths.destinations.contains(start_pos); } - const map_location& readonly_context_impl::nearest_keep(const map_location& loc) const { std::set avoided_locations; @@ -1034,23 +1030,24 @@ const map_location& readonly_context_impl::nearest_keep(const map_location& loc) const map_location* res = nullptr; int closest = -1; for(std::set::const_iterator i = keeps.begin(); i != keeps.end(); ++i) { - if (avoided_locations.find(*i)!=avoided_locations.end()) { + if(avoided_locations.find(*i) != avoided_locations.end()) { continue; } - const int distance = distance_between(*i,loc); + + const int distance = distance_between(*i, loc); if(res == nullptr || distance < closest) { closest = distance; res = &*i; } } - if (res) { + + if(res) { return *res; } else { return map_location::null_location(); } } - double readonly_context_impl::power_projection(const map_location& loc, const move_map& dstsrc) const { map_location used_locs[6]; @@ -1059,7 +1056,7 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo int num_used_locs = 0; adjacent_loc_array_t locs; - get_adjacent_tiles(loc,locs.data()); + get_adjacent_tiles(loc, locs.data()); const gamemap& map_ = resources::gameboard->map(); unit_map& units_ = resources::gameboard->units(); @@ -1067,23 +1064,26 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo int res = 0; bool changed = false; - for (int i = 0;; ++i) { - if (i == 6) { - if (!changed) break; + for(int i = 0;; ++i) { + if(i == 6) { + if(!changed) { + break; + } + // Loop once again, in case a unit found a better spot // and freed the place for another unit. changed = false; i = 0; } - if (map_.on_board(locs[i]) == false) { + if(map_.on_board(locs[i]) == false) { continue; } const t_translation::terrain_code terrain = map_[locs[i]]; typedef move_map::const_iterator Itor; - typedef std::pair Range; + typedef std::pair Range; Range its = dstsrc.equal_range(locs[i]); map_location* const beg_used = used_locs; @@ -1107,6 +1107,7 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo if(un.side() < get_side()) { ++attack_turn; } + // Considering the unit location would be too slow, we only apply the bonus granted by the global ToD const int lawful_bonus = resources::tod_manager->get_time_of_day(attack_turn).lawful_bonus; int tod_modifier = 0; @@ -1121,10 +1122,9 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo // The 0.5 power avoids underestimating too much the damage of a wounded unit. int64_t hp = int(std::sqrt(double(un.hitpoints()) / un.max_hitpoints()) * 1000); int64_t most_damage = 0; - for(const attack_type &att : un.attacks()) - { + for(const attack_type& att : un.attacks()) { int damage = att.damage() * att.num_attacks() * (100 + tod_modifier); - if (damage > most_damage) { + if(damage > most_damage) { most_damage = damage; } } @@ -1136,29 +1136,34 @@ double readonly_context_impl::power_projection(const map_location& loc, const mo if(static_cast(rating) != rating_64) { WRN_AI << "overflow in ai attack calculation\n"; } + if(rating > best_rating) { - map_location *pos = std::find(beg_used, end_used, it->second); + map_location* pos = std::find(beg_used, end_used, it->second); // Check if the spot is the same or better than an older one. - if (pos == end_used || rating >= ratings[pos - beg_used]) { + if(pos == end_used || rating >= ratings[pos - beg_used]) { best_rating = rating; best_unit = it->second; } } } - if (!best_unit.valid()) continue; - map_location *pos = std::find(beg_used, end_used, best_unit); + if(!best_unit.valid()) { + continue; + } + + map_location* pos = std::find(beg_used, end_used, best_unit); int index = pos - beg_used; - if (index == num_used_locs) + if(index == num_used_locs) { ++num_used_locs; - else if (best_rating == ratings[index]) + } else if(best_rating == ratings[index]) { continue; - else { + } else { // The unit was in another spot already, so remove its older rating // from the final result, and require a new run to fill its old spot. res -= ratings[index]; changed = true; } + used_locs[index] = best_unit; ratings[index] = best_rating; res += best_rating; @@ -1172,22 +1177,25 @@ void readonly_context_impl::recalculate_move_maps() const dstsrc_ = move_map(); possible_moves_ = moves_map(); srcdst_ = move_map(); - calculate_possible_moves(possible_moves_,srcdst_,dstsrc_,false,false,&get_avoid()); - if (get_passive_leader()||get_passive_leader_shares_keep()) { + + calculate_possible_moves(possible_moves_, srcdst_, dstsrc_, false, false, &get_avoid()); + + if(get_passive_leader() || get_passive_leader_shares_keep()) { unit_map::iterator i = resources::gameboard->units().find_leader(get_side()); - if (i.valid()) { + if(i.valid()) { map_location loc = i->get_location(); srcdst_.erase(loc); - for(move_map::iterator it = dstsrc_.begin(); it != dstsrc_.end(); ) { + for(move_map::iterator it = dstsrc_.begin(); it != dstsrc_.end();) { if(it->second == loc) { it = dstsrc_.erase(it); } else { ++it; } } - ///@todo: shall possible moves be modified as well ? + ///@todo: shall possible moves be modified as well ? } } + move_maps_valid_ = true; // invalidate lua cache @@ -1195,13 +1203,12 @@ void readonly_context_impl::recalculate_move_maps() const src_dst_valid_lua_ = false; } - void readonly_context_impl::recalculate_move_maps_enemy() const { enemy_dstsrc_ = move_map(); enemy_srcdst_ = move_map(); enemy_possible_moves_ = moves_map(); - calculate_possible_moves(enemy_possible_moves_,enemy_srcdst_,enemy_dstsrc_,true); + calculate_possible_moves(enemy_possible_moves_, enemy_srcdst_, enemy_dstsrc_, true); move_maps_enemy_valid_ = true; // invalidate lua cache @@ -1229,9 +1236,11 @@ void readonly_context_impl::set_src_dst_enemy_valid_lua() src_dst_enemy_valid_lua_ = true; } -const map_location& readonly_context_impl::suitable_keep(const map_location& leader_location, const pathfind::paths& leader_paths) const { - if (resources::gameboard->map().is_keep(leader_location)) { - return leader_location; //if leader already on keep, then return leader_location +const map_location& readonly_context_impl::suitable_keep( + const map_location& leader_location, const pathfind::paths& leader_paths) const +{ + if(resources::gameboard->map().is_keep(leader_location)) { + return leader_location; // if leader already on keep, then return leader_location } map_location const* best_free_keep = &map_location::null_location(); @@ -1240,66 +1249,67 @@ const map_location& readonly_context_impl::suitable_keep(const map_location& lea map_location const* best_occupied_keep = &map_location::null_location(); double move_left_at_best_occupied_keep = 0.0; - for(const pathfind::paths::step &dest : leader_paths.destinations) - { - const map_location &loc = dest.curr; - if (keeps().find(loc)!=keeps().end()){ + for(const pathfind::paths::step& dest : leader_paths.destinations) { + const map_location& loc = dest.curr; + if(keeps().find(loc) != keeps().end()) { const int move_left_at_loc = dest.move_left; - if (resources::gameboard->units().count(loc) == 0) { - if ((*best_free_keep==map_location::null_location())||(move_left_at_loc>move_left_at_best_free_keep)){ + if(resources::gameboard->units().count(loc) == 0) { + if((*best_free_keep == map_location::null_location()) + || (move_left_at_loc > move_left_at_best_free_keep)) { best_free_keep = &loc; move_left_at_best_free_keep = move_left_at_loc; } } else { - if ((*best_occupied_keep==map_location::null_location())||(move_left_at_loc>move_left_at_best_occupied_keep)){ + if((*best_occupied_keep == map_location::null_location()) + || (move_left_at_loc > move_left_at_best_occupied_keep)) { best_occupied_keep = &loc; - move_left_at_best_occupied_keep = move_left_at_loc; + move_left_at_best_occupied_keep = move_left_at_loc; } } } } - if (*best_free_keep != map_location::null_location()){ + if(*best_free_keep != map_location::null_location()) { return *best_free_keep; // if there is a free keep reachable during current turn, return it } - if (*best_occupied_keep != map_location::null_location()){ + if(*best_occupied_keep != map_location::null_location()) { return *best_occupied_keep; // if there is an occupied keep reachable during current turn, return it } return nearest_keep(leader_location); // return nearest keep } - - /** Weapon choice cache, to speed simulations. */ -readonly_context::unit_stats_cache_t & readonly_context_impl::unit_stats_cache() const +/** Weapon choice cache, to speed simulations. */ +readonly_context::unit_stats_cache_t& readonly_context_impl::unit_stats_cache() const { return unit_stats_cache_; } - -bool readonly_context_impl::is_active(const std::string &time_of_day, const std::string &turns) const +bool readonly_context_impl::is_active(const std::string& time_of_day, const std::string& turns) const { - if(time_of_day.empty() == false) { - const std::vector& times = utils::split(time_of_day); - if(std::count(times.begin(),times.end(),resources::tod_manager->get_time_of_day().id) == 0) { - return false; - } + if(time_of_day.empty() == false) { + const std::vector& times = utils::split(time_of_day); + if(std::count(times.begin(), times.end(), resources::tod_manager->get_time_of_day().id) == 0) { + return false; } + } - if(turns.empty() == false) { - int turn = resources::tod_manager->turn(); - const std::vector& turns_list = utils::split(turns); - for(std::vector::const_iterator j = turns_list.begin(); j != turns_list.end() ; ++j ) { - const std::pair range = utils::parse_range(*j); - if(turn >= range.first && turn <= range.second) { - return true; - } + if(turns.empty() == false) { + int turn = resources::tod_manager->turn(); + const std::vector& turns_list = utils::split(turns); + for(std::vector::const_iterator j = turns_list.begin(); j != turns_list.end(); ++j) { + const std::pair range = utils::parse_range(*j); + if(turn >= range.first && turn <= range.second) { + return true; } - return false; } - return true; + + return false; + } + + return true; } -} //of namespace ai +} // of namespace ai diff --git a/src/ai/contexts.hpp b/src/ai/contexts.hpp index 4ab21487f99e..2906139111e3 100644 --- a/src/ai/contexts.hpp +++ b/src/ai/contexts.hpp @@ -20,50 +20,51 @@ #pragma once -#include "ai/game_info.hpp" // for move_map, typesafe_aspect_ptr, etc +#include "ai/game_info.hpp" // for move_map, typesafe_aspect_ptr, etc -#include "config.hpp" // for config +#include "config.hpp" // for config #include "game_errors.hpp" -#include "generic_event.hpp" // for observer -#include "units/ptr.hpp" // for unit_ptr -#include "map/location.hpp" // for map_location +#include "generic_event.hpp" // for observer +#include "map/location.hpp" // for map_location +#include "units/ptr.hpp" // for unit_ptr -#include // for map, map<>::value_compare -#include // for set -#include // for string -#include // for pair -#include // for vector +#include // for map, map<>::value_compare +#include // for set +#include // for string +#include // for pair +#include // for vector -class gamemap; // lines 41-41 +class gamemap; class team; -class terrain_filter; // lines 43-43 +class terrain_filter; class unit_map; -class unit_type; // lines 46-46 +class unit_type; + namespace wfl { class variant; } -namespace ai { class ai_context; } // lines 51-51 +namespace ai { class ai_context; } namespace ai { class unit_advancements_aspect; } namespace ai { template class typesafe_aspect; } namespace boost { template class shared_ptr; } namespace pathfind { struct paths; } -struct battle_context_unit_stats; // lines 39-39 -namespace ai { +struct battle_context_unit_stats; +namespace ai +{ typedef ai_context* ai_context_ptr; - // recursion counter -class recursion_counter { +class recursion_counter +{ public: recursion_counter(int counter) : counter_(++counter) { - if (counter > MAX_COUNTER_VALUE ) { + if(counter > MAX_COUNTER_VALUE) { throw game::game_error("maximum recursion depth reached!"); } } - /** * Get the current value of the recursion counter */ @@ -72,11 +73,9 @@ class recursion_counter { return counter_; } - - //max recursion depth + // max recursion depth static const int MAX_COUNTER_VALUE = 100; - /** * Check if more recursion is allowed */ @@ -84,21 +83,23 @@ class recursion_counter { { return counter_ < MAX_COUNTER_VALUE; } -private: +private: // recursion counter value int counter_; }; -//defensive position +// defensive position -struct defensive_position { - defensive_position() : - loc(), - chance_to_hit(0), - vulnerability(0.0), - support(0.0) - {} +struct defensive_position +{ + defensive_position() + : loc() + , chance_to_hit(0) + , vulnerability(0.0) + , support(0.0) + { + } map_location loc; int chance_to_hit; @@ -114,9 +115,10 @@ class keeps_cache : public events::observer void handle_generic_event(const std::string& event_name); void clear(); const std::set& get(); - void init(const gamemap &map); + void init(const gamemap& map); + private: - const gamemap *map_; + const gamemap* map_; std::set keeps_; }; @@ -124,132 +126,147 @@ class keeps_cache : public events::observer class side_context; -class side_context{ +class side_context +{ public: - /** * Get the side number */ - virtual side_number get_side() const = 0; - + virtual side_number get_side() const = 0; /** * Set the side number */ virtual void set_side(side_number side) = 0; - /** * empty destructor */ - virtual ~side_context(){} - + virtual ~side_context() + { + } /** * empty constructor */ - side_context() {} - + side_context() + { + } /** * unwrap */ virtual side_context& get_side_context() = 0; - /** * serialize this context to config */ virtual config to_side_context_config() const = 0; - /** * Get the value of the recursion counter */ virtual int get_recursion_count() const = 0; - - }; class readonly_context; -class readonly_context : public virtual side_context { +class readonly_context : public virtual side_context +{ public: - readonly_context(){} - virtual ~readonly_context(){} + readonly_context() + { + } + + virtual ~readonly_context() + { + } + virtual readonly_context& get_readonly_context() = 0; virtual void on_readonly_context_create() = 0; virtual const team& current_team() const = 0; virtual void diagnostic(const std::string& msg) = 0; virtual void log_message(const std::string& msg) = 0; - virtual attack_result_ptr check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) = 0; - virtual move_result_ptr check_move_action(const map_location& from, const map_location& to, bool remove_movement=true, bool unreach_is_ok=false) = 0; - virtual recall_result_ptr check_recall_action(const std::string& id, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) = 0; - virtual recruit_result_ptr check_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) = 0; - virtual stopunit_result_ptr check_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) = 0; - virtual synced_command_result_ptr check_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) = 0; - virtual void calculate_possible_moves(std::map& possible_moves, - move_map& srcdst, move_map& dstsrc, bool enemy, - bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr) const = 0; + + virtual attack_result_ptr check_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) + = 0; + + virtual move_result_ptr check_move_action( + const map_location& from, const map_location& to, bool remove_movement = true, bool unreach_is_ok = false) + = 0; + + virtual recall_result_ptr check_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) + = 0; + + virtual recruit_result_ptr check_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) + = 0; + + virtual stopunit_result_ptr check_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) + = 0; + + virtual synced_command_result_ptr check_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) + = 0; + + virtual void calculate_possible_moves(std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr) const = 0; + virtual void calculate_moves(const unit_map& units, - std::map& possible_moves, move_map& srcdst, - move_map& dstsrc, bool enemy, bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr, - bool see_all=false) const = 0; + std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr, + bool see_all = false) const = 0; virtual const game_info& get_info() const = 0; - //@note: following part is in alphabetic order virtual const defensive_position& best_defensive_position(const map_location& unit, - const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const = 0; - - - virtual std::map& defensive_position_cache() const = 0; + const move_map& dstsrc, + const move_map& srcdst, + const move_map& enemy_dstsrc) const = 0; + virtual std::map& defensive_position_cache() const = 0; virtual const unit_advancements_aspect& get_advancements() const = 0; - virtual double get_aggression() const = 0; - virtual int get_attack_depth() const = 0; - virtual const aspect_map& get_aspects() const = 0; - virtual aspect_map& get_aspects() = 0; + virtual void add_facet(const std::string& id, const config& cfg) const = 0; - virtual void add_facet(const std::string &id, const config &cfg) const = 0; - - - virtual void add_aspects(std::vector< aspect_ptr > &aspects ) = 0; - + virtual void add_aspects(std::vector& aspects) = 0; virtual const attacks_vector& get_attacks() const = 0; - virtual const wfl::variant& get_attacks_as_variant() const = 0; - virtual const terrain_filter& get_avoid() const = 0; - virtual double get_caution() const = 0; - virtual const move_map& get_dstsrc() const = 0; - virtual const move_map& get_enemy_dstsrc() const = 0; - virtual const moves_map& get_enemy_possible_moves() const = 0; - virtual const move_map& get_enemy_srcdst() const = 0; /** @@ -257,84 +274,57 @@ class readonly_context : public virtual side_context { */ virtual engine_ptr get_engine_by_cfg(const config& cfg) = 0; - virtual const std::vector& get_engines() const = 0; - virtual std::vector& get_engines() = 0; - virtual std::string get_grouping() const = 0; - virtual const std::vector& get_goals() const = 0; - virtual std::vector& get_goals() = 0; - virtual double get_leader_aggression() const = 0; - virtual config get_leader_goal() const = 0; - virtual bool get_leader_ignores_keep() const = 0; - virtual double get_leader_value() const = 0; - virtual bool get_passive_leader() const = 0; - virtual bool get_passive_leader_shares_keep() const = 0; - virtual const moves_map& get_possible_moves() const = 0; - virtual const std::vector& get_recall_list() const = 0; - virtual double get_recruitment_diversity() const = 0; - virtual const config get_recruitment_instructions() const = 0; - virtual const std::vector get_recruitment_more() const = 0; - virtual const std::vector get_recruitment_pattern() const = 0; - virtual int get_recruitment_randomness() const = 0; - virtual const config get_recruitment_save_gold() const = 0; - virtual double get_scout_village_targeting() const = 0; - virtual bool get_simple_targeting() const = 0; - virtual const move_map& get_srcdst() const = 0; - virtual bool get_support_villages() const = 0; - virtual double get_village_value() const = 0; - virtual int get_villages_per_scout() const = 0; - - - virtual bool is_active(const std::string &time_of_day, const std::string &turns) const = 0; + virtual bool is_active(const std::string& time_of_day, const std::string& turns) const = 0; virtual bool is_dst_src_valid_lua() const = 0; @@ -346,22 +336,16 @@ class readonly_context : public virtual side_context { virtual void invalidate_defensive_position_cache() const = 0; - virtual void invalidate_move_maps() const = 0; + virtual void invalidate_keeps_cache() const = 0; - virtual void invalidate_keeps_cache() const= 0; - - - virtual const std::set& keeps() const= 0; - + virtual const std::set& keeps() const = 0; virtual bool leader_can_reach_keep() const = 0; - virtual const map_location& nearest_keep(const map_location& loc) const = 0; - /** * Function which finds how much 'power' a side can attack a certain location with. * This is basically the maximum hp of damage that can be inflicted upon a unit on loc @@ -375,13 +359,10 @@ class readonly_context : public virtual side_context { */ virtual double power_projection(const map_location& loc, const move_map& dstsrc) const = 0; - virtual void raise_user_interact() const = 0; - virtual void recalculate_move_maps() const = 0; - virtual void recalculate_move_maps_enemy() const = 0; virtual void set_src_dst_valid_lua() = 0; @@ -389,83 +370,95 @@ class readonly_context : public virtual side_context { virtual void set_dst_src_valid_lua() = 0; virtual void set_dst_src_enemy_valid_lua() = 0; - /** get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return nearest occupied that can be reached in 1 turn, if none - return nearest keep, if none - return null_location */ - virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths ) const = 0; + /** + * get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return nearest + * occupied that can be reached in 1 turn, if none - return nearest keep, if none - return null_location + * */ + virtual const map_location& suitable_keep( + const map_location& leader_location, const pathfind::paths& leader_paths) const = 0; /** * serialize to config */ virtual config to_readonly_context_config() const = 0; + using unit_stats_cache_t = std::map< + std::pair, + std::pair + >; - typedef std::map, - std::pair> - unit_stats_cache_t; - virtual unit_stats_cache_t & unit_stats_cache() const = 0; - + virtual unit_stats_cache_t& unit_stats_cache() const = 0; }; class readwrite_context; -class readwrite_context : public virtual readonly_context { +class readwrite_context : public virtual readonly_context +{ public: - readwrite_context(){} - - - virtual ~readwrite_context(){} + readwrite_context() + { + } + virtual ~readwrite_context() + { + } virtual readwrite_context& get_readwrite_context() = 0; + virtual attack_result_ptr execute_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) + = 0; - virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) = 0; - - - virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true, bool unreach_is_ok=false) = 0; - - - virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) = 0; - - - virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) = 0; + virtual move_result_ptr execute_move_action( + const map_location& from, const map_location& to, bool remove_movement = true, bool unreach_is_ok = false) + = 0; + virtual recall_result_ptr execute_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) + = 0; - virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) = 0; + virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) + = 0; + virtual stopunit_result_ptr execute_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) + = 0; - virtual synced_command_result_ptr execute_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) = 0; - + virtual synced_command_result_ptr execute_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) + = 0; virtual team& current_team_w() = 0; - virtual void raise_gamestate_changed() const = 0; - virtual game_info& get_info_w() = 0; - /** * serialize this context to config */ virtual config to_readwrite_context_config() const = 0; - }; -//proxies +// proxies -class side_context_proxy : public virtual side_context { +class side_context_proxy : public virtual side_context +{ public: side_context_proxy() : target_(nullptr) { } - virtual ~side_context_proxy(){} - + virtual ~side_context_proxy() + { + } - void init_side_context_proxy(side_context &target) + void init_side_context_proxy(side_context& target) { - target_= &target.get_side_context(); + target_ = &target.get_side_context(); } virtual side_number get_side() const override @@ -488,28 +481,28 @@ class side_context_proxy : public virtual side_context { return target_->get_recursion_count(); } - virtual config to_side_context_config() const override { return target_->to_side_context_config(); } - private: - side_context *target_; + side_context* target_; }; - -class readonly_context_proxy : public virtual readonly_context, public virtual side_context_proxy { +class readonly_context_proxy : public virtual readonly_context, public virtual side_context_proxy +{ public: readonly_context_proxy() : target_(nullptr) { } - virtual ~readonly_context_proxy() {} + virtual ~readonly_context_proxy() + { + } - void init_readonly_context_proxy(readonly_context &target) + void init_readonly_context_proxy(readonly_context& target) { init_side_context_proxy(target); target_ = &target.get_readonly_context(); @@ -520,13 +513,11 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s return target_->get_readonly_context(); } - virtual void on_readonly_context_create() override { return target_->on_readonly_context_create(); } - virtual const team& current_team() const override { return target_->current_team(); @@ -542,55 +533,68 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s target_->log_message(msg); } - virtual attack_result_ptr check_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon) override + virtual attack_result_ptr check_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override { return target_->check_attack_action(attacker_loc, defender_loc, attacker_weapon); } - virtual move_result_ptr check_move_action(const map_location &from, const map_location &to, bool remove_movement=true, bool unreach_is_ok=false) override + virtual move_result_ptr check_move_action(const map_location& from, + const map_location& to, + bool remove_movement = true, + bool unreach_is_ok = false) override { return target_->check_move_action(from, to, remove_movement, unreach_is_ok); } - - virtual recall_result_ptr check_recall_action(const std::string &id, const map_location &where = map_location::null_location(), - const map_location &from = map_location::null_location()) override + virtual recall_result_ptr check_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override { return target_->check_recall_action(id, where, from); } - - virtual recruit_result_ptr check_recruit_action(const std::string &unit_name, const map_location &where = map_location::null_location(), - const map_location &from = map_location::null_location()) override + virtual recruit_result_ptr check_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override { return target_->check_recruit_action(unit_name, where, from); } - virtual stopunit_result_ptr check_stopunit_action(const map_location &unit_location, bool remove_movement = true, bool remove_attacks = false) override + virtual stopunit_result_ptr check_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override { return target_->check_stopunit_action(unit_location, remove_movement, remove_attacks); } - virtual synced_command_result_ptr check_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) override + virtual synced_command_result_ptr check_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) override { return target_->check_synced_command_action(lua_code, location); } - virtual void calculate_possible_moves(std::map& possible_moves, - move_map& srcdst, move_map& dstsrc, bool enemy, - bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr) const override + virtual void calculate_possible_moves(std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr) const override { - target_->calculate_possible_moves(possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations); + target_->calculate_possible_moves( + possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations); } virtual void calculate_moves(const unit_map& units, - std::map& possible_moves, move_map& srcdst, - move_map& dstsrc, bool enemy, bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr, - bool see_all=false) const override + std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr, + bool see_all = false) const override { - target_->calculate_moves(units, possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations, see_all); + target_->calculate_moves( + units, possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations, see_all); } virtual const game_info& get_info() const override @@ -603,7 +607,6 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s target_->raise_user_interact(); } - virtual int get_recursion_count() const override { return target_->get_recursion_count(); @@ -611,275 +614,229 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s //@note: following part is in alphabetic order const defensive_position& best_defensive_position(const map_location& unit, - const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const override + const move_map& dstsrc, + const move_map& srcdst, + const move_map& enemy_dstsrc) const override { - return target_->best_defensive_position(unit,dstsrc,srcdst,enemy_dstsrc); + return target_->best_defensive_position(unit, dstsrc, srcdst, enemy_dstsrc); } - - virtual std::map& defensive_position_cache() const override + virtual std::map& defensive_position_cache() const override { return target_->defensive_position_cache(); } - virtual const unit_advancements_aspect& get_advancements() const override { return target_->get_advancements(); } - virtual double get_aggression() const override { return target_->get_aggression(); } - virtual int get_attack_depth() const override { return target_->get_attack_depth(); } - virtual const aspect_map& get_aspects() const override { return target_->get_aspects(); } - virtual aspect_map& get_aspects() override { return target_->get_aspects(); } - - virtual void add_aspects(std::vector< aspect_ptr > &aspects ) override + virtual void add_aspects(std::vector& aspects) override { return target_->add_aspects(aspects); } - - virtual void add_facet(const std::string &id, const config &cfg) const override + virtual void add_facet(const std::string& id, const config& cfg) const override { - target_->add_facet(id,cfg); + target_->add_facet(id, cfg); } - - virtual const attacks_vector& get_attacks() const override { return target_->get_attacks(); } - - virtual const wfl::variant& get_attacks_as_variant() const override { return target_->get_attacks_as_variant(); } - virtual const terrain_filter& get_avoid() const override { return target_->get_avoid(); } - virtual double get_caution() const override { return target_->get_caution(); } - virtual const move_map& get_dstsrc() const override { return target_->get_dstsrc(); } - virtual const move_map& get_enemy_dstsrc() const override { return target_->get_enemy_dstsrc(); } - virtual const moves_map& get_enemy_possible_moves() const override { return target_->get_enemy_possible_moves(); } - virtual const move_map& get_enemy_srcdst() const override { return target_->get_enemy_srcdst(); } - - virtual engine_ptr get_engine_by_cfg(const config &cfg) override + virtual engine_ptr get_engine_by_cfg(const config& cfg) override { return target_->get_engine_by_cfg(cfg); } - virtual const std::vector& get_engines() const override { return target_->get_engines(); } - virtual std::vector& get_engines() override { return target_->get_engines(); } - virtual std::string get_grouping() const override { return target_->get_grouping(); } - virtual const std::vector& get_goals() const override { return target_->get_goals(); } - virtual std::vector& get_goals() override { return target_->get_goals(); } - virtual double get_leader_aggression() const override { return target_->get_leader_aggression(); } - - virtual config get_leader_goal() const override { return target_->get_leader_goal(); } - virtual bool get_leader_ignores_keep() const override { return target_->get_leader_ignores_keep(); } - virtual double get_leader_value() const override { return target_->get_leader_value(); } - virtual bool get_passive_leader() const override { return target_->get_passive_leader(); } - virtual bool get_passive_leader_shares_keep() const override { return target_->get_passive_leader_shares_keep(); } - virtual const moves_map& get_possible_moves() const override { return target_->get_possible_moves(); } - virtual double power_projection(const map_location& loc, const move_map& dstsrc) const override { - return target_->power_projection(loc,dstsrc); + return target_->power_projection(loc, dstsrc); } - virtual const std::vector& get_recall_list() const override { return target_->get_recall_list(); } - virtual double get_recruitment_diversity() const override { return target_->get_recruitment_diversity(); } - virtual const config get_recruitment_instructions() const override { return target_->get_recruitment_instructions(); } - virtual const std::vector get_recruitment_more() const override { return target_->get_recruitment_more(); } - virtual const std::vector get_recruitment_pattern() const override { return target_->get_recruitment_pattern(); } - virtual int get_recruitment_randomness() const override { return target_->get_recruitment_randomness(); } - virtual const config get_recruitment_save_gold() const override { return target_->get_recruitment_save_gold(); } - virtual const move_map& get_srcdst() const override { return target_->get_srcdst(); } - virtual double get_scout_village_targeting() const override { return target_->get_scout_village_targeting(); } - virtual bool get_simple_targeting() const override { return target_->get_simple_targeting(); } - virtual bool get_support_villages() const override { return target_->get_support_villages(); } - virtual double get_village_value() const override { return target_->get_village_value(); } - virtual int get_villages_per_scout() const override { return target_->get_villages_per_scout(); } - - - virtual bool is_active(const std::string &time_of_day, const std::string &turns) const override + virtual bool is_active(const std::string& time_of_day, const std::string& turns) const override { return target_->is_active(time_of_day, turns); } @@ -909,43 +866,36 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s return target_->invalidate_defensive_position_cache(); } - virtual void invalidate_move_maps() const override { target_->invalidate_move_maps(); } - virtual void invalidate_keeps_cache() const override { return target_->invalidate_keeps_cache(); } - virtual const std::set& keeps() const override { return target_->keeps(); } - virtual bool leader_can_reach_keep() const override { return target_->leader_can_reach_keep(); } - - virtual const map_location& nearest_keep( const map_location& loc ) const override + virtual const map_location& nearest_keep(const map_location& loc) const override { return target_->nearest_keep(loc); } - virtual void recalculate_move_maps() const override { target_->recalculate_move_maps(); } - virtual void recalculate_move_maps_enemy() const override { target_->recalculate_move_maps_enemy(); @@ -971,129 +921,127 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s target_->set_src_dst_enemy_valid_lua(); } - virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths ) const override + virtual const map_location& suitable_keep( + const map_location& leader_location, const pathfind::paths& leader_paths) const override { return target_->suitable_keep(leader_location, leader_paths); } - virtual config to_readonly_context_config() const override { return target_->to_readonly_context_config(); } - - virtual unit_stats_cache_t & unit_stats_cache() const override + virtual unit_stats_cache_t& unit_stats_cache() const override { return target_->unit_stats_cache(); } - private: - readonly_context *target_; + readonly_context* target_; }; - -class readwrite_context_proxy : public virtual readwrite_context, public virtual readonly_context_proxy { +class readwrite_context_proxy : public virtual readwrite_context, public virtual readonly_context_proxy +{ public: readwrite_context_proxy() : target_(nullptr) { } - - void init_readwrite_context_proxy(readwrite_context &target) + void init_readwrite_context_proxy(readwrite_context& target) { init_readonly_context_proxy(target); target_ = &target.get_readwrite_context(); } - virtual readwrite_context& get_readwrite_context() override { return target_->get_readwrite_context(); } - - virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override + virtual attack_result_ptr execute_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override { - return target_->execute_attack_action(attacker_loc,defender_loc,attacker_weapon); + return target_->execute_attack_action(attacker_loc, defender_loc, attacker_weapon); } - - virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true, bool unreach_is_ok=false) override + virtual move_result_ptr execute_move_action(const map_location& from, + const map_location& to, + bool remove_movement = true, + bool unreach_is_ok = false) override { return target_->execute_move_action(from, to, remove_movement, unreach_is_ok); } - - virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override + virtual recall_result_ptr execute_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override { - return target_->execute_recall_action(id,where,from); + return target_->execute_recall_action(id, where, from); } - - virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override + virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override { - return target_->execute_recruit_action(unit_name,where,from); + return target_->execute_recruit_action(unit_name, where, from); } - - virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override + virtual stopunit_result_ptr execute_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override { - return target_->execute_stopunit_action(unit_location,remove_movement,remove_attacks); + return target_->execute_stopunit_action(unit_location, remove_movement, remove_attacks); } - - virtual synced_command_result_ptr execute_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) override + virtual synced_command_result_ptr execute_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) override { - return target_->execute_synced_command_action(lua_code,location); + return target_->execute_synced_command_action(lua_code, location); } - virtual team& current_team_w() override { return target_->current_team_w(); } - virtual void raise_gamestate_changed() const override { target_->raise_gamestate_changed(); } - virtual game_info& get_info_w() override { return target_->get_info_w(); } - virtual int get_recursion_count() const override { return target_->get_recursion_count(); } - virtual config to_readwrite_context_config() const override { return target_->to_readwrite_context_config(); } private: - readwrite_context *target_; + readwrite_context* target_; }; - -//implementation -class side_context_impl : public side_context { +// implementation +class side_context_impl : public side_context +{ public: - side_context_impl(side_number side, const config &/*cfg*/) - : side_(side), recursion_counter_(0) + side_context_impl(side_number side, const config& /*cfg*/) + : side_(side) + , recursion_counter_(0) { } - virtual ~side_context_impl(){} + virtual ~side_context_impl() + { + } virtual side_number get_side() const override { @@ -1105,16 +1053,13 @@ class side_context_impl : public side_context { side_ = side; } - virtual side_context& get_side_context() override { return *this; } - virtual int get_recursion_count() const override; - virtual config to_side_context_config() const override; private: @@ -1122,51 +1067,41 @@ class side_context_impl : public side_context { recursion_counter recursion_counter_; }; - -class readonly_context_impl : public virtual side_context_proxy, public readonly_context, public events::observer { +class readonly_context_impl : public virtual side_context_proxy, public readonly_context, public events::observer +{ public: - /** * Constructor */ - readonly_context_impl(side_context &context, const config &cfg); - + readonly_context_impl(side_context& context, const config& cfg); /** * Destructor */ virtual ~readonly_context_impl(); - /** * Unwrap - this class is not a proxy, so return *this -:w */ virtual readonly_context& get_readonly_context() override { return *this; } - virtual void on_readonly_context_create() override; - /** Handle generic event */ virtual void handle_generic_event(const std::string& event_name) override; - /** Return a reference to the 'team' object for the AI. */ const team& current_team() const override; - /** Show a diagnostic message on the screen. */ void diagnostic(const std::string& msg) override; - /** Display a debug message as a chat message. */ void log_message(const std::string& msg) override; - /** * Check if it is possible to attack enemy defender using our unit attacker from attackers current location, * @param attacker_loc location of attacker @@ -1178,8 +1113,8 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible result: attacker and/or defender are invalid * @retval possible result: attacker doesn't have the specified weapon */ - attack_result_ptr check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override; - + attack_result_ptr check_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override; /** * Check if it is possible to move our unit from location 'from' to location 'to' @@ -1191,9 +1126,10 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible result: move is interrupted * @retval possible result: move is impossible */ - move_result_ptr check_move_action(const map_location& from, const map_location& to, bool remove_movement=true, bool unreach_is_ok=false) override; - - + move_result_ptr check_move_action(const map_location& from, + const map_location& to, + bool remove_movement = true, + bool unreach_is_ok = false) override; /** * Check if it is possible to recall a unit for us on specified location @@ -1205,8 +1141,9 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible_result: no free space on keep * @retval possible_result: not enough gold */ - recall_result_ptr check_recall_action(const std::string& id, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override; - + recall_result_ptr check_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override; /** * Check if it is possible to recruit a unit for us on specified location @@ -1218,8 +1155,9 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible_result: no free space on keep * @retval possible_result: not enough gold */ - recruit_result_ptr check_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override; - + recruit_result_ptr check_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override; /** * Check if it is possible to remove unit movements and/or attack @@ -1230,8 +1168,8 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible_result: something wrong * @retval possible_result: nothing to do */ - stopunit_result_ptr check_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override; - + stopunit_result_ptr check_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override; /** * Check if it is possible to run Lua code @@ -1241,8 +1179,8 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @retval possible_result: something wrong * @retval possible_result: nothing to do */ - synced_command_result_ptr check_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) override; - + synced_command_result_ptr check_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) override; /** * Calculate the moves units may possibly make. @@ -1268,10 +1206,12 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * @param remove_destinations a pointer to a terrain filter for possible destinations * to omit. */ - void calculate_possible_moves(std::map& possible_moves, - move_map& srcdst, move_map& dstsrc, bool enemy, - bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr) const override; + void calculate_possible_moves(std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr) const override; /** * A more fundamental version of calculate_possible_moves which allows the @@ -1281,11 +1221,13 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly * (See the todo in the implementation.) */ void calculate_moves(const unit_map& units, - std::map& possible_moves, move_map& srcdst, - move_map& dstsrc, bool enemy, bool assume_full_movement=false, - const terrain_filter* remove_destinations=nullptr, - bool see_all=false) const override; - + std::map& possible_moves, + move_map& srcdst, + move_map& dstsrc, + bool enemy, + bool assume_full_movement = false, + const terrain_filter* remove_destinations = nullptr, + bool see_all = false) const override; virtual const game_info& get_info() const override; @@ -1297,136 +1239,95 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly */ void raise_user_interact() const override; - virtual int get_recursion_count() const override; - //@note: following functions are in alphabetic order const defensive_position& best_defensive_position(const map_location& unit, - const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const override; - - - virtual std::map& defensive_position_cache() const override; + const move_map& dstsrc, + const move_map& srcdst, + const move_map& enemy_dstsrc) const override; + virtual std::map& defensive_position_cache() const override; virtual const unit_advancements_aspect& get_advancements() const override; - virtual double get_aggression() const override; - virtual int get_attack_depth() const override; - virtual const aspect_map& get_aspects() const override; - virtual aspect_map& get_aspects() override; - virtual const attacks_vector& get_attacks() const override; - virtual const wfl::variant& get_attacks_as_variant() const override; - virtual const terrain_filter& get_avoid() const override; - virtual double get_caution() const override; - virtual const move_map& get_dstsrc() const override; - virtual const move_map& get_enemy_dstsrc() const override; - virtual const moves_map& get_enemy_possible_moves() const override; - virtual const move_map& get_enemy_srcdst() const override; - virtual engine_ptr get_engine_by_cfg(const config& cfg) override; - virtual const std::vector& get_engines() const override; - virtual std::vector& get_engines() override; - virtual std::string get_grouping() const override; - virtual const std::vector& get_goals() const override; - virtual std::vector& get_goals() override; - virtual double get_leader_aggression() const override; - virtual config get_leader_goal() const override; - virtual bool get_leader_ignores_keep() const override; - virtual double get_leader_value() const override; - virtual bool get_passive_leader() const override; - virtual bool get_passive_leader_shares_keep() const override; - virtual const moves_map& get_possible_moves() const override; - virtual const std::vector& get_recall_list() const override; - virtual double get_recruitment_diversity() const override; - virtual const config get_recruitment_instructions() const override; - virtual const std::vector get_recruitment_more() const override; - virtual const std::vector get_recruitment_pattern() const override; - virtual int get_recruitment_randomness() const override; - virtual const config get_recruitment_save_gold() const override; - virtual double get_scout_village_targeting() const override; - virtual bool get_simple_targeting() const override; - virtual const move_map& get_srcdst() const override; - virtual bool get_support_villages() const override; - virtual double get_village_value() const override; - virtual int get_villages_per_scout() const override; - - virtual bool is_active(const std::string &time_of_day, const std::string &turns) const override; + virtual bool is_active(const std::string& time_of_day, const std::string& turns) const override; virtual bool is_dst_src_valid_lua() const override; @@ -1438,36 +1339,25 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly virtual void invalidate_defensive_position_cache() const override; - virtual void invalidate_move_maps() const override; - virtual void invalidate_keeps_cache() const override; - virtual const std::set& keeps() const override; - virtual bool leader_can_reach_keep() const override; - virtual const map_location& nearest_keep(const map_location& loc) const override; - virtual double power_projection(const map_location& loc, const move_map& dstsrc) const override; - virtual void recalculate_move_maps() const override; - virtual void recalculate_move_maps_enemy() const override; + virtual void add_aspects(std::vector& aspects) override; - virtual void add_aspects(std::vector< aspect_ptr > &aspects) override; - - - virtual void add_facet(const std::string &id, const config &cfg) const override; - + virtual void add_facet(const std::string& id, const config& cfg) const override; void on_create(); @@ -1479,72 +1369,90 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly virtual void set_src_dst_enemy_valid_lua() override; - virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths ) const override; - + virtual const map_location& suitable_keep( + const map_location& leader_location, const pathfind::paths& leader_paths) const override; virtual config to_readonly_context_config() const override; - - virtual unit_stats_cache_t & unit_stats_cache() const override; + virtual unit_stats_cache_t& unit_stats_cache() const override; private: template - void add_known_aspect(const std::string &name, typesafe_aspect_ptr& where); + void add_known_aspect(const std::string& name, typesafe_aspect_ptr& where); const config cfg_; /** * AI Support Engines */ - std::vector< engine_ptr > engines_; + std::vector engines_; known_aspect_map known_aspects_; typesafe_aspect_ptr advancements_; typesafe_aspect_ptr aggression_; typesafe_aspect_ptr attack_depth_; + aspect_map aspects_; + typesafe_aspect_ptr attacks_; + mutable typesafe_aspect_ptr avoid_; typesafe_aspect_ptr caution_; - mutable std::map defensive_position_cache_; + + mutable std::map defensive_position_cache_; mutable move_map dstsrc_; mutable move_map enemy_dstsrc_; mutable moves_map enemy_possible_moves_; mutable move_map enemy_srcdst_; + typesafe_aspect_ptr grouping_; - std::vector< goal_ptr > goals_; + + std::vector goals_; + mutable keeps_cache keeps_; + typesafe_aspect_ptr leader_aggression_; typesafe_aspect_ptr leader_goal_; typesafe_aspect_ptr leader_ignores_keep_; typesafe_aspect_ptr leader_value_; + mutable bool move_maps_enemy_valid_; mutable bool move_maps_valid_; mutable bool dst_src_valid_lua_; mutable bool dst_src_enemy_valid_lua_; mutable bool src_dst_valid_lua_; mutable bool src_dst_enemy_valid_lua_; + typesafe_aspect_ptr passive_leader_; typesafe_aspect_ptr passive_leader_shares_keep_; + mutable moves_map possible_moves_; + typesafe_aspect_ptr recruitment_diversity_; typesafe_aspect_ptr recruitment_instructions_; typesafe_aspect_ptr> recruitment_more_; typesafe_aspect_ptr> recruitment_pattern_; typesafe_aspect_ptr recruitment_randomness_; typesafe_aspect_ptr recruitment_save_gold_; + recursion_counter recursion_counter_; + typesafe_aspect_ptr scout_village_targeting_; typesafe_aspect_ptr simple_targeting_; + mutable move_map srcdst_; + typesafe_aspect_ptr support_villages_; + mutable unit_stats_cache_t unit_stats_cache_; + typesafe_aspect_ptr village_value_; typesafe_aspect_ptr villages_per_scout_; }; -class readwrite_context_impl : public virtual readonly_context_proxy, public readwrite_context { +class readwrite_context_impl : public virtual readonly_context_proxy, public readwrite_context +{ public: /** * Unwrap - this class is not a proxy, so return *this @@ -1554,7 +1462,6 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea return *this; } - /** * Ask the game to attack an enemy defender using our unit attacker from attackers current location, * @param attacker_loc location of attacker @@ -1566,8 +1473,8 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible result: attacker and/or defender are invalid * @retval possible result: attacker doesn't have the specified weapon */ - virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override; - + virtual attack_result_ptr execute_attack_action( + const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) override; /** * Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial move @@ -1579,8 +1486,10 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible result: move is interrupted * @retval possible result: move is impossible */ - virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true, bool unreach_is_ok=false) override; - + virtual move_result_ptr execute_move_action(const map_location& from, + const map_location& to, + bool remove_movement = true, + bool unreach_is_ok = false) override; /** * Ask the game to recall a unit for us on specified location @@ -1592,8 +1501,9 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible_result: no free space on keep * @retval possible_result: not enough gold */ - virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override; - + virtual recall_result_ptr execute_recall_action(const std::string& id, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override; /** * Ask the game to recruit a unit for us on specified location @@ -1605,8 +1515,9 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible_result: no free space on keep * @retval possible_result: not enough gold */ - virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location(), const map_location &from = map_location::null_location()) override; - + virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, + const map_location& where = map_location::null_location(), + const map_location& from = map_location::null_location()) override; /** * Ask the game to remove unit movements and/or attack @@ -1617,8 +1528,8 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible_result: something wrong * @retval possible_result: nothing to do */ - virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override; - + virtual stopunit_result_ptr execute_stopunit_action( + const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) override; /** * Ask the game to run Lua code @@ -1628,27 +1539,24 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea * @retval possible_result: something wrong * @retval possible_result: nothing to do */ - virtual synced_command_result_ptr execute_synced_command_action(const std::string& lua_code, const map_location& location = map_location::null_location()) override; - + virtual synced_command_result_ptr execute_synced_command_action( + const std::string& lua_code, const map_location& location = map_location::null_location()) override; /** Return a reference to the 'team' object for the AI. */ virtual team& current_team_w() override; - /** Notifies all interested observers of the event respectively. */ void raise_gamestate_changed() const override; - /** * Constructor. */ - readwrite_context_impl(readonly_context &context, const config &/*cfg*/) + readwrite_context_impl(readonly_context& context, const config& /*cfg*/) : recursion_counter_(context.get_recursion_count()) { init_readonly_context_proxy(context); } - virtual ~readwrite_context_impl() { } @@ -1659,15 +1567,12 @@ class readwrite_context_impl : public virtual readonly_context_proxy, public rea */ virtual game_info& get_info_w() override; - virtual int get_recursion_count() const override; - virtual config to_readwrite_context_config() const override; private: recursion_counter recursion_counter_; }; - -} //end of namespace ai +} // end of namespace ai