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;
693 if(
std::find(dispatched_units.begin(), dispatched_units.end(),
694 j->second) != dispatched_units.end()) {
702 bool want_village =
true, owned =
false;
704 owned =
t.owns_village(current_loc);
706 want_village =
false;
714 if(want_village ==
false) {
725 const std::map<map_location,double>::const_iterator vuln = vulnerability.find(current_loc);
726 if(vuln != vulnerability.end()) {
727 threat = vuln->second;
730 vulnerability.emplace(current_loc, threat);
748 std::multimap<map_location, map_location>::const_iterator next = j;
750 const bool at_begin = (j == dstsrc.begin());
751 std::multimap<map_location, map_location>::const_iterator
prev = j;
756 if((next == dstsrc.end() || next->first != current_loc)
757 && (at_begin ||
prev->first != current_loc)) {
760 if (move_check_res->is_ok()) {
762 moves.emplace_back(j->first, j->second);
764 reachmap.erase(j->second);
765 dispatched_units.push_back(j->second);
769 reachmap[j->second].push_back(current_loc);
773 << reachmap.size() <<
" left to evaluate.";
787 std::size_t village_count = 0;
788 bool dispatched =
true;
795 if(reachmap.empty()) {
806 if(reachmap.empty()) {
814 if(!reachmap.empty() && dispatched) {
821 if(reachmap.empty()) {
827 << village_count <<
" villages left.";
841 while(itor != reachmap.end()) {
842 if(itor->second.size() == 1) {
847 moves.emplace_back(village, itor->first);
848 reachmap.erase(itor++);
851 itor = reachmap.begin();
860 if(reachmap.empty()) {
865 if(reachmap.size() == 1) {
868 <<
" to village " << reachmap.begin()->second[0];
870 moves.emplace_back(reachmap.begin()->second[0], reachmap.begin()->first);
885 bool dispatched =
true;
893 treachmap::const_iterator itor = reachmap.begin();
894 for(;itor != reachmap.end(); ++itor) {
896 for(std::vector<map_location>::const_iterator
897 v_itor = itor->second.begin();
898 v_itor != itor->second.end(); ++v_itor) {
900 reversemap[*v_itor].push_back(itor->first);
905 village_count = reversemap.size();
907 itor = reversemap.begin();
908 while(itor != reversemap.end()) {
909 if(itor->second.size() == 1) {
916 moves.emplace_back(itor->first, itor->second[0]);
918 reachmap.erase(itor->second[0]);
937 while(itor != reachmap.end()) {
939 if(itor->second.empty()) {
952 assert(
unit->second.empty());
961 reachmap.erase(
unit++);
970 const std::size_t unit_count = reachmap.size();
972 const std::size_t max_result = unit_count < village_count ? unit_count : village_count;
974 assert(unit_count >= 2 && village_count >= 2);
977 if(unit_count == 2 && village_count == 2) {
983 std::vector<map_location> units(unit_count);
984 std::vector<std::size_t> villages_per_unit(unit_count);
985 std::vector<map_location> villages;
986 std::vector<std::size_t> units_per_village(village_count);
990 std::multimap<std::size_t ,
991 std::size_t > unit_lookup;
993 std::vector<
boost::dynamic_bitset<>> matrix(reachmap.size(), boost::dynamic_bitset<>(village_count));
995 treachmap::const_iterator itor = reachmap.begin();
996 for(std::size_t u = 0; u < unit_count; ++u, ++itor) {
997 units[u] = itor->first;
998 villages_per_unit[u] = itor->second.size();
999 unit_lookup.emplace(villages_per_unit[u], u);
1001 assert(itor->second.size() >= 2);
1003 for(std::size_t v = 0; v < itor->second.size(); ++v) {
1005 std::size_t v_index;
1007 std::vector<map_location>::const_iterator v_itor =
1008 std::find(villages.begin(), villages.end(), itor->second[v]);
1009 if(v_itor == villages.end()) {
1010 v_index = villages.size();
1011 villages.push_back(itor->second[v]);
1013 v_index = v_itor - villages.begin();
1016 units_per_village[v_index]++;
1018 matrix[u][v_index] =
true;
1021 for(std::vector<std::size_t>::const_iterator upv_it = units_per_village.begin();
1022 upv_it != units_per_village.end(); ++upv_it) {
1024 assert(*upv_it >=2);
1031 for(v = 0; v < village_count; ++v) {
1037 for(u = 0; u < unit_count; ++u) {
1040 for(v = 0; v < village_count; ++v) {
1048 for(v = 0; v < village_count; ++v) {
1055 const bool reach_all = ((village_count == unit_count)
1056 && (std::accumulate(villages_per_unit.begin(), villages_per_unit.end(), std::size_t())
1057 == (village_count * unit_count)));
1067 std::multimap<std::size_t , std::size_t >
1068 ::const_iterator src_itor = unit_lookup.begin();
1070 while(src_itor != unit_lookup.end() && src_itor->first == 2) {
1072 for(std::multimap<std::size_t, std::size_t>::const_iterator
1073 dst_itor = unit_lookup.begin();
1074 dst_itor != unit_lookup.end(); ++ dst_itor) {
1077 if(src_itor == dst_itor) {
1081 boost::dynamic_bitset<> result = matrix[src_itor->second] & matrix[dst_itor->second];
1082 std::size_t matched = result.count();
1087 std::size_t first = result.find_first();
1088 std::size_t second = result.find_next(first);
1093 const bool perfect = (src_itor->first == 2 &&
1094 dst_itor->first == 2 &&
1095 units_per_village[first] == 2 &&
1096 units_per_village[second] == 2);
1100 <<
" to village " << village1;
1101 moves.emplace_back(village1, units[src_itor->second]);
1104 <<
" to village " << village2;
1105 moves.emplace_back(village2, units[dst_itor->second]);
1108 reachmap.erase(units[src_itor->second]);
1109 reachmap.erase(units[dst_itor->second]);
1141 std::vector<std::pair<map_location, map_location>> best_result;
1149 const std::size_t max_options = 8;
1150 if(unit_count >= max_options && village_count >= max_options) {
1153 << village_count<<
" found, evaluate only the first "
1154 << max_options <<
" options;";
1156 std::vector<std::size_t> perm (max_options, 0);
1157 for(std::size_t
i =0;
i < max_options; ++
i) {
1160 while(std::next_permutation(perm.begin(), perm.end())) {
1163 std::vector<std::pair<map_location,map_location>> result;
1164 for(std::size_t u = 0; u < max_options; ++u) {
1165 if(matrix[u][perm[u]]) {
1166 result.emplace_back(villages[perm[u]], units[u]);
1170 if(result.size() == max_result) {
1171 best_result.swap(result);
1175 if(result.size() > best_result.size()) {
1176 best_result.swap(result);
1180 moves.insert(moves.end(), best_result.begin(), best_result.end());
1183 for(
const auto& unit_village_pair : best_result) {
1184 reachmap.erase(unit_village_pair.second);
1191 }
else if(unit_count <= village_count) {
1195 std::vector<std::size_t> perm (unit_count, 0);
1196 for(std::size_t
i =0;
i < unit_count; ++
i) {
1199 while(std::next_permutation(perm.begin(), perm.end())) {
1201 std::vector<std::pair<map_location,map_location>> result;
1202 for(std::size_t u = 0; u < unit_count; ++u) {
1203 if(matrix[u][perm[u]]) {
1204 result.emplace_back(villages[perm[u]], units[u]);
1208 if(result.size() == max_result) {
1209 moves.insert(moves.end(), result.begin(), result.end());
1214 if(result.size() > best_result.size()) {
1215 best_result.swap(result);
1219 moves.insert(moves.end(), best_result.begin(), best_result.end());
1223 for(
const auto& unit_village_pair : best_result) {
1224 reachmap.erase(unit_village_pair.second);
1227 if(
unit != reachmap.end()) {
1228 unit->second.clear();
1237 std::vector<std::size_t> perm (village_count, 0);
1238 for(std::size_t
i =0;
i < village_count; ++
i) {
1241 while(std::next_permutation(perm.begin(), perm.end())) {
1243 std::vector<std::pair<map_location,map_location>> result;
1244 for(std::size_t v = 0; v < village_count; ++v) {
1245 if(matrix[perm[v]][v]) {
1246 result.emplace_back(villages[v], units[perm[v]]);
1250 if(result.size() == max_result) {
1251 moves.insert(moves.end(), result.begin(), result.end());
1256 if(result.size() > best_result.size()) {
1257 best_result.swap(result);
1261 moves.insert(moves.end(), best_result.begin(), best_result.end());
1265 for(
const auto& unit_village_pair : best_result) {
1266 reachmap.erase(unit_village_pair.second);
1269 if(
unit != reachmap.end()) {
1270 unit->second.clear();
1279 treachmap::const_iterator itor = reachmap.begin();
1280 for(std::size_t
i = 0;
i < reachmap.size(); ++
i, ++itor) {
1282 <<
" to village " << itor->second[
i];
1283 moves.emplace_back(itor->second[
i], itor->first);
1293 for(treachmap::const_iterator itor =
1294 reachmap.begin(); itor != reachmap.end(); ++itor) {
1298 if(itor->second.empty()) {
1302 for(std::vector<map_location>::const_iterator
1303 v_itor = itor->second.begin();
1304 v_itor != itor->second.end(); ++v_itor) {
1328 for(; u_it != units_.
end(); ++u_it) {
1344 auto 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 auto 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 auto 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.
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.