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...";
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()) {
298 if (leaders.empty()) {
302 const unit* leader =
nullptr;
304 if (!l_itor->incapacitated() && l_itor->movement_left() > 0 &&
is_allowed_unit(*l_itor)) {
310 if (leader ==
nullptr) {
322 if (
move_->is_ok()) {
334 if(route.
steps.empty()) {
341 std::map<map_location,pathfind::paths> possible_moves;
342 possible_moves.emplace(leader->
get_location(), leader_paths);
356 if (
move_->is_ok()) {
367 if (!
move_->is_ok()){
382 mod_ai[
"path"] =
"aspect[leader_goal].facet["+
id+
"]";
383 mod_ai[
"action"] =
"delete";
416 if (leaders.empty()) {
421 const unit* best_leader =
nullptr;
423 int shortest_distance = 99999;
432 const ai::moves_map::const_iterator& p_it = possible_moves.find(leader->get_location());
433 if (p_it == possible_moves.end()) {
450 if (!route.
steps.empty() || route.
move_cost < shortest_distance) {
451 best_leader = &(*leader);
457 if (best_leader ==
nullptr) {
462 const unit* leader = best_leader;
470 if (
move_->is_ok()) {
480 typedef std::multimap<int, map_location> ordered_locations;
481 ordered_locations moves_toward_keep;
488 int next_hop_cost = 0;
499 moves_toward_keep.emplace(0, next_hop);
513 for (
const ordered_locations::value_type& pair : moves_toward_keep) {
517 if (
move_->is_ok()) {
528 if (!
move_->is_ok()) {
566 std::pair<map_location,map_location> leader_move;
568 for(tmoves::const_iterator
i =
moves_.begin();
i !=
moves_.end(); ++
i) {
570 if(leader != units_.
end() && leader->get_location() ==
i->second) {
575 if (!move_res->is_ok()) {
583 if (new_unit != units_.
end() &&
592 if(leader_move.second.valid()) {
596 if (!move_res->is_ok()) {
611 const int ticks = SDL_GetTicks();
613 if(leader != units_.
end()) {
626 u_itor != units_.
end(); ++u_itor) {
631 reachmap.emplace(u_itor->get_location(), std::vector<map_location>());
640 while(itor != reachmap.end()) {
641 if(itor->second.empty()) {
648 if(!reachmap.empty()) {
650 "can't reach a village, send the to the dispatcher.";
660 <<
" ms, resulted in " <<
moves_.size() <<
" units being dispatched.";
667 const std::multimap<map_location,map_location>& dstsrc,
668 const std::multimap<map_location,map_location>& enemy_dstsrc)
671 std::map<map_location, double> vulnerability;
673 std::size_t min_distance = 100000;
678 std::vector<map_location> dispatched_units;
679 for(std::multimap<map_location, map_location>::const_iterator
681 j != dstsrc.end(); ++j) {
687 if(distance < min_distance) {
688 min_distance = distance;
701 bool want_village =
true, owned =
false;
703 owned =
t.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()) {
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 auto it =
get_srcdst().equal_range(u_it->get_location());
1344 double best_vulnerability = 100000.0;
1346 const double leader_penalty = (u.
can_recruit()?2.0:1.0);
1347 auto best_loc = it.second;
1348 while(it.first != it.second) {
1353 if(vuln < best_vulnerability) {
1354 best_vulnerability = vuln;
1355 best_loc = it.first;
1365 if(best_loc != it.second && best_vulnerability*leader_penalty < u.
hitpoints()) {
1367 if (
move_->is_ok()) {
1381 if (!
move_->is_ok()){
1405 std::map<map_location,pathfind::paths> dummy_possible_moves;
1412 std::vector<map_location> leaders_adj_v;
1423 leaders_adj_v.push_back(
loc);
1431 i->movement_left() ==
i->total_movement() &&
1441 bool can_reach_leader =
false;
1447 auto itors =
get_srcdst().equal_range(
i->get_location());
1450 double best_rating = -1000.0;
1451 int best_defensive_rating =
i->defense_modifier(
resources::gameboard->map().get_terrain(
i->get_location()))
1453 while(itors.first != itors.second) {
1458 can_reach_leader =
true;
1469 const double rating = our_power - their_power;
1470 if(rating > best_rating) {
1472 best_rating = rating;
1478 if(modified_defense < best_defensive_rating) {
1479 best_defensive_rating = modified_defense;
1480 best_defensive = hex;
1488 if(can_reach_leader) {
1492 if(!best_pos.
valid()) {
1493 best_pos = best_defensive;
1496 if(best_pos.
valid()) {
1498 if (
move_->is_ok()) {
1512 if (!
move_->is_ok()){
1521 if(caution <= 0.0) {
1527 const double proposed_terrain =
1532 const double exposure = proposed_terrain - optimal_terrain;
1536 return caution*their_power*(1.0+exposure) > our_power;
1574 bool have_active_leader =
false;
1578 have_active_leader =
true;
1582 if(!have_active_leader) {
1586 bool allied_leaders_available =
false;
1590 if (!allied_leaders.empty()){
1591 allied_leaders_available =
true;
1596 if(allied_leaders_available){
1608 typedef std::map<map_location, pathfind::paths> path_map;
1609 path_map possible_moves;
1610 move_map friends_srcdst, friends_dstsrc;
1628 bool friend_can_reach_keep =
false;
1631 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1633 assert(itor.
valid());
1636 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1637 if(tokeep !=
i->second.destinations.end()){
1638 friend_can_reach_keep =
true;
1644 if(friend_can_reach_keep){
1647 int defense_modifier = 100;
1648 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1649 ;
i != possible_moves[keep].destinations.end()
1654 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1657 if(tmp_def_mod < defense_modifier){
1658 defense_modifier = tmp_def_mod;
1659 best_move =
i->curr;
1664 if(defense_modifier < 100){
1668 if (!move->is_ok()){
1671 ai_leader->set_goto(keep);
1675 possible_moves.clear();
1682 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 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.
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.
void get_adjacent_tiles(const map_location &a, utils::span< map_location, 6 > res)
Function which, given a location, will place all adjacent locations in res.
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
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::size_t erase(Container &container, const Value &value)
Convenience wrapper for using std::remove on a container.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
std::string::const_iterator iterator
This module contains various pathfinding functions and utilities.
candidate action framework
rect dst
Location on the final composed sheet.
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.