38 #include <SDL2/SDL_timer.h>
41 #define DBG_AI_TESTING_AI_DEFAULT LOG_STREAM(debug, log_ai_testing_ai_default)
42 #define LOG_AI_TESTING_AI_DEFAULT LOG_STREAM(info, log_ai_testing_ai_default)
43 #define WRN_AI_TESTING_AI_DEFAULT LOG_STREAM(warn, log_ai_testing_ai_default)
44 #define ERR_AI_TESTING_AI_DEFAULT LOG_STREAM(err, log_ai_testing_ai_default)
48 namespace ai_default_rca {
65 std::vector<map_location> gotos;
70 if (ui->get_goto() == ui->get_location()) {
73 gotos.push_back(ui->get_location());
77 for(std::vector<map_location>::const_iterator
g = gotos.begin();
g != gotos.end(); ++
g) {
94 route =
pathfind::a_star_search(ui->get_location(), ui->get_goto(), 10000.0, calc, map_.
w(), map_.
h(), &allowed_teleports);
96 if (!route.
steps.empty()){
103 int closest_distance = -1;
104 std::pair<map_location,map_location> closest_move;
106 if(
i->second != ui->get_location()) {
110 if(closest_distance == -1 || distance < closest_distance) {
111 closest_distance = distance;
115 if(closest_distance != -1) {
122 if (
move_->is_ok()) {
137 if (!
move_->is_ok()){
144 if (!
move_->is_gamestate_changed()){
168 int ticks = SDL_GetTicks();
170 const std::vector<attack_analysis> analysis =
get_attacks();
172 int time_taken = SDL_GetTicks() - ticks;
174 <<
" positions. Analyzing...";
176 ticks = SDL_GetTicks();
178 const int max_sims = 50000;
179 int num_sims = analysis.empty() ? 0 : max_sims/analysis.size();
187 const int max_positions = 30000;
188 const int skip_num = analysis.size()/max_positions;
190 std::vector<attack_analysis>::const_iterator choice_it = analysis.end();
191 for(std::vector<attack_analysis>::const_iterator it = analysis.begin();
192 it != analysis.end(); ++it) {
194 if(skip_num > 0 && ((it - analysis.begin())%skip_num) && it->movements.size() > 1)
202 bool skip_attack =
false;
203 for(std::size_t
i = 0;
i != it->movements.size(); ++
i) {
223 time_taken = SDL_GetTicks() - ticks;
246 if (!move_res->is_ok()) {
253 if (!attack_res->is_ok()) {
256 attack_res->execute();
257 if (!attack_res->is_ok()) {
297 if (leaders.empty()) {
301 const unit* leader =
nullptr;
303 if (!l_itor->incapacitated() && l_itor->movement_left() > 0 &&
is_allowed_unit(*l_itor)) {
309 if (leader ==
nullptr) {
321 if (
move_->is_ok()) {
333 if(route.
steps.empty()) {
340 std::map<map_location,pathfind::paths> possible_moves;
341 possible_moves.emplace(leader->
get_location(), leader_paths);
355 if (
move_->is_ok()) {
366 if (!
move_->is_ok()){
381 mod_ai[
"path"] =
"aspect[leader_goal].facet["+
id+
"]";
382 mod_ai[
"action"] =
"delete";
415 if (leaders.empty()) {
420 const unit* best_leader =
nullptr;
422 int shortest_distance = 99999;
431 const ai::moves_map::const_iterator& p_it = possible_moves.find(leader->get_location());
432 if (p_it == possible_moves.end()) {
449 if (!route.
steps.empty() || route.
move_cost < shortest_distance) {
450 best_leader = &(*leader);
456 if (best_leader ==
nullptr) {
461 const unit* leader = best_leader;
469 if (
move_->is_ok()) {
479 typedef std::multimap<int, map_location> ordered_locations;
480 ordered_locations moves_toward_keep;
487 int next_hop_cost = 0;
498 moves_toward_keep.emplace(0, next_hop);
512 for (
const ordered_locations::value_type& pair : moves_toward_keep) {
516 if (
move_->is_ok()) {
527 if (!
move_->is_ok()) {
565 std::pair<map_location,map_location> leader_move;
567 for(tmoves::const_iterator
i =
moves_.begin();
i !=
moves_.end(); ++
i) {
569 if(leader != units_.
end() && leader->get_location() ==
i->second) {
574 if (!move_res->is_ok()) {
582 if (new_unit != units_.
end() &&
591 if(leader_move.second.valid()) {
595 if (!move_res->is_ok()) {
610 const int ticks = SDL_GetTicks();
612 if(leader != units_.
end()) {
625 u_itor != units_.
end(); ++u_itor) {
630 reachmap.emplace(u_itor->get_location(), std::vector<map_location>());
639 while(itor != reachmap.end()) {
640 if(itor->second.empty()) {
647 if(!reachmap.empty()) {
649 "can't reach a village, send the to the dispatcher.";
659 <<
" ms, resulted in " <<
moves_.size() <<
" units being dispatched.";
666 const std::multimap<map_location,map_location>& dstsrc,
667 const std::multimap<map_location,map_location>& enemy_dstsrc)
670 std::map<map_location, double> vulnerability;
672 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;
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() &&
1433 std::find(leaders.begin(), leaders.end(),
i) == leaders.end() &&
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) {
1457 if(
std::find(leaders_adj_v.begin(), leaders_adj_v.end(), itors.first->second) != leaders_adj_v.end()){
1459 can_reach_leader =
true;
1470 const double rating = our_power - their_power;
1471 if(rating > best_rating) {
1473 best_rating = rating;
1479 if(modified_defense < best_defensive_rating) {
1480 best_defensive_rating = modified_defense;
1481 best_defensive = hex;
1489 if(can_reach_leader) {
1493 if(!best_pos.
valid()) {
1494 best_pos = best_defensive;
1497 if(best_pos.
valid()) {
1499 if (
move_->is_ok()) {
1513 if (!
move_->is_ok()){
1522 if(caution <= 0.0) {
1528 const double proposed_terrain =
1533 const double exposure = proposed_terrain - optimal_terrain;
1537 return caution*their_power*(1.0+exposure) > our_power;
1575 bool have_active_leader =
false;
1579 have_active_leader =
true;
1583 if(!have_active_leader) {
1587 bool allied_leaders_available =
false;
1591 if (!allied_leaders.empty()){
1592 allied_leaders_available =
true;
1597 if(allied_leaders_available){
1609 typedef std::map<map_location, pathfind::paths> path_map;
1610 path_map possible_moves;
1611 move_map friends_srcdst, friends_dstsrc;
1629 bool friend_can_reach_keep =
false;
1632 for(path_map::const_iterator
i = possible_moves.begin();
i != possible_moves.end(); ++
i){
1634 assert(itor.
valid());
1637 pathfind::paths::dest_vect::const_iterator tokeep =
i->second.destinations.find(keep);
1638 if(tokeep !=
i->second.destinations.end()){
1639 friend_can_reach_keep =
true;
1645 if(friend_can_reach_keep){
1648 int defense_modifier = 100;
1649 for(pathfind::paths::dest_vect::const_iterator
i = possible_moves[keep].destinations.begin()
1650 ;
i != possible_moves[keep].destinations.end()
1655 &&
static_cast<int>(
distance_between(
i->curr, keep)) <= ai_leader->movement_left()){
1658 if(tmp_def_mod < defense_modifier){
1659 defense_modifier = tmp_def_mod;
1660 best_move =
i->curr;
1665 if(defense_modifier < 100){
1669 if (!move->is_ok()){
1672 ai_leader->set_goto(keep);
1676 possible_moves.clear();
1683 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.
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.
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.