38 #include <boost/dynamic_bitset.hpp>
40 #include <SDL2/SDL_timer.h>
43 #define DBG_AI_TESTING_AI_DEFAULT LOG_STREAM(debug, log_ai_testing_ai_default)
44 #define LOG_AI_TESTING_AI_DEFAULT LOG_STREAM(info, log_ai_testing_ai_default)
45 #define WRN_AI_TESTING_AI_DEFAULT LOG_STREAM(warn, log_ai_testing_ai_default)
46 #define ERR_AI_TESTING_AI_DEFAULT LOG_STREAM(err, log_ai_testing_ai_default)
50 namespace ai_default_rca {
67 std::vector<map_location> gotos;
72 if (ui->get_goto() == ui->get_location()) {
75 gotos.push_back(ui->get_location());
79 for(std::vector<map_location>::const_iterator
g = gotos.begin();
g != gotos.end(); ++
g) {
96 route =
pathfind::a_star_search(ui->get_location(), ui->get_goto(), 10000.0, calc, map_.
w(), map_.
h(), &allowed_teleports);
98 if (!route.
steps.empty()){
105 int closest_distance = -1;
106 std::pair<map_location,map_location> closest_move;
108 if(
i->second != ui->get_location()) {
112 if(closest_distance == -1 || distance < closest_distance) {
113 closest_distance = distance;
117 if(closest_distance != -1) {
124 if (
move_->is_ok()) {
139 if (!
move_->is_ok()){
146 if (!
move_->is_gamestate_changed()){
170 int ticks = SDL_GetTicks();
172 const std::vector<attack_analysis> analysis =
get_attacks();
174 int time_taken = SDL_GetTicks() - ticks;
176 <<
" positions. Analyzing...";
178 ticks = SDL_GetTicks();
180 const int max_sims = 50000;
181 int num_sims = analysis.empty() ? 0 : max_sims/analysis.size();
189 const int max_positions = 30000;
190 const int skip_num = analysis.size()/max_positions;
192 std::vector<attack_analysis>::const_iterator choice_it = analysis.end();
193 for(std::vector<attack_analysis>::const_iterator it = analysis.begin();
194 it != analysis.end(); ++it) {
196 if(skip_num > 0 && ((it - analysis.begin())%skip_num) && it->movements.size() > 1)
204 bool skip_attack =
false;
205 for(std::size_t
i = 0;
i != it->movements.size(); ++
i) {
225 time_taken = SDL_GetTicks() - ticks;
248 if (!move_res->is_ok()) {
255 if (!attack_res->is_ok()) {
258 attack_res->execute();
259 if (!attack_res->is_ok()) {
299 if (leaders.empty()) {
303 const unit* leader =
nullptr;
305 if (!l_itor->incapacitated() && l_itor->movement_left() > 0 &&
is_allowed_unit(*l_itor)) {
311 if (leader ==
nullptr) {
323 if (
move_->is_ok()) {
335 if(route.
steps.empty()) {
342 std::map<map_location,pathfind::paths> possible_moves;
343 possible_moves.emplace(leader->
get_location(), leader_paths);
357 if (
move_->is_ok()) {
368 if (!
move_->is_ok()){
383 mod_ai[
"path"] =
"aspect[leader_goal].facet["+
id+
"]";
384 mod_ai[
"action"] =
"delete";
417 if (leaders.empty()) {
422 const unit* best_leader =
nullptr;
424 int shortest_distance = 99999;
433 const ai::moves_map::const_iterator& p_it = possible_moves.find(leader->get_location());
434 if (p_it == possible_moves.end()) {
451 if (!route.
steps.empty() || route.
move_cost < shortest_distance) {
452 best_leader = &(*leader);
458 if (best_leader ==
nullptr) {
463 const unit* leader = best_leader;
471 if (
move_->is_ok()) {
481 typedef std::multimap<int, map_location> ordered_locations;
482 ordered_locations moves_toward_keep;
489 int next_hop_cost = 0;
500 moves_toward_keep.emplace(0, next_hop);
514 for (
const ordered_locations::value_type& pair : moves_toward_keep) {
518 if (
move_->is_ok()) {
529 if (!
move_->is_ok()) {
567 std::pair<map_location,map_location> leader_move;
569 for(tmoves::const_iterator
i =
moves_.begin();
i !=
moves_.end(); ++
i) {
571 if(leader != units_.
end() && leader->get_location() ==
i->second) {
576 if (!move_res->is_ok()) {
584 if (new_unit != units_.
end() &&
593 if(leader_move.second.valid()) {
597 if (!move_res->is_ok()) {
612 const int ticks = SDL_GetTicks();
614 if(leader != units_.
end()) {
627 u_itor != units_.
end(); ++u_itor) {
632 reachmap.emplace(u_itor->get_location(), std::vector<map_location>());
641 while(itor != reachmap.end()) {
642 if(itor->second.empty()) {
649 if(!reachmap.empty()) {
651 "can't reach a village, send the to the dispatcher.";
661 <<
" ms, resulted in " <<
moves_.size() <<
" units being dispatched.";
668 const std::multimap<map_location,map_location>& dstsrc,
669 const std::multimap<map_location,map_location>& enemy_dstsrc)
672 std::map<map_location, double> vulnerability;
674 std::size_t min_distance = 100000;
680 std::vector<map_location> dispatched_units;
681 for(std::multimap<map_location, map_location>::const_iterator
683 j != dstsrc.end(); ++j) {
689 if(distance < min_distance) {
690 min_distance = distance;
695 if(std::find(dispatched_units.begin(), dispatched_units.end(),
696 j->second) != dispatched_units.end()) {
704 bool want_village =
true, owned =
false;
705 for(std::size_t
n = 0;
n != teams_.size(); ++
n) {
706 owned = teams_[
n].owns_village(current_loc);
708 want_village =
false;
716 if(want_village ==
false) {
727 const std::map<map_location,double>::const_iterator vuln = vulnerability.find(current_loc);
728 if(vuln != vulnerability.end()) {
729 threat = vuln->second;
732 vulnerability.emplace(current_loc, threat);
750 std::multimap<map_location, map_location>::const_iterator next = j;
752 const bool at_begin = (j == dstsrc.begin());
753 std::multimap<map_location, map_location>::const_iterator
prev = j;
758 if((next == dstsrc.end() || next->first != current_loc)
759 && (at_begin ||
prev->first != current_loc)) {
762 if (move_check_res->is_ok()) {
764 moves.emplace_back(j->first, j->second);
766 reachmap.erase(j->second);
767 dispatched_units.push_back(j->second);
771 reachmap[j->second].push_back(current_loc);
775 << reachmap.size() <<
" left to evaluate.";
789 std::size_t village_count = 0;
790 bool dispatched =
true;
797 if(reachmap.empty()) {
808 if(reachmap.empty()) {
816 if(!reachmap.empty() && dispatched) {
823 if(reachmap.empty()) {
829 << village_count <<
" villages left.";
843 while(itor != reachmap.end()) {
844 if(itor->second.size() == 1) {
849 moves.emplace_back(village, itor->first);
850 reachmap.erase(itor++);
853 itor = reachmap.begin();
862 if(reachmap.empty()) {
867 if(reachmap.size() == 1) {
870 <<
" to village " << reachmap.begin()->second[0];
872 moves.emplace_back(reachmap.begin()->second[0], reachmap.begin()->first);
887 bool dispatched =
true;
895 treachmap::const_iterator itor = reachmap.begin();
896 for(;itor != reachmap.end(); ++itor) {
898 for(std::vector<map_location>::const_iterator
899 v_itor = itor->second.begin();
900 v_itor != itor->second.end(); ++v_itor) {
902 reversemap[*v_itor].push_back(itor->first);
907 village_count = reversemap.size();
909 itor = reversemap.begin();
910 while(itor != reversemap.end()) {
911 if(itor->second.size() == 1) {
918 moves.emplace_back(itor->first, itor->second[0]);
920 reachmap.erase(itor->second[0]);
939 while(itor != reachmap.end()) {
940 itor->second.erase(
std::remove(itor->second.begin(), itor->second.end(), village), itor->second.end());
941 if(itor->second.empty()) {
954 assert(
unit->second.empty());
963 reachmap.erase(
unit++);
972 const std::size_t unit_count = reachmap.size();
974 const std::size_t max_result = unit_count < village_count ? unit_count : village_count;
976 assert(unit_count >= 2 && village_count >= 2);
979 if(unit_count == 2 && village_count == 2) {
985 std::vector<map_location> units(unit_count);
986 std::vector<std::size_t> villages_per_unit(unit_count);
987 std::vector<map_location> villages;
988 std::vector<std::size_t> units_per_village(village_count);
992 std::multimap<std::size_t ,
993 std::size_t > unit_lookup;
995 std::vector<
boost::dynamic_bitset<>> matrix(reachmap.size(), boost::dynamic_bitset<>(village_count));
997 treachmap::const_iterator itor = reachmap.begin();
998 for(std::size_t u = 0; u < unit_count; ++u, ++itor) {
999 units[u] = itor->first;
1000 villages_per_unit[u] = itor->second.size();
1001 unit_lookup.emplace(villages_per_unit[u], u);
1003 assert(itor->second.size() >= 2);
1005 for(std::size_t v = 0; v < itor->second.size(); ++v) {
1007 std::size_t v_index;
1009 std::vector<map_location>::const_iterator v_itor =
1010 std::find(villages.begin(), villages.end(), itor->second[v]);
1011 if(v_itor == villages.end()) {
1012 v_index = villages.size();
1013 villages.push_back(itor->second[v]);
1015 v_index = v_itor - villages.begin();
1018 units_per_village[v_index]++;
1020 matrix[u][v_index] =
true;
1023 for(std::vector<std::size_t>::const_iterator upv_it = units_per_village.begin();
1024 upv_it != units_per_village.end(); ++upv_it) {
1026 assert(*upv_it >=2);
1033 for(v = 0; v < village_count; ++v) {
1039 for(u = 0; u < unit_count; ++u) {
1042 for(v = 0; v < village_count; ++v) {
1050 for(v = 0; v < village_count; ++v) {
1057 const bool reach_all = ((village_count == unit_count)
1058 && (std::accumulate(villages_per_unit.begin(), villages_per_unit.end(), std::size_t())
1059 == (village_count * unit_count)));
1069 std::multimap<std::size_t , std::size_t >
1070 ::const_iterator src_itor = unit_lookup.begin();
1072 while(src_itor != unit_lookup.end() && src_itor->first == 2) {
1074 for(std::multimap<std::size_t, std::size_t>::const_iterator
1075 dst_itor = unit_lookup.begin();
1076 dst_itor != unit_lookup.end(); ++ dst_itor) {
1079 if(src_itor == dst_itor) {
1083 boost::dynamic_bitset<> result = matrix[src_itor->second] & matrix[dst_itor->second];
1084 std::size_t matched = result.count();
1089 std::size_t first = result.find_first();
1090 std::size_t second = result.find_next(first);
1095 const bool perfect = (src_itor->first == 2 &&
1096 dst_itor->first == 2 &&
1097 units_per_village[first] == 2 &&
1098 units_per_village[second] == 2);
1102 <<
" to village " << village1;
1103 moves.emplace_back(village1, units[src_itor->second]);
1106 <<
" to village " << village2;
1107 moves.emplace_back(village2, units[dst_itor->second]);
1110 reachmap.erase(units[src_itor->second]);
1111 reachmap.erase(units[dst_itor->second]);
1143 std::vector<std::pair<map_location, map_location>> best_result;
1151 const std::size_t max_options = 8;
1152 if(unit_count >= max_options && village_count >= max_options) {
1155 << village_count<<
" found, evaluate only the first "
1156 << max_options <<
" options;";
1158 std::vector<std::size_t> perm (max_options, 0);
1159 for(std::size_t
i =0;
i < max_options; ++
i) {
1162 while(std::next_permutation(perm.begin(), perm.end())) {
1165 std::vector<std::pair<map_location,map_location>> result;
1166 for(std::size_t u = 0; u < max_options; ++u) {
1167 if(matrix[u][perm[u]]) {
1168 result.emplace_back(villages[perm[u]], units[u]);
1172 if(result.size() == max_result) {
1173 best_result.swap(result);
1177 if(result.size() > best_result.size()) {
1178 best_result.swap(result);
1182 moves.insert(moves.end(), best_result.begin(), best_result.end());
1185 for(
const auto& unit_village_pair : best_result) {
1186 reachmap.erase(unit_village_pair.second);
1193 }
else if(unit_count <= village_count) {
1197 std::vector<std::size_t> perm (unit_count, 0);
1198 for(std::size_t
i =0;
i < unit_count; ++
i) {
1201 while(std::next_permutation(perm.begin(), perm.end())) {
1203 std::vector<std::pair<map_location,map_location>> result;
1204 for(std::size_t u = 0; u < unit_count; ++u) {
1205 if(matrix[u][perm[u]]) {
1206 result.emplace_back(villages[perm[u]], units[u]);
1210 if(result.size() == max_result) {
1211 moves.insert(moves.end(), result.begin(), result.end());
1216 if(result.size() > best_result.size()) {
1217 best_result.swap(result);
1221 moves.insert(moves.end(), best_result.begin(), best_result.end());
1225 for(
const auto& unit_village_pair : best_result) {
1226 reachmap.erase(unit_village_pair.second);
1229 if(
unit != reachmap.end()) {
1230 unit->second.clear();
1239 std::vector<std::size_t> perm (village_count, 0);
1240 for(std::size_t
i =0;
i < village_count; ++
i) {
1243 while(std::next_permutation(perm.begin(), perm.end())) {
1245 std::vector<std::pair<map_location,map_location>> result;
1246 for(std::size_t v = 0; v < village_count; ++v) {
1247 if(matrix[perm[v]][v]) {
1248 result.emplace_back(villages[v], units[perm[v]]);
1252 if(result.size() == max_result) {
1253 moves.insert(moves.end(), result.begin(), result.end());
1258 if(result.size() > best_result.size()) {
1259 best_result.swap(result);
1263 moves.insert(moves.end(), best_result.begin(), best_result.end());
1267 for(
const auto& unit_village_pair : best_result) {
1268 reachmap.erase(unit_village_pair.second);
1271 if(
unit != reachmap.end()) {
1272 unit->second.clear();
1281 treachmap::const_iterator itor = reachmap.begin();
1282 for(std::size_t
i = 0;
i < reachmap.size(); ++
i, ++itor) {
1284 <<
" to village " << itor->second[
i];
1285 moves.emplace_back(itor->second[
i], itor->first);
1295 for(treachmap::const_iterator itor =
1296 reachmap.begin(); itor != reachmap.end(); ++itor) {
1300 if(itor->second.empty()) {
1304 for(std::vector<map_location>::const_iterator
1305 v_itor = itor->second.begin();
1306 v_itor != itor->second.end(); ++v_itor) {
1330 for(; u_it != units_.
end(); ++u_it) {
1346 typedef std::multimap<map_location,map_location>::const_iterator Itor;
1347 std::pair<Itor,Itor> it =
get_srcdst().equal_range(u_it->get_location());
1348 double best_vulnerability = 100000.0;
1350 const double leader_penalty = (u.
can_recruit()?2.0:1.0);
1351 Itor best_loc = it.second;
1352 while(it.first != it.second) {
1357 if(vuln < best_vulnerability) {
1358 best_vulnerability = vuln;
1359 best_loc = it.first;
1369 if(best_loc != it.second && best_vulnerability*leader_penalty < u.
hitpoints()) {
1371 if (
move_->is_ok()) {
1385 if (!
move_->is_ok()){
1409 std::map<map_location,pathfind::paths> dummy_possible_moves;
1416 std::vector<map_location> leaders_adj_v;
1427 leaders_adj_v.push_back(loc);
1435 i->movement_left() ==
i->total_movement() &&
1437 std::find(leaders.begin(), leaders.end(),
i) == leaders.end() &&
1445 bool can_reach_leader =
false;
1451 typedef move_map::const_iterator Itor;
1452 std::pair<Itor,Itor> itors =
get_srcdst().equal_range(
i->get_location());
1455 double best_rating = -1000.0;
1456 int best_defensive_rating =
i->defense_modifier(
resources::gameboard->map().get_terrain(
i->get_location()))
1458 while(itors.first != itors.second) {
1462 if(std::find(leaders_adj_v.begin(), leaders_adj_v.end(), itors.first->second) != leaders_adj_v.end()){
1464 can_reach_leader =
true;
1475 const double rating = our_power - their_power;
1476 if(rating > best_rating) {
1478 best_rating = rating;
1484 if(modified_defense < best_defensive_rating) {
1485 best_defensive_rating = modified_defense;
1486 best_defensive = hex;
1494 if(can_reach_leader) {
1498 if(!best_pos.
valid()) {
1499 best_pos = best_defensive;
1502 if(best_pos.
valid()) {
1504 if (
move_->is_ok()) {
1518 if (!
move_->is_ok()){
1527 if(caution <= 0.0) {
1533 const double proposed_terrain =
1538 const double exposure = proposed_terrain - optimal_terrain;
1542 return caution*their_power*(1.0+exposure) > our_power;
1580 bool have_active_leader =
false;
1584 have_active_leader =
true;
1588 if(!have_active_leader) {
1592 bool allied_leaders_available =
false;
1596 if (!allied_leaders.empty()){
1597 allied_leaders_available =
true;
1602 if(allied_leaders_available){
1614 typedef std::map<map_location, pathfind::paths> path_map;
1615 path_map possible_moves;
1616 move_map friends_srcdst, friends_dstsrc;
1634 bool friend_can_reach_keep =
false;
1637 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1639 assert(itor.
valid());
1642 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1643 if(tokeep !=
i->second.destinations.end()){
1644 friend_can_reach_keep =
true;
1650 if(friend_can_reach_keep){
1653 int defense_modifier = 100;
1654 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1655 ;
i != possible_moves[keep].destinations.end()
1660 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1663 if(tmp_def_mod < defense_modifier){
1664 defense_modifier = tmp_def_mod;
1665 best_move =
i->curr;
1670 if(defense_modifier < 100){
1674 if (!move->is_ok()){
1677 ai_leader->set_goto(keep);
1681 possible_moves.clear();
1688 ai_leader->remove_movement_ai();
Managing the AI-Game interaction - AI actions and their results.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
#define DBG_AI_TESTING_AI_DEFAULT
#define WRN_AI_TESTING_AI_DEFAULT
static lg::log_domain log_ai_testing_ai_default("ai/ca/testing_ai_default")
#define ERR_AI_TESTING_AI_DEFAULT
#define LOG_AI_TESTING_AI_DEFAULT
virtual void execute()
Execute the candidate action.
attack_analysis best_analysis_
combat_phase(rca_context &context, const config &cfg)
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()
Execute the candidate action.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
get_healing_phase(rca_context &context, const config &cfg)
virtual ~get_healing_phase()
void dump_reachmap(treachmap &reachmap)
Shows which villages every unit can reach (debug function).
bool dispatch_village_simple(treachmap &reachmap, tmoves &moves, std::size_t &village_count)
get_villages_phase(rca_context &context, const config &cfg)
map_location keep_loc_
Location of the keep the closest to our leader.
treachmap::iterator remove_unit(treachmap &reachmap, tmoves &moves, treachmap::iterator unit)
Removes a unit which can't reach any village anymore.
virtual ~get_villages_phase()
map_location leader_loc_
Locaton of our leader.
bool dispatch_unit_simple(treachmap &reachmap, tmoves &moves)
Dispatches all units who can reach one village.
std::map< map_location, std::vector< map_location > > treachmap
void dispatch(treachmap &reachmap, tmoves &moves)
Dispatches all units to their best location.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
void dispatch_complex(treachmap &reachmap, tmoves &moves, const std::size_t village_count)
Dispatches the units to a village after the simple dispatching failed.
bool debug_
debug log level for AI enabled?
bool remove_village(treachmap &reachmap, tmoves &moves, const map_location &village)
Removes a village for all units, returns true if anything is deleted.
void find_villages(treachmap &reachmap, tmoves &moves, const std::multimap< map_location, map_location > &dstsrc, const std::multimap< map_location, map_location > &enemy_dstsrc)
virtual void execute()
Execute the candidate action.
void full_dispatch(treachmap &reachmap, tmoves &moves)
Dispatches all units to a village, every unit can reach every village.
void get_villages(const move_map &dstsrc, const move_map &enemy_dstsrc, unit_map::const_iterator &leader)
std::vector< std::pair< map_location, map_location > > tmoves
map_location best_leader_loc_
The best possible location for our leader if it can't reach a village.
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()
Execute the candidate action.
goto_phase(rca_context &context, const config &cfg)
leader_control_phase(rca_context &context, const config &cfg)
virtual ~leader_control_phase()
virtual void execute()
Execute the candidate action.
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.
virtual ~leader_shares_keep_phase()
leader_shares_keep_phase(rca_context &context, const config &cfg)
virtual void execute()
Execute the candidate action.
move_leader_to_goals_phase(rca_context &context, const config &cfg)
virtual void execute()
Execute the candidate action.
virtual ~move_leader_to_goals_phase()
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
void remove_goal(const std::string &id)
move_leader_to_keep_phase(rca_context &context, const config &cfg)
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()
Execute the candidate action.
virtual ~move_leader_to_keep_phase()
bool should_retreat(const map_location &loc, const unit_map::const_iterator &un, const move_map &srcdst, const move_map &dstsrc, double caution)
retreat_phase(rca_context &context, const config &cfg)
virtual double evaluate()
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()
Execute the candidate action.
std::vector< std::pair< map_location, map_location > > movements
static const double BAD_SCORE
virtual std::string get_name() const
Get the name of the candidate action (useful for debug purposes)
bool is_allowed_unit(const unit &u) const
Flag indicating whether unit may be used by this candidate action.
double get_score() const
Get the usual score of the candidate action without re-evaluation.
static manager & get_singleton()
void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
virtual double get_caution() const override
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...
virtual config get_leader_goal() const override
virtual const team & current_team() const override
virtual bool is_keep_ignoring_leader(const std::string &id) const override
virtual bool is_passive_keep_sharing_leader(const std::string &id) const override
virtual const map_location & nearest_keep(const map_location &loc) const override
virtual const move_map & get_dstsrc() const override
virtual const terrain_filter & get_avoid() const override
virtual const attacks_vector & get_attacks() 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
virtual const move_map & get_srcdst() const override
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 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
virtual bool is_passive_leader(const std::string &id) const override
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.
virtual const std::vector< std::string > get_recruitment_pattern() const 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
virtual double get_aggression() const override
virtual stopunit_result_ptr check_stopunit_action(const map_location &unit_location, bool remove_movement=true, bool remove_attacks=false) override
virtual double get_leader_aggression() const override
virtual const move_map & get_enemy_dstsrc() const override
virtual attack_result_ptr check_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon) override
virtual const moves_map & get_possible_moves() const 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
virtual side_number get_side() const override
Get the side number.
A config object defines a single node in a WML file, with access to child nodes.
virtual const std::vector< team > & teams() const override
virtual const unit_map & units() const override
virtual const gamemap & map() const override
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
int w() const
Effective map width.
int h() const
Effective map height.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Encapsulates the map of the game.
bool is_village(const map_location &loc) const
bool dont_log(const log_domain &domain) const
This class stores all the data for a single 'side' (in game nomenclature).
int minimum_recruit_price() const
Container associating units to locations.
std::vector< unit_iterator > find_leaders(int side)
std::size_t count(const map_location &loc) const
unit_iterator find(std::size_t id)
unit_iterator find_leader(int side)
This class represents a single unit of a specific type.
AI Support engine - creating specific ai components from config.
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.
int max_hitpoints() const
The max number of hitpoints this unit can have.
int hitpoints() const
The current number of hitpoints this unit has.
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
@ STATE_POISONED
The unit is slowed - it moves slower and does less damage.
int defense_modifier(const t_translation::terrain_code &terrain) const
The unit's defense on a given terrain.
const map_location & get_location() const
The current map location this unit is at.
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit's movement cost on a particular terrain.
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
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.
Standard logging facilities (interface).
boost::dynamic_bitset<> dynamic_bitset
A small explanation about what's going on here: Each action has access to two game_info objects First...
std::shared_ptr< attack_result > attack_result_ptr
std::shared_ptr< stopunit_result > stopunit_result_ptr
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.
std::shared_ptr< move_result > move_result_ptr
void remove()
Removes a tip.
map_location find_vacant_castle(const unit &leader)
Wrapper for find_vacant_tile() when looking for a vacant castle tile near a leader.
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)
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
std::string::const_iterator iterator
This module contains various pathfinding functions and utilities.
candidate action framework
Encapsulates the map of the game.
static const map_location & null_location()
bool contains(const map_location &) const
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Structure which holds a single route between one location and another.
std::vector< map_location > steps
int move_cost
Movement cost for reaching the end of the route.
static map_location::DIRECTION n