37 #include <SDL2/SDL_timer.h>
40 #define DBG_AI_TESTING_AI_DEFAULT LOG_STREAM(debug, log_ai_testing_ai_default)
41 #define LOG_AI_TESTING_AI_DEFAULT LOG_STREAM(info, log_ai_testing_ai_default)
42 #define WRN_AI_TESTING_AI_DEFAULT LOG_STREAM(warn, log_ai_testing_ai_default)
43 #define ERR_AI_TESTING_AI_DEFAULT LOG_STREAM(err, log_ai_testing_ai_default)
47 namespace ai_default_rca {
64 std::vector<map_location> gotos;
69 if (ui->get_goto() == ui->get_location()) {
72 gotos.push_back(ui->get_location());
76 for(std::vector<map_location>::const_iterator
g = gotos.begin();
g != gotos.end(); ++
g) {
93 route =
pathfind::a_star_search(ui->get_location(), ui->get_goto(), 10000.0, calc, map_.
w(), map_.
h(), &allowed_teleports);
95 if (!route.
steps.empty()){
102 int closest_distance = -1;
103 std::pair<map_location,map_location> closest_move;
105 if(
i->second != ui->get_location()) {
109 if(closest_distance == -1 || distance < closest_distance) {
110 closest_distance = distance;
114 if(closest_distance != -1) {
121 if (
move_->is_ok()) {
136 if (!
move_->is_ok()){
143 if (!
move_->is_gamestate_changed()){
167 int ticks = SDL_GetTicks();
169 const std::vector<attack_analysis> analysis =
get_attacks();
171 int time_taken = SDL_GetTicks() - ticks;
173 <<
" positions. Analyzing...";
175 ticks = SDL_GetTicks();
177 const int max_sims = 50000;
178 int num_sims = analysis.empty() ? 0 : max_sims/analysis.size();
186 const int max_positions = 30000;
187 const int skip_num = analysis.size()/max_positions;
189 std::vector<attack_analysis>::const_iterator choice_it = analysis.end();
190 for(std::vector<attack_analysis>::const_iterator it = analysis.begin();
191 it != analysis.end(); ++it) {
193 if(skip_num > 0 && ((it - analysis.begin())%skip_num) && it->movements.size() > 1)
201 bool skip_attack =
false;
202 for(std::size_t
i = 0;
i != it->movements.size(); ++
i) {
222 time_taken = SDL_GetTicks() - ticks;
245 if (!move_res->is_ok()) {
252 if (!attack_res->is_ok()) {
255 attack_res->execute();
256 if (!attack_res->is_ok()) {
296 if (leaders.empty()) {
300 const unit* leader =
nullptr;
302 if (!l_itor->incapacitated() && l_itor->movement_left() > 0 &&
is_allowed_unit(*l_itor)) {
308 if (leader ==
nullptr) {
320 if (
move_->is_ok()) {
332 if(route.
steps.empty()) {
339 std::map<map_location,pathfind::paths> possible_moves;
340 possible_moves.emplace(leader->
get_location(), leader_paths);
354 if (
move_->is_ok()) {
365 if (!
move_->is_ok()){
380 mod_ai[
"path"] =
"aspect[leader_goal].facet["+
id+
"]";
381 mod_ai[
"action"] =
"delete";
414 if (leaders.empty()) {
419 const unit* best_leader =
nullptr;
421 int shortest_distance = 99999;
430 const ai::moves_map::const_iterator& p_it = possible_moves.find(leader->get_location());
431 if (p_it == possible_moves.end()) {
448 if (!route.
steps.empty() || route.
move_cost < shortest_distance) {
449 best_leader = &(*leader);
455 if (best_leader ==
nullptr) {
460 const unit* leader = best_leader;
468 if (
move_->is_ok()) {
478 typedef std::multimap<int, map_location> ordered_locations;
479 ordered_locations moves_toward_keep;
486 int next_hop_cost = 0;
497 moves_toward_keep.emplace(0, next_hop);
511 for (
const ordered_locations::value_type& pair : moves_toward_keep) {
515 if (
move_->is_ok()) {
526 if (!
move_->is_ok()) {
564 std::pair<map_location,map_location> leader_move;
566 for(tmoves::const_iterator
i =
moves_.begin();
i !=
moves_.end(); ++
i) {
568 if(leader != units_.
end() && leader->get_location() ==
i->second) {
573 if (!move_res->is_ok()) {
581 if (new_unit != units_.
end() &&
590 if(leader_move.second.valid()) {
594 if (!move_res->is_ok()) {
609 const int ticks = SDL_GetTicks();
611 if(leader != units_.
end()) {
624 u_itor != units_.
end(); ++u_itor) {
629 reachmap.emplace(u_itor->get_location(), std::vector<map_location>());
638 while(itor != reachmap.end()) {
639 if(itor->second.empty()) {
646 if(!reachmap.empty()) {
648 "can't reach a village, send the to the dispatcher.";
658 <<
" ms, resulted in " <<
moves_.size() <<
" units being dispatched.";
665 const std::multimap<map_location,map_location>& dstsrc,
666 const std::multimap<map_location,map_location>& enemy_dstsrc)
669 std::map<map_location, double> vulnerability;
671 std::size_t min_distance = 100000;
677 std::vector<map_location> dispatched_units;
678 for(std::multimap<map_location, map_location>::const_iterator
680 j != dstsrc.end(); ++j) {
686 if(distance < min_distance) {
687 min_distance = distance;
692 if(std::find(dispatched_units.begin(), dispatched_units.end(),
693 j->second) != dispatched_units.end()) {
701 bool want_village =
true, owned =
false;
702 for(std::size_t
n = 0;
n != teams_.size(); ++
n) {
703 owned = teams_[
n].owns_village(current_loc);
705 want_village =
false;
713 if(want_village ==
false) {
724 const std::map<map_location,double>::const_iterator vuln = vulnerability.find(current_loc);
725 if(vuln != vulnerability.end()) {
726 threat = vuln->second;
729 vulnerability.emplace(current_loc, threat);
747 std::multimap<map_location, map_location>::const_iterator next = j;
749 const bool at_begin = (j == dstsrc.begin());
750 std::multimap<map_location, map_location>::const_iterator
prev = j;
755 if((next == dstsrc.end() || next->first != current_loc)
756 && (at_begin ||
prev->first != current_loc)) {
759 if (move_check_res->is_ok()) {
761 moves.emplace_back(j->first, j->second);
763 reachmap.erase(j->second);
764 dispatched_units.push_back(j->second);
768 reachmap[j->second].push_back(current_loc);
772 << reachmap.size() <<
" left to evaluate.";
786 std::size_t village_count = 0;
787 bool dispatched =
true;
794 if(reachmap.empty()) {
805 if(reachmap.empty()) {
813 if(!reachmap.empty() && dispatched) {
820 if(reachmap.empty()) {
826 << village_count <<
" villages left.";
840 while(itor != reachmap.end()) {
841 if(itor->second.size() == 1) {
846 moves.emplace_back(village, itor->first);
847 reachmap.erase(itor++);
850 itor = reachmap.begin();
859 if(reachmap.empty()) {
864 if(reachmap.size() == 1) {
867 <<
" to village " << reachmap.begin()->second[0];
869 moves.emplace_back(reachmap.begin()->second[0], reachmap.begin()->first);
884 bool dispatched =
true;
892 treachmap::const_iterator itor = reachmap.begin();
893 for(;itor != reachmap.end(); ++itor) {
895 for(std::vector<map_location>::const_iterator
896 v_itor = itor->second.begin();
897 v_itor != itor->second.end(); ++v_itor) {
899 reversemap[*v_itor].push_back(itor->first);
904 village_count = reversemap.size();
906 itor = reversemap.begin();
907 while(itor != reversemap.end()) {
908 if(itor->second.size() == 1) {
915 moves.emplace_back(itor->first, itor->second[0]);
917 reachmap.erase(itor->second[0]);
936 while(itor != reachmap.end()) {
937 itor->second.erase(
std::remove(itor->second.begin(), itor->second.end(), village), itor->second.end());
938 if(itor->second.empty()) {
951 assert(
unit->second.empty());
960 reachmap.erase(
unit++);
969 const std::size_t unit_count = reachmap.size();
971 const std::size_t max_result = unit_count < village_count ? unit_count : village_count;
973 assert(unit_count >= 2 && village_count >= 2);
976 if(unit_count == 2 && village_count == 2) {
982 std::vector<map_location> units(unit_count);
983 std::vector<std::size_t> villages_per_unit(unit_count);
984 std::vector<map_location> villages;
985 std::vector<std::size_t> units_per_village(village_count);
989 std::multimap<std::size_t ,
990 std::size_t > unit_lookup;
992 std::vector<
boost::dynamic_bitset<>> matrix(reachmap.size(), boost::dynamic_bitset<>(village_count));
994 treachmap::const_iterator itor = reachmap.begin();
995 for(std::size_t u = 0; u < unit_count; ++u, ++itor) {
996 units[u] = itor->first;
997 villages_per_unit[u] = itor->second.size();
998 unit_lookup.emplace(villages_per_unit[u], u);
1000 assert(itor->second.size() >= 2);
1002 for(std::size_t v = 0; v < itor->second.size(); ++v) {
1004 std::size_t v_index;
1006 std::vector<map_location>::const_iterator v_itor =
1007 std::find(villages.begin(), villages.end(), itor->second[v]);
1008 if(v_itor == villages.end()) {
1009 v_index = villages.size();
1010 villages.push_back(itor->second[v]);
1012 v_index = v_itor - villages.begin();
1015 units_per_village[v_index]++;
1017 matrix[u][v_index] =
true;
1020 for(std::vector<std::size_t>::const_iterator upv_it = units_per_village.begin();
1021 upv_it != units_per_village.end(); ++upv_it) {
1023 assert(*upv_it >=2);
1030 for(v = 0; v < village_count; ++v) {
1036 for(u = 0; u < unit_count; ++u) {
1039 for(v = 0; v < village_count; ++v) {
1047 for(v = 0; v < village_count; ++v) {
1054 const bool reach_all = ((village_count == unit_count)
1055 && (std::accumulate(villages_per_unit.begin(), villages_per_unit.end(), std::size_t())
1056 == (village_count * unit_count)));
1066 std::multimap<std::size_t , std::size_t >
1067 ::const_iterator src_itor = unit_lookup.begin();
1069 while(src_itor != unit_lookup.end() && src_itor->first == 2) {
1071 for(std::multimap<std::size_t, std::size_t>::const_iterator
1072 dst_itor = unit_lookup.begin();
1073 dst_itor != unit_lookup.end(); ++ dst_itor) {
1076 if(src_itor == dst_itor) {
1080 boost::dynamic_bitset<> result = matrix[src_itor->second] & matrix[dst_itor->second];
1081 std::size_t matched = result.count();
1086 std::size_t first = result.find_first();
1087 std::size_t second = result.find_next(first);
1092 const bool perfect = (src_itor->first == 2 &&
1093 dst_itor->first == 2 &&
1094 units_per_village[first] == 2 &&
1095 units_per_village[second] == 2);
1099 <<
" to village " << village1;
1100 moves.emplace_back(village1, units[src_itor->second]);
1103 <<
" to village " << village2;
1104 moves.emplace_back(village2, units[dst_itor->second]);
1107 reachmap.erase(units[src_itor->second]);
1108 reachmap.erase(units[dst_itor->second]);
1140 std::vector<std::pair<map_location, map_location>> best_result;
1148 const std::size_t max_options = 8;
1149 if(unit_count >= max_options && village_count >= max_options) {
1152 << village_count<<
" found, evaluate only the first "
1153 << max_options <<
" options;";
1155 std::vector<std::size_t> perm (max_options, 0);
1156 for(std::size_t
i =0;
i < max_options; ++
i) {
1159 while(std::next_permutation(perm.begin(), perm.end())) {
1162 std::vector<std::pair<map_location,map_location>> result;
1163 for(std::size_t u = 0; u < max_options; ++u) {
1164 if(matrix[u][perm[u]]) {
1165 result.emplace_back(villages[perm[u]], units[u]);
1169 if(result.size() == max_result) {
1170 best_result.swap(result);
1174 if(result.size() > best_result.size()) {
1175 best_result.swap(result);
1179 moves.insert(moves.end(), best_result.begin(), best_result.end());
1182 for(
const auto& unit_village_pair : best_result) {
1183 reachmap.erase(unit_village_pair.second);
1190 }
else if(unit_count <= village_count) {
1194 std::vector<std::size_t> perm (unit_count, 0);
1195 for(std::size_t
i =0;
i < unit_count; ++
i) {
1198 while(std::next_permutation(perm.begin(), perm.end())) {
1200 std::vector<std::pair<map_location,map_location>> result;
1201 for(std::size_t u = 0; u < unit_count; ++u) {
1202 if(matrix[u][perm[u]]) {
1203 result.emplace_back(villages[perm[u]], units[u]);
1207 if(result.size() == max_result) {
1208 moves.insert(moves.end(), result.begin(), result.end());
1213 if(result.size() > best_result.size()) {
1214 best_result.swap(result);
1218 moves.insert(moves.end(), best_result.begin(), best_result.end());
1222 for(
const auto& unit_village_pair : best_result) {
1223 reachmap.erase(unit_village_pair.second);
1226 if(
unit != reachmap.end()) {
1227 unit->second.clear();
1236 std::vector<std::size_t> perm (village_count, 0);
1237 for(std::size_t
i =0;
i < village_count; ++
i) {
1240 while(std::next_permutation(perm.begin(), perm.end())) {
1242 std::vector<std::pair<map_location,map_location>> result;
1243 for(std::size_t v = 0; v < village_count; ++v) {
1244 if(matrix[perm[v]][v]) {
1245 result.emplace_back(villages[v], units[perm[v]]);
1249 if(result.size() == max_result) {
1250 moves.insert(moves.end(), result.begin(), result.end());
1255 if(result.size() > best_result.size()) {
1256 best_result.swap(result);
1260 moves.insert(moves.end(), best_result.begin(), best_result.end());
1264 for(
const auto& unit_village_pair : best_result) {
1265 reachmap.erase(unit_village_pair.second);
1268 if(
unit != reachmap.end()) {
1269 unit->second.clear();
1278 treachmap::const_iterator itor = reachmap.begin();
1279 for(std::size_t
i = 0;
i < reachmap.size(); ++
i, ++itor) {
1281 <<
" to village " << itor->second[
i];
1282 moves.emplace_back(itor->second[
i], itor->first);
1292 for(treachmap::const_iterator itor =
1293 reachmap.begin(); itor != reachmap.end(); ++itor) {
1297 if(itor->second.empty()) {
1301 for(std::vector<map_location>::const_iterator
1302 v_itor = itor->second.begin();
1303 v_itor != itor->second.end(); ++v_itor) {
1327 for(; u_it != units_.
end(); ++u_it) {
1343 typedef std::multimap<map_location,map_location>::const_iterator Itor;
1344 std::pair<Itor,Itor> it =
get_srcdst().equal_range(u_it->get_location());
1345 double best_vulnerability = 100000.0;
1347 const double leader_penalty = (u.
can_recruit()?2.0:1.0);
1348 Itor best_loc = it.second;
1349 while(it.first != it.second) {
1354 if(vuln < best_vulnerability) {
1355 best_vulnerability = vuln;
1356 best_loc = it.first;
1366 if(best_loc != it.second && best_vulnerability*leader_penalty < u.
hitpoints()) {
1368 if (
move_->is_ok()) {
1382 if (!
move_->is_ok()){
1406 std::map<map_location,pathfind::paths> dummy_possible_moves;
1413 std::vector<map_location> leaders_adj_v;
1424 leaders_adj_v.push_back(loc);
1432 i->movement_left() ==
i->total_movement() &&
1434 std::find(leaders.begin(), leaders.end(),
i) == leaders.end() &&
1442 bool can_reach_leader =
false;
1448 typedef move_map::const_iterator Itor;
1449 std::pair<Itor,Itor> itors =
get_srcdst().equal_range(
i->get_location());
1452 double best_rating = -1000.0;
1453 int best_defensive_rating =
i->defense_modifier(
resources::gameboard->map().get_terrain(
i->get_location()))
1455 while(itors.first != itors.second) {
1459 if(std::find(leaders_adj_v.begin(), leaders_adj_v.end(), itors.first->second) != leaders_adj_v.end()){
1461 can_reach_leader =
true;
1472 const double rating = our_power - their_power;
1473 if(rating > best_rating) {
1475 best_rating = rating;
1481 if(modified_defense < best_defensive_rating) {
1482 best_defensive_rating = modified_defense;
1483 best_defensive = hex;
1491 if(can_reach_leader) {
1495 if(!best_pos.
valid()) {
1496 best_pos = best_defensive;
1499 if(best_pos.
valid()) {
1501 if (
move_->is_ok()) {
1515 if (!
move_->is_ok()){
1524 if(caution <= 0.0) {
1530 const double proposed_terrain =
1535 const double exposure = proposed_terrain - optimal_terrain;
1539 return caution*their_power*(1.0+exposure) > our_power;
1577 bool have_active_leader =
false;
1581 have_active_leader =
true;
1585 if(!have_active_leader) {
1589 bool allied_leaders_available =
false;
1593 if (!allied_leaders.empty()){
1594 allied_leaders_available =
true;
1599 if(allied_leaders_available){
1611 typedef std::map<map_location, pathfind::paths> path_map;
1612 path_map possible_moves;
1613 move_map friends_srcdst, friends_dstsrc;
1631 bool friend_can_reach_keep =
false;
1634 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1636 assert(itor.
valid());
1639 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1640 if(tokeep !=
i->second.destinations.end()){
1641 friend_can_reach_keep =
true;
1647 if(friend_can_reach_keep){
1650 int defense_modifier = 100;
1651 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1652 ;
i != possible_moves[keep].destinations.end()
1657 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1660 if(tmp_def_mod < defense_modifier){
1661 defense_modifier = tmp_def_mod;
1662 best_move =
i->curr;
1667 if(defense_modifier < 100){
1671 if (!move->is_ok()){
1674 ai_leader->set_goto(keep);
1678 possible_moves.clear();
1685 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.
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