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>());
639 if(itor->second.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;
676 std::vector<map_location> dispatched_units;
677 for(std::multimap<map_location, map_location>::const_iterator
679 j != dstsrc.end(); ++j) {
685 if(distance < min_distance) {
686 min_distance = distance;
691 if(std::find(dispatched_units.begin(), dispatched_units.end(),
692 j->second) != dispatched_units.end()) {
700 bool want_village =
true, owned =
false;
702 owned =
t.owns_village(current_loc);
704 want_village =
false;
712 if(want_village ==
false) {
723 const std::map<map_location,double>::const_iterator vuln = vulnerability.find(current_loc);
724 if(vuln != vulnerability.end()) {
725 threat = vuln->second;
728 vulnerability.emplace(current_loc, threat);
746 std::multimap<map_location, map_location>::const_iterator next = j;
748 const bool at_begin = (j == dstsrc.begin());
749 std::multimap<map_location, map_location>::const_iterator
prev = j;
754 if((next == dstsrc.end() || next->first != current_loc)
755 && (at_begin ||
prev->first != current_loc)) {
758 if (move_check_res->is_ok()) {
760 moves.emplace_back(j->first, j->second);
763 dispatched_units.push_back(j->second);
767 reachmap[j->second].push_back(current_loc);
771 <<
reachmap.size() <<
" left to evaluate.";
785 std::size_t village_count = 0;
786 bool dispatched =
true;
812 if(!
reachmap.empty() && dispatched) {
825 << village_count <<
" villages left.";
840 if(itor->second.size() == 1) {
845 moves.emplace_back(village, itor->first);
866 <<
" to village " <<
reachmap.begin()->second[0];
883 bool dispatched =
true;
891 treachmap::const_iterator itor =
reachmap.begin();
892 for(;itor !=
reachmap.end(); ++itor) {
894 for(std::vector<map_location>::const_iterator
895 v_itor = itor->second.begin();
896 v_itor != itor->second.end(); ++v_itor) {
898 reversemap[*v_itor].push_back(itor->first);
903 village_count = reversemap.size();
905 itor = reversemap.begin();
906 while(itor != reversemap.end()) {
907 if(itor->second.size() == 1) {
914 moves.emplace_back(itor->first, itor->second[0]);
937 if(itor->second.empty()) {
950 assert(
unit->second.empty());
968 const std::size_t unit_count =
reachmap.size();
970 const std::size_t max_result = unit_count < village_count ? unit_count : village_count;
972 assert(unit_count >= 2 && village_count >= 2);
975 if(unit_count == 2 && village_count == 2) {
981 std::vector<map_location> units(unit_count);
982 std::vector<std::size_t> villages_per_unit(unit_count);
983 std::vector<map_location> villages;
984 std::vector<std::size_t> units_per_village(village_count);
988 std::multimap<std::size_t ,
989 std::size_t > unit_lookup;
993 treachmap::const_iterator itor =
reachmap.begin();
994 for(std::size_t u = 0; u < unit_count; ++u, ++itor) {
995 units[u] = itor->first;
996 villages_per_unit[u] = itor->second.size();
997 unit_lookup.emplace(villages_per_unit[u], u);
999 assert(itor->second.size() >= 2);
1001 for(std::size_t v = 0; v < itor->second.size(); ++v) {
1003 std::size_t v_index;
1005 std::vector<map_location>::const_iterator v_itor =
1006 std::find(villages.begin(), villages.end(), itor->second[v]);
1007 if(v_itor == villages.end()) {
1008 v_index = villages.size();
1009 villages.push_back(itor->second[v]);
1011 v_index = v_itor - villages.begin();
1014 units_per_village[v_index]++;
1016 matrix[u][v_index] =
true;
1019 for(std::vector<std::size_t>::const_iterator upv_it = units_per_village.begin();
1020 upv_it != units_per_village.end(); ++upv_it) {
1022 assert(*upv_it >=2);
1029 for(v = 0; v < village_count; ++v) {
1035 for(u = 0; u < unit_count; ++u) {
1038 for(v = 0; v < village_count; ++v) {
1046 for(v = 0; v < village_count; ++v) {
1053 const bool reach_all = ((village_count == unit_count)
1054 && (std::accumulate(villages_per_unit.begin(), villages_per_unit.end(), std::size_t())
1055 == (village_count * unit_count)));
1065 std::multimap<std::size_t , std::size_t >
1066 ::const_iterator src_itor = unit_lookup.begin();
1068 while(src_itor != unit_lookup.end() && src_itor->first == 2) {
1070 for(std::multimap<std::size_t, std::size_t>::const_iterator
1071 dst_itor = unit_lookup.begin();
1072 dst_itor != unit_lookup.end(); ++ dst_itor) {
1075 if(src_itor == dst_itor) {
1079 boost::dynamic_bitset<> result = matrix[src_itor->second] & matrix[dst_itor->second];
1080 std::size_t matched = result.count();
1085 std::size_t first = result.find_first();
1086 std::size_t second = result.find_next(first);
1091 const bool perfect = (src_itor->first == 2 &&
1092 dst_itor->first == 2 &&
1093 units_per_village[first] == 2 &&
1094 units_per_village[second] == 2);
1098 <<
" to village " << village1;
1099 moves.emplace_back(village1, units[src_itor->second]);
1102 <<
" to village " << village2;
1103 moves.emplace_back(village2, units[dst_itor->second]);
1106 reachmap.erase(units[src_itor->second]);
1107 reachmap.erase(units[dst_itor->second]);
1139 std::vector<std::pair<map_location, map_location>> best_result;
1147 const std::size_t max_options = 8;
1148 if(unit_count >= max_options && village_count >= max_options) {
1151 << village_count<<
" found, evaluate only the first "
1152 << max_options <<
" options;";
1154 std::vector<std::size_t> perm (max_options, 0);
1155 for(std::size_t
i =0;
i < max_options; ++
i) {
1158 while(std::next_permutation(perm.begin(), perm.end())) {
1161 std::vector<std::pair<map_location,map_location>> result;
1162 for(std::size_t u = 0; u < max_options; ++u) {
1163 if(matrix[u][perm[u]]) {
1164 result.emplace_back(villages[perm[u]], units[u]);
1168 if(result.size() == max_result) {
1169 best_result.swap(result);
1173 if(result.size() > best_result.size()) {
1174 best_result.swap(result);
1178 moves.insert(moves.end(), best_result.begin(), best_result.end());
1181 for(
const auto& unit_village_pair : best_result) {
1182 reachmap.erase(unit_village_pair.second);
1189 }
else if(unit_count <= village_count) {
1193 std::vector<std::size_t> perm (unit_count, 0);
1194 for(std::size_t
i =0;
i < unit_count; ++
i) {
1197 while(std::next_permutation(perm.begin(), perm.end())) {
1199 std::vector<std::pair<map_location,map_location>> result;
1200 for(std::size_t u = 0; u < unit_count; ++u) {
1201 if(matrix[u][perm[u]]) {
1202 result.emplace_back(villages[perm[u]], units[u]);
1206 if(result.size() == max_result) {
1207 moves.insert(moves.end(), result.begin(), result.end());
1212 if(result.size() > best_result.size()) {
1213 best_result.swap(result);
1217 moves.insert(moves.end(), best_result.begin(), best_result.end());
1221 for(
const auto& unit_village_pair : best_result) {
1222 reachmap.erase(unit_village_pair.second);
1226 unit->second.clear();
1235 std::vector<std::size_t> perm (village_count, 0);
1236 for(std::size_t
i =0;
i < village_count; ++
i) {
1239 while(std::next_permutation(perm.begin(), perm.end())) {
1241 std::vector<std::pair<map_location,map_location>> result;
1242 for(std::size_t v = 0; v < village_count; ++v) {
1243 if(matrix[perm[v]][v]) {
1244 result.emplace_back(villages[v], units[perm[v]]);
1248 if(result.size() == max_result) {
1249 moves.insert(moves.end(), result.begin(), result.end());
1254 if(result.size() > best_result.size()) {
1255 best_result.swap(result);
1259 moves.insert(moves.end(), best_result.begin(), best_result.end());
1263 for(
const auto& unit_village_pair : best_result) {
1264 reachmap.erase(unit_village_pair.second);
1268 unit->second.clear();
1277 treachmap::const_iterator itor =
reachmap.begin();
1278 for(std::size_t
i = 0;
i <
reachmap.size(); ++
i, ++itor) {
1280 <<
" to village " << itor->second[
i];
1281 moves.emplace_back(itor->second[
i], itor->first);
1291 for(treachmap::const_iterator itor =
1296 if(itor->second.empty()) {
1300 for(std::vector<map_location>::const_iterator
1301 v_itor = itor->second.begin();
1302 v_itor != itor->second.end(); ++v_itor) {
1326 for(; u_it != units_.
end(); ++u_it) {
1342 typedef std::multimap<map_location,map_location>::const_iterator Itor;
1343 std::pair<Itor,Itor> 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 Itor 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() &&
1433 std::find(leaders.begin(), leaders.end(),
i) == leaders.end() &&
1441 bool can_reach_leader =
false;
1447 typedef move_map::const_iterator Itor;
1448 std::pair<Itor,Itor> itors =
get_srcdst().equal_range(
i->get_location());
1451 double best_rating = -1000.0;
1452 int best_defensive_rating =
i->defense_modifier(
resources::gameboard->map().get_terrain(
i->get_location()))
1454 while(itors.first != itors.second) {
1458 if(std::find(leaders_adj_v.begin(), leaders_adj_v.end(), itors.first->second) != leaders_adj_v.end()){
1460 can_reach_leader =
true;
1471 const double rating = our_power - their_power;
1472 if(rating > best_rating) {
1474 best_rating = rating;
1480 if(modified_defense < best_defensive_rating) {
1481 best_defensive_rating = modified_defense;
1482 best_defensive = hex;
1490 if(can_reach_leader) {
1494 if(!best_pos.
valid()) {
1495 best_pos = best_defensive;
1498 if(best_pos.
valid()) {
1500 if (
move_->is_ok()) {
1514 if (!
move_->is_ok()){
1523 if(caution <= 0.0) {
1529 const double proposed_terrain =
1534 const double exposure = proposed_terrain - optimal_terrain;
1538 return caution*their_power*(1.0+exposure) > our_power;
1576 bool have_active_leader =
false;
1580 have_active_leader =
true;
1584 if(!have_active_leader) {
1588 bool allied_leaders_available =
false;
1592 if (!allied_leaders.empty()){
1593 allied_leaders_available =
true;
1598 if(allied_leaders_available){
1610 typedef std::map<map_location, pathfind::paths> path_map;
1611 path_map possible_moves;
1612 move_map friends_srcdst, friends_dstsrc;
1630 bool friend_can_reach_keep =
false;
1633 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1635 assert(itor.
valid());
1638 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1639 if(tokeep !=
i->second.destinations.end()){
1640 friend_can_reach_keep =
true;
1646 if(friend_can_reach_keep){
1649 int defense_modifier = 100;
1650 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1651 ;
i != possible_moves[keep].destinations.end()
1656 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1659 if(tmp_def_mod < defense_modifier){
1660 defense_modifier = tmp_def_mod;
1661 best_move =
i->curr;
1666 if(defense_modifier < 100){
1670 if (!move->is_ok()){
1673 ai_leader->set_goto(keep);
1677 possible_moves.clear();
1684 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.
@ reachmap
Overlay on unreachable hexes.
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
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.
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.