37 #include <boost/dynamic_bitset.hpp> 39 #include <SDL2/SDL_timer.h> 42 #define DBG_AI_TESTING_AI_DEFAULT LOG_STREAM(debug, log_ai_testing_ai_default) 43 #define LOG_AI_TESTING_AI_DEFAULT LOG_STREAM(info, log_ai_testing_ai_default) 44 #define WRN_AI_TESTING_AI_DEFAULT LOG_STREAM(warn, log_ai_testing_ai_default) 45 #define ERR_AI_TESTING_AI_DEFAULT LOG_STREAM(err, log_ai_testing_ai_default) 49 namespace ai_default_rca {
66 std::vector<map_location> gotos;
71 if (ui->get_goto() == ui->get_location()) {
74 gotos.push_back(ui->get_location());
78 for(std::vector<map_location>::const_iterator
g = gotos.begin();
g != gotos.end(); ++
g) {
95 route =
pathfind::a_star_search(ui->get_location(), ui->get_goto(), 10000.0, calc, map_.
w(), map_.
h(), &allowed_teleports);
97 if (!route.
steps.empty()){
104 int closest_distance = -1;
105 std::pair<map_location,map_location> closest_move;
107 if(
i->second != ui->get_location()) {
111 if(closest_distance == -1 || distance < closest_distance) {
112 closest_distance = distance;
116 if(closest_distance != -1) {
123 if (
move_->is_ok()) {
138 if (!
move_->is_ok()){
145 if (!
move_->is_gamestate_changed()){
169 int ticks = SDL_GetTicks();
171 const std::vector<attack_analysis> analysis =
get_attacks();
173 int time_taken = SDL_GetTicks() - ticks;
175 <<
" positions. Analyzing...\n";
177 ticks = SDL_GetTicks();
179 const int max_sims = 50000;
180 int num_sims = analysis.empty() ? 0 : max_sims/analysis.size();
188 const int max_positions = 30000;
189 const int skip_num = analysis.size()/max_positions;
191 std::vector<attack_analysis>::const_iterator choice_it = analysis.end();
192 for(std::vector<attack_analysis>::const_iterator it = analysis.begin();
193 it != analysis.end(); ++it) {
195 if(skip_num > 0 && ((it - analysis.begin())%skip_num) && it->movements.size() > 1)
203 bool skip_attack =
false;
204 for(std::size_t
i = 0;
i != it->movements.size(); ++
i) {
224 time_taken = SDL_GetTicks() - ticks;
247 if (!move_res->is_ok()) {
254 if (!attack_res->is_ok()) {
257 attack_res->execute();
258 if (!attack_res->is_ok()) {
291 double max_risk = goal[
"max_risk"].to_double(1 -
get_caution());
302 if (leaders.empty()) {
306 const unit* leader =
nullptr;
308 if (!l_itor->incapacitated() && l_itor->movement_left() > 0 &&
is_allowed_unit(*l_itor)) {
314 if (leader ==
nullptr) {
319 id_ = goal[
"id"].str();
326 if (
move_->is_ok()) {
338 if(route.
steps.empty()) {
345 std::map<map_location,pathfind::paths> possible_moves;
346 possible_moves.emplace(leader->
get_location(), leader_paths);
360 if (
move_->is_ok()) {
371 if (!
move_->is_ok()){
386 mod_ai[
"path"] =
"aspect[leader_goal].facet["+
id+
"]";
387 mod_ai[
"action"] =
"delete";
420 if (leaders.empty()) {
425 const unit* best_leader =
nullptr;
427 int shortest_distance = 99999;
436 const ai::moves_map::const_iterator& p_it = possible_moves.find(leader->get_location());
437 if (p_it == possible_moves.end()) {
454 if (!route.
steps.empty() || route.
move_cost < shortest_distance) {
455 best_leader = &(*leader);
461 if (best_leader ==
nullptr) {
466 const unit* leader = best_leader;
474 if (
move_->is_ok()) {
484 typedef std::multimap<int, map_location> ordered_locations;
485 ordered_locations moves_toward_keep;
492 int next_hop_cost = 0;
503 moves_toward_keep.emplace(0, next_hop);
517 for (
const ordered_locations::value_type& pair : moves_toward_keep) {
521 if (
move_->is_ok()) {
532 if (!
move_->is_ok()) {
570 std::pair<map_location,map_location> leader_move;
572 for(tmoves::const_iterator
i =
moves_.begin();
i !=
moves_.end(); ++
i) {
574 if(leader != units_.
end() && leader->get_location() ==
i->second) {
579 if (!move_res->is_ok()) {
587 if (new_unit != units_.
end() &&
596 if(leader_move.second.valid()) {
600 if (!move_res->is_ok()) {
615 const int ticks = SDL_GetTicks();
617 if(leader != units_.
end()) {
630 u_itor != units_.
end(); ++u_itor) {
635 reachmap.emplace(u_itor->get_location(), std::vector<map_location>());
644 while(itor != reachmap.end()) {
645 if(itor->second.empty()) {
652 if(!reachmap.empty()) {
654 "can't reach a village, send the to the dispatcher.\n";
664 <<
" ms, resulted in " <<
moves_.size() <<
" units being dispatched.\n";
671 const std::multimap<map_location,map_location>& dstsrc,
672 const std::multimap<map_location,map_location>& enemy_dstsrc)
675 std::map<map_location, double> vulnerability;
677 std::size_t min_distance = 100000;
683 std::vector<map_location> dispatched_units;
684 for(std::multimap<map_location, map_location>::const_iterator
686 j != dstsrc.end(); ++j) {
692 if(distance < min_distance) {
693 min_distance = distance;
698 if(std::find(dispatched_units.begin(), dispatched_units.end(),
699 j->second) != dispatched_units.end()) {
707 bool want_village =
true, owned =
false;
708 for(std::size_t
n = 0;
n != teams_.size(); ++
n) {
709 owned = teams_[
n].owns_village(current_loc);
711 want_village =
false;
719 if(want_village ==
false) {
730 const std::map<map_location,double>::const_iterator vuln = vulnerability.find(current_loc);
731 if(vuln != vulnerability.end()) {
732 threat = vuln->second;
735 vulnerability.emplace(current_loc, threat);
753 std::multimap<map_location, map_location>::const_iterator
next = j;
755 const bool at_begin = (j == dstsrc.begin());
756 std::multimap<map_location, map_location>::const_iterator
prev = j;
761 if((next == dstsrc.end() || next->first != current_loc)
762 && (at_begin || prev->first != current_loc)) {
765 if (move_check_res->is_ok()) {
767 moves.emplace_back(j->first, j->second);
769 reachmap.erase(j->second);
770 dispatched_units.push_back(j->second);
774 reachmap[j->second].push_back(current_loc);
778 << reachmap.size() <<
" left to evaluate.\n";
792 std::size_t village_count = 0;
793 bool dispatched =
true;
800 if(reachmap.empty()) {
811 if(reachmap.empty()) {
819 if(!reachmap.empty() && dispatched) {
826 if(reachmap.empty()) {
832 << village_count <<
" villages left.\n";
846 while(itor != reachmap.end()) {
847 if(itor->second.size() == 1) {
852 moves.emplace_back(village, itor->first);
853 reachmap.erase(itor++);
856 itor = reachmap.begin();
865 if(reachmap.empty()) {
870 if(reachmap.size() == 1) {
873 <<
" to village " << reachmap.begin()->second[0] <<
'\n';
875 moves.emplace_back(reachmap.begin()->second[0], reachmap.begin()->first);
890 bool dispatched =
true;
896 std::vector<map_location >>reversemap;
898 treachmap::const_iterator itor = reachmap.begin();
899 for(;itor != reachmap.end(); ++itor) {
901 for(std::vector<map_location>::const_iterator
902 v_itor = itor->second.begin();
903 v_itor != itor->second.end(); ++v_itor) {
905 reversemap[*v_itor].push_back(itor->first);
910 village_count = reversemap.size();
912 itor = reversemap.begin();
913 while(itor != reversemap.end()) {
914 if(itor->second.size() == 1) {
916 const map_location village = itor->first;
921 moves.emplace_back(itor->first, itor->second[0]);
923 reachmap.erase(itor->second[0]);
942 while(itor != reachmap.end()) {
943 itor->second.erase(
std::remove(itor->second.begin(), itor->second.end(), village), itor->second.end());
944 if(itor->second.empty()) {
957 assert(unit->second.empty());
966 reachmap.erase(unit++);
975 const std::size_t unit_count = reachmap.size();
977 const std::size_t max_result = unit_count < village_count ? unit_count : village_count;
979 assert(unit_count >= 2 && village_count >= 2);
982 if(unit_count == 2 && village_count == 2) {
988 std::vector<map_location> units(unit_count);
989 std::vector<std::size_t> villages_per_unit(unit_count);
990 std::vector<map_location> villages;
991 std::vector<std::size_t> units_per_village(village_count);
995 std::multimap<std::size_t ,
996 std::size_t > unit_lookup;
998 std::vector<
boost::dynamic_bitset<>> matrix(reachmap.size(), boost::dynamic_bitset<>(village_count));
1000 treachmap::const_iterator itor = reachmap.begin();
1001 for(std::size_t u = 0; u < unit_count; ++u, ++itor) {
1002 units[u] = itor->first;
1003 villages_per_unit[u] = itor->second.size();
1004 unit_lookup.emplace(villages_per_unit[u], u);
1006 assert(itor->second.size() >= 2);
1008 for(std::size_t v = 0; v < itor->second.size(); ++v) {
1010 std::size_t v_index;
1012 std::vector<map_location>::const_iterator v_itor =
1013 std::find(villages.begin(), villages.end(), itor->second[v]);
1014 if(v_itor == villages.end()) {
1015 v_index = villages.size();
1016 villages.push_back(itor->second[v]);
1018 v_index = v_itor - villages.begin();
1021 units_per_village[v_index]++;
1023 matrix[u][v_index] =
true;
1026 for(std::vector<std::size_t>::const_iterator upv_it = units_per_village.begin();
1027 upv_it != units_per_village.end(); ++upv_it) {
1029 assert(*upv_it >=2);
1034 std::cerr <<
"Reach matrix:\n\nvillage";
1036 for(v = 0; v < village_count; ++v) {
1037 std::cerr <<
'\t' << villages[v];
1039 std::cerr <<
"\ttotal\nunit\n";
1042 for(u = 0; u < unit_count; ++u) {
1043 std::cerr << units[u];
1045 for(v = 0; v < village_count; ++v) {
1046 std::cerr <<
'\t' << matrix[u][v];
1048 std::cerr <<
"\t" << villages_per_unit[u] <<
'\n';
1052 std::cerr <<
"total";
1053 for(v = 0; v < village_count; ++v) {
1054 std::cerr <<
'\t' << units_per_village[v];
1060 const bool reach_all = ((village_count == unit_count)
1061 && (std::accumulate(villages_per_unit.begin(), villages_per_unit.end(), std::size_t())
1062 == (village_count * unit_count)));
1072 std::multimap<std::size_t , std::size_t >
1073 ::const_iterator src_itor = unit_lookup.begin();
1075 while(src_itor != unit_lookup.end() && src_itor->first == 2) {
1077 for(std::multimap<std::size_t, std::size_t>::const_iterator
1078 dst_itor = unit_lookup.begin();
1079 dst_itor != unit_lookup.end(); ++ dst_itor) {
1082 if(src_itor == dst_itor) {
1086 boost::dynamic_bitset<> result = matrix[src_itor->second] & matrix[dst_itor->second];
1087 std::size_t matched = result.count();
1092 std::size_t first = result.find_first();
1093 std::size_t second = result.find_next(first);
1098 const bool perfect = (src_itor->first == 2 &&
1099 dst_itor->first == 2 &&
1100 units_per_village[first] == 2 &&
1101 units_per_village[second] == 2);
1105 <<
" to village " << village1 <<
'\n';
1106 moves.emplace_back(village1, units[src_itor->second]);
1109 <<
" to village " << village2 <<
'\n';
1110 moves.emplace_back(village2, units[dst_itor->second]);
1113 reachmap.erase(units[src_itor->second]);
1114 reachmap.erase(units[dst_itor->second]);
1146 std::vector<std::pair<map_location, map_location>> best_result;
1154 const std::size_t max_options = 8;
1155 if(unit_count >= max_options && village_count >= max_options) {
1158 << village_count<<
" found, evaluate only the first " 1159 << max_options <<
" options;\n";
1161 std::vector<std::size_t> perm (max_options, 0);
1162 for(std::size_t
i =0;
i < max_options; ++
i) {
1165 while(std::next_permutation(perm.begin(), perm.end())) {
1168 std::vector<std::pair<map_location,map_location>> result;
1169 for(std::size_t u = 0; u < max_options; ++u) {
1170 if(matrix[u][perm[u]]) {
1171 result.emplace_back(villages[perm[u]], units[u]);
1175 if(result.size() == max_result) {
1176 best_result.swap(result);
1180 if(result.size() > best_result.size()) {
1181 best_result.swap(result);
1185 moves.insert(moves.end(), best_result.begin(), best_result.end());
1188 for(
const auto& unit_village_pair : best_result) {
1189 reachmap.erase(unit_village_pair.second);
1196 }
else if(unit_count <= village_count) {
1200 std::vector<std::size_t> perm (unit_count, 0);
1201 for(std::size_t
i =0;
i < unit_count; ++
i) {
1204 while(std::next_permutation(perm.begin(), perm.end())) {
1206 std::vector<std::pair<map_location,map_location>> result;
1207 for(std::size_t u = 0; u < unit_count; ++u) {
1208 if(matrix[u][perm[u]]) {
1209 result.emplace_back(villages[perm[u]], units[u]);
1213 if(result.size() == max_result) {
1214 moves.insert(moves.end(), result.begin(), result.end());
1219 if(result.size() > best_result.size()) {
1220 best_result.swap(result);
1224 moves.insert(moves.end(), best_result.begin(), best_result.end());
1228 for(
const auto& unit_village_pair : best_result) {
1229 reachmap.erase(unit_village_pair.second);
1232 if(unit != reachmap.end()) {
1233 unit->second.clear();
1242 std::vector<std::size_t> perm (village_count, 0);
1243 for(std::size_t
i =0;
i < village_count; ++
i) {
1246 while(std::next_permutation(perm.begin(), perm.end())) {
1248 std::vector<std::pair<map_location,map_location>> result;
1249 for(std::size_t v = 0; v < village_count; ++v) {
1250 if(matrix[perm[v]][v]) {
1251 result.emplace_back(villages[v], units[perm[v]]);
1255 if(result.size() == max_result) {
1256 moves.insert(moves.end(), result.begin(), result.end());
1261 if(result.size() > best_result.size()) {
1262 best_result.swap(result);
1266 moves.insert(moves.end(), best_result.begin(), best_result.end());
1270 for(
const auto& unit_village_pair : best_result) {
1271 reachmap.erase(unit_village_pair.second);
1274 if(unit != reachmap.end()) {
1275 unit->second.clear();
1284 treachmap::const_iterator itor = reachmap.begin();
1285 for(std::size_t
i = 0;
i < reachmap.size(); ++
i, ++itor) {
1287 <<
" to village " << itor->second[
i] <<
'\n';
1288 moves.emplace_back(itor->second[
i], itor->first);
1298 for(treachmap::const_iterator itor =
1299 reachmap.begin(); itor != reachmap.end(); ++itor) {
1301 std::cerr <<
"Reachlist for unit at " << itor->first;
1303 if(itor->second.empty()) {
1304 std::cerr <<
"\tNone";
1307 for(std::vector<map_location>::const_iterator
1308 v_itor = itor->second.begin();
1309 v_itor != itor->second.end(); ++v_itor) {
1311 std::cerr <<
'\t' << *v_itor;
1334 for(; u_it != units_.
end(); ++u_it) {
1350 typedef std::multimap<map_location,map_location>::const_iterator Itor;
1351 std::pair<Itor,Itor> it =
get_srcdst().equal_range(u_it->get_location());
1352 double best_vulnerability = 100000.0;
1354 const double leader_penalty = (u.
can_recruit()?2.0:1.0);
1355 Itor best_loc = it.second;
1356 while(it.first != it.second) {
1361 if(vuln < best_vulnerability) {
1362 best_vulnerability = vuln;
1363 best_loc = it.first;
1373 if(best_loc != it.second && best_vulnerability*leader_penalty < u.
hitpoints()) {
1375 if (
move_->is_ok()) {
1389 if (!
move_->is_ok()){
1413 std::map<map_location,pathfind::paths> dummy_possible_moves;
1420 std::vector<map_location> leaders_adj_v;
1431 leaders_adj_v.push_back(loc);
1439 i->movement_left() ==
i->total_movement() &&
1441 std::find(leaders.begin(), leaders.end(),
i) == leaders.end() &&
1449 bool can_reach_leader =
false;
1455 typedef move_map::const_iterator Itor;
1456 std::pair<Itor,Itor> itors =
get_srcdst().equal_range(
i->get_location());
1459 double best_rating = -1000.0;
1460 int best_defensive_rating =
i->defense_modifier(
resources::gameboard->map().get_terrain(
i->get_location()))
1462 while(itors.first != itors.second) {
1466 if(std::find(leaders_adj_v.begin(), leaders_adj_v.end(), itors.first->second) != leaders_adj_v.end()){
1468 can_reach_leader =
true;
1479 const double rating = our_power - their_power;
1480 if(rating > best_rating) {
1482 best_rating = rating;
1488 if(modified_defense < best_defensive_rating) {
1489 best_defensive_rating = modified_defense;
1490 best_defensive = hex;
1498 if(can_reach_leader) {
1502 if(!best_pos.
valid()) {
1503 best_pos = best_defensive;
1506 if(best_pos.
valid()) {
1508 if (
move_->is_ok()) {
1522 if (!
move_->is_ok()){
1531 if(caution <= 0.0) {
1536 srcdst, enemy_dstsrc).chance_to_hit/100.0;
1537 const double proposed_terrain =
1542 const double exposure = proposed_terrain - optimal_terrain;
1546 return caution*their_power*(1.0+exposure) > our_power;
1584 bool have_active_leader =
false;
1588 have_active_leader =
true;
1592 if(!have_active_leader) {
1596 bool allied_leaders_available =
false;
1600 if (!allied_leaders.empty()){
1601 allied_leaders_available =
true;
1606 if(allied_leaders_available){
1618 typedef std::map<map_location, pathfind::paths> path_map;
1619 path_map possible_moves;
1620 move_map friends_srcdst, friends_dstsrc;
1638 bool friend_can_reach_keep =
false;
1641 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1643 assert(itor.
valid());
1645 if(itor !=
resources::gameboard->units().end() && itor->can_recruit() && itor->side() !=
get_side() && (leader_team.total_income() + leader_team.gold() > leader_team.minimum_recruit_price())){
1646 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1647 if(tokeep !=
i->second.destinations.end()){
1648 friend_can_reach_keep =
true;
1654 if(friend_can_reach_keep){
1657 int defense_modifier = 100;
1658 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1659 ;
i != possible_moves[keep].destinations.end()
1664 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1667 if(tmp_def_mod < defense_modifier){
1668 defense_modifier = tmp_def_mod;
1669 best_move =
i->curr;
1674 if(defense_modifier < 100){
1678 if (!move->is_ok()){
1681 ai_leader->set_goto(keep);
1685 possible_moves.clear();
1692 ai_leader->remove_movement_ai();
void remove()
Removes a tip.
virtual void execute()
Execute the candidate action.
virtual void execute()
Execute the candidate action.
virtual attack_result_ptr check_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon) override
std::vector< unit_iterator > find_leaders(int side)
virtual const attacks_vector & get_attacks() const override
virtual const std::vector< team > & teams() const override
std::vector< std::pair< map_location, map_location > > tmoves
std::shared_ptr< stopunit_result > stopunit_result_ptr
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
virtual const unit_map & units() const override
virtual const map_location & nearest_keep(const map_location &loc) const override
This class represents a single unit of a specific type.
void dispatch(treachmap &reachmap, tmoves &moves)
Dispatches all units to their best location.
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit's movement cost on a particular terrain.
map_location find_vacant_castle(const unit &leader)
Wrapper for find_vacant_tile() when looking for a vacant castle tile near a leader.
goto_phase(rca_context &context, const config &cfg)
static manager & get_singleton()
map_location best_leader_loc_
The best possible location for our leader if it can't reach a village.
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
virtual stopunit_result_ptr check_stopunit_action(const map_location &unit_location, bool remove_movement=true, bool remove_attacks=false) override
unit_iterator find_leader(int side)
void dump_reachmap(treachmap &reachmap)
Shows which villages every unit can reach (debug function).
Managing the AI-Game interaction - AI actions and their results.
int hitpoints() const
The current number of hitpoints this unit has.
leader_shares_keep_phase(rca_context &context, const config &cfg)
map_location keep_loc_
Location of the keep the closest to our leader.
virtual const move_map & get_srcdst() const override
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
std::shared_ptr< move_result > move_result_ptr
virtual ~move_leader_to_keep_phase()
virtual const gamemap & map() const override
The unit is slowed - it moves slower and does less damage.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
AI Support engine - creating specific ai components from config.
virtual ~move_leader_to_goals_phase()
std::shared_ptr< attack_result > attack_result_ptr
move_leader_to_keep_phase(rca_context &context, const config &cfg)
retreat_phase(rca_context &context, const config &cfg)
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
#define ERR_AI_TESTING_AI_DEFAULT
bool remove_village(treachmap &reachmap, tmoves &moves, const map_location &village)
Removes a village for all units, returns true if anything is deleted.
virtual void execute()
Execute the candidate action.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
std::multimap< map_location, map_location > move_map
The standard way in which a map of possible moves is recorded.
std::map< map_location, pathfind::paths > moves_map
The standard way in which a map of possible movement routes to location is recorded.
int defense_modifier(const t_translation::terrain_code &terrain) const
The unit's defense on a given terrain.
This class stores all the data for a single 'side' (in game nomenclature).
static lg::log_domain log_ai_testing_ai_default("ai/ca/testing_ai_default")
A small explanation about what's going on here: Each action has access to two game_info objects First...
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
const std::string & id() const
Gets this unit's id.
std::vector< map_location > steps
bool should_retreat(const map_location &loc, const unit_map::const_iterator &un, const move_map &srcdst, const move_map &dstsrc, double caution)
virtual void execute()
Execute the candidate action.
int w() const
Effective map width.
Structure which holds a single route between one location and another.
void dispatch_complex(treachmap &reachmap, tmoves &moves, const std::size_t village_count)
Dispatches the units to a village after the simple dispatching failed.
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
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
bool is_allowed_unit(const unit &u) const
Flag indicating whether unit may be used by this candidate action.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual double get_leader_aggression() const override
boost::dynamic_bitset<> dynamic_bitset
Encapsulates the map of the game.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
bool is_enemy(int n) const
virtual bool is_passive_leader(const std::string &id) const override
virtual const move_map & get_enemy_dstsrc() const override
leader_control_phase(rca_context &context, const config &cfg)
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands...
virtual const std::vector< std::string > get_recruitment_pattern() const override
std::size_t count(const map_location &loc) const
void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
bool dont_log(const log_domain &domain) const
int move_cost
Movement cost for reaching the end of the route.
#define DBG_AI_TESTING_AI_DEFAULT
bool dispatch_village_simple(treachmap &reachmap, tmoves &moves, std::size_t &village_count)
Encapsulates the map of the game.
map_location leader_loc_
Locaton of our leader.
unit_iterator find(std::size_t id)
virtual ~leader_control_phase()
get_healing_phase(rca_context &context, const config &cfg)
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Checks whether this unit currently possesses or is affected by a given ability.
bool debug_
debug log level for AI enabled?
virtual const map_location & suitable_keep(const map_location &leader_location, const pathfind::paths &leader_paths) const override
get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return near...
bool dispatch_unit_simple(treachmap &reachmap, tmoves &moves)
Dispatches all units who can reach one village.
virtual const team & current_team() const override
int max_hitpoints() const
The max number of hitpoints this unit can have.
virtual ~leader_shares_keep_phase()
virtual ~get_villages_phase()
std::vector< std::pair< map_location, map_location > > movements
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
virtual double power_projection(const map_location &loc, const move_map &dstsrc) const override
Function which finds how much 'power' a side can attack a certain location with.
#define LOG_AI_TESTING_AI_DEFAULT
virtual void execute()
Execute the candidate action.
virtual side_number get_side() const override
Get the side number.
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
bool on_board(const map_location &loc) const
Tell if a location is on the map.
std::map< map_location, std::vector< map_location > > treachmap
virtual bool is_passive_keep_sharing_leader(const std::string &id) const override
virtual std::string get_name() const
Get the name of the candidate action (useful for debug purposes)
void get_villages(const move_map &dstsrc, const move_map &enemy_dstsrc, unit_map::const_iterator &leader)
virtual ~get_healing_phase()
void full_dispatch(treachmap &reachmap, tmoves &moves)
Dispatches all units to a village, every unit can reach every village.
treachmap::iterator remove_unit(treachmap &reachmap, tmoves &moves, treachmap::iterator unit)
Removes a unit which can't reach any village anymore.
bool is_village(const map_location &loc) const
virtual const move_map & get_dstsrc() const override
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
get_villages_phase(rca_context &context, const config &cfg)
virtual double get_aggression() const override
virtual void execute()
Execute the candidate action.
virtual void calculate_possible_moves(std::map< map_location, pathfind::paths > &possible_moves, move_map &srcdst, move_map &dstsrc, bool enemy, bool assume_full_movement=false, const terrain_filter *remove_destinations=nullptr) const override
const map_location & get_location() const
The current map location this unit is at.
bool contains(const map_location &) const
Standard logging facilities (interface).
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
Object which contains all the possible locations a unit can move to, with associated best routes to t...
static const map_location & null_location()
static const double BAD_SCORE
Container associating units to locations.
virtual bool is_keep_ignoring_leader(const std::string &id) const override
virtual void calculate_moves(const unit_map &units, std::map< map_location, pathfind::paths > &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
int side() const
The side this unit belongs to.
virtual const terrain_filter & get_avoid() const override
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()
Execute the candidate action.
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
A config object defines a single node in a WML file, with access to child nodes.
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
combat_phase(rca_context &context, const config &cfg)
virtual double get_caution() const override
static map_location::DIRECTION n
double get_score() const
Get the usual score of the candidate action without re-evaluation.
int h() const
Effective map height.
virtual void execute()
Execute the candidate action.
virtual void execute()
Execute the candidate action.
#define WRN_AI_TESTING_AI_DEFAULT
This module contains various pathfinding functions and utilities.
void remove_goal(const std::string &id)
virtual const moves_map & get_possible_moves() const override
std::string::const_iterator iterator
virtual config get_leader_goal() const override
void find_villages(treachmap &reachmap, tmoves &moves, const std::multimap< map_location, map_location > &dstsrc, const std::multimap< map_location, map_location > &enemy_dstsrc)
move_leader_to_goals_phase(rca_context &context, const config &cfg)
candidate action framework
attack_analysis best_analysis_