void ai_composite::on_create() { LOG_AI_COMPOSITE << "side "<< get_side() << " : "<<" created AI with id=["<< cfg_["id"]<<"]"<<std::endl; // init the composite ai stages for (const config &cfg_element : cfg_.child_range("stage")) { add_stage(cfg_element); } config cfg; cfg["engine"] = "fai"; engine_ptr e_ptr = get_engine_by_cfg(cfg); if (e_ptr) { e_ptr->set_ai_context(this); } std::function<void(std::vector<engine_ptr>&, const config&)> factory_engines = std::bind(&ai::ai_composite::create_engine,*this,_1,_2); std::function<void(std::vector<goal_ptr>&, const config&)> factory_goals = std::bind(&ai::ai_composite::create_goal,*this,_1,_2); std::function<void(std::vector<stage_ptr>&, const config&)> factory_stages = std::bind(&ai::ai_composite::create_stage,*this,_1,_2); std::function<void(std::map<std::string,aspect_ptr>&, const config&, std::string)> factory_aspects = std::bind(&ai::ai_composite::replace_aspect,*this,_1,_2,_3); register_vector_property(property_handlers(),"engine",get_engines(), factory_engines); register_vector_property(property_handlers(),"goal",get_goals(), factory_goals); register_vector_property(property_handlers(),"stage",stages_, factory_stages); register_aspect_property(property_handlers(),"aspect",get_aspects(), factory_aspects); }
bool ai_composite::add_goal(const config &cfg) { std::vector< goal_ptr > goals; create_goal(goals,cfg); int j=0; for (goal_ptr b : goals) { get_goals().push_back(b); j++; } return (j>0); }
void readonly_context_impl::on_readonly_context_create() { //init the composite ai engines foreach(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 foreach(const config &cfg_element, cfg_.child_range("aspect")){ std::vector<aspect_ptr> aspects; engine::parse_aspect_from_config(*this,cfg_element,cfg_element["id"],std::back_inserter(aspects)); add_aspects(aspects); } // init the composite ai goals foreach(const config &cfg_element, cfg_.child_range("goal")){ engine::parse_goal_from_config(*this,cfg_element,std::back_inserter(get_goals())); } }
std::vector<target> default_ai_context_impl::find_targets(const move_map& enemy_dstsrc) { log_scope2(log_ai, "finding targets..."); unit_map &units_ = resources::gameboard->units(); unit_map::iterator leader = units_.find_leader(get_side()); const gamemap &map_ = resources::gameboard->map(); std::vector<team> teams_ = resources::gameboard->teams(); const bool has_leader = leader != units_.end(); std::vector<target> targets; //=== start getting targets //if enemy units are in range of the leader, then we target the enemies who are in range. if(has_leader) { double threat = power_projection(leader->get_location(), enemy_dstsrc); if(threat > 0.0) { //find the location of enemy threats std::set<map_location> threats; map_location adj[6]; get_adjacent_tiles(leader->get_location(), adj); for(size_t n = 0; n != 6; ++n) { std::pair<move_map::const_iterator,move_map::const_iterator> itors = enemy_dstsrc.equal_range(adj[n]); while(itors.first != itors.second) { if(units_.count(itors.first->second)) { threats.insert(itors.first->second); } ++itors.first; } } assert(threats.empty() == false); const double value = threat/double(threats.size()); for(std::set<map_location>::const_iterator i = threats.begin(); i != threats.end(); ++i) { LOG_AI << "found threat target... " << *i << " with value: " << value << "\n"; targets.push_back(target(*i,value,target::TYPE::THREAT)); } } } double corner_distance = distance_between(map_location::ZERO(), map_location(map_.w(),map_.h())); double village_value = get_village_value(); if(has_leader && village_value > 0.0) { std::map<map_location,pathfind::paths> friends_possible_moves; move_map friends_srcdst, friends_dstsrc; calculate_possible_moves(friends_possible_moves, friends_srcdst, friends_dstsrc, false, true); const std::vector<map_location>& villages = map_.villages(); for(std::vector<map_location>::const_iterator t = villages.begin(); t != villages.end(); ++t) { assert(map_.on_board(*t)); bool ally_village = false; for (size_t i = 0; i != teams_.size(); ++i) { if (!current_team().is_enemy(i + 1) && teams_[i].owns_village(*t)) { ally_village = true; break; } } if (ally_village) { //Support seems to cause the AI to just 'sit around' a lot, so //only turn it on if it's explicitly enabled. if(get_support_villages()) { double enemy = power_projection(*t, enemy_dstsrc); if (enemy > 0) { enemy *= 1.7; double our = power_projection(*t, friends_dstsrc); double value = village_value * our / enemy; add_target(target(*t, value, target::TYPE::SUPPORT)); } } } else { double leader_distance = distance_between(*t, leader->get_location()); double value = village_value * (1.0 - leader_distance / corner_distance); LOG_AI << "found village target... " << *t << " with value: " << value << " distance: " << leader_distance << '\n'; targets.push_back(target(*t,value,target::TYPE::VILLAGE)); } } } std::vector<goal_ptr>& goals = get_goals(); //find the enemy leaders and explicit targets unit_map::const_iterator u; if (get_leader_value()>0.0) { for(u = units_.begin(); u != units_.end(); ++u) { //is a visible enemy leader if (u->can_recruit() && current_team().is_enemy(u->side()) && !u->invisible(u->get_location(), *resources::gameboard)) { assert(map_.on_board(u->get_location())); LOG_AI << "found enemy leader (side: " << u->side() << ") target... " << u->get_location() << " with value: " << get_leader_value() << "\n"; targets.push_back(target(u->get_location(), get_leader_value(), target::TYPE::LEADER)); } } } //explicit targets for this team for(std::vector<goal_ptr>::iterator j = goals.begin(); j != goals.end(); ++j) { if (!(*j)->active()) { continue; } (*j)->add_targets(std::back_inserter(targets)); } //=== end getting targets std::vector<double> new_values; for(std::vector<target>::iterator i = targets.begin(); i != targets.end(); ++i) { new_values.push_back(i->value); for(std::vector<target>::const_iterator j = targets.begin(); j != targets.end(); ++j) { if(i->loc == j->loc) { continue; } const double distance = std::abs(j->loc.x - i->loc.x) + std::abs(j->loc.y - i->loc.y); new_values.back() += j->value/(distance*distance); } } assert(new_values.size() == targets.size()); for(size_t n = 0; n != new_values.size(); ++n) { LOG_AI << "target value: " << targets[n].value << " -> " << new_values[n] << "\n"; targets[n].value = new_values[n]; } return targets; }