37 #define LOG_AI LOG_STREAM(info, log_ai)
38 #define ERR_AI LOG_STREAM(err, log_ai)
45 const move_map& enemy_dstsrc,
double aggression)
48 assert(defend_it != units.
end());
53 for(tile = 0; tile < adj.size(); ++tile) {
64 target_value += (
static_cast<double>(defend_it->experience())/
65 static_cast<double>(defend_it->max_experience()))*
target_value;
67 defend_it->hitpoints();
74 double cost_sum = 0.0;
77 const double cost = att->cost();
90 double def_avg_experience = 0.0;
91 double first_chance_kill = 0.0;
93 double prob_dead_already = 0.0;
95 std::vector<std::pair<map_location,map_location>>::const_iterator m;
97 std::unique_ptr<battle_context> bc(
nullptr);
98 std::unique_ptr<battle_context> old_bc(
nullptr);
105 up->set_location(m->second);
107 double m_aggression = aggression;
109 if (up->can_recruit()) {
116 bool from_cache =
false;
125 const readonly_context::unit_stats_cache_t::key_type cache_key = std::pair(
target, &up->
type());
129 usc->second.first.attack_num <
130 static_cast<int>(up->attacks().size())) {
133 bc.reset(
new battle_context(usc->second.first, usc->second.second));
137 const combatant &att = bc->get_attacker_combatant(prev_def);
138 const combatant &def = bc->get_defender_combatant(prev_def);
140 prev_def = &bc->get_defender_combatant(prev_def);
143 old_bc.reset(
nullptr);
147 bc->get_attacker_stats(),
148 bc->get_defender_stats()
153 double prob_fought = (1.0 - prob_dead_already);
155 double prob_killed = def.
hp_dist[0] - prob_dead_already;
156 prob_dead_already = def.
hp_dist[0];
158 double prob_died = att.
hp_dist[0];
159 double prob_survived = (1.0 - prob_died) * prob_fought;
161 double cost = up->cost();
162 const bool on_village = map.
is_village(m->second);
164 cost += (
static_cast<double>(up->experience()) / up->max_experience())*cost;
171 if (!bc->get_defender_stats().is_poisoned) {
180 terrain_quality += (
static_cast<double>(bc->get_defender_stats().chance_to_hit)/100.0)*cost * (on_village ? 0.5 : 1.0);
182 double advance_prob = 0.0;
184 if (!up->advances_to().empty()) {
185 int xp_for_advance = up->experience_to_advance();
189 if (xp_for_advance == 0)
195 if (fight_xp >= xp_for_advance) {
196 advance_prob = prob_fought;
198 }
else if (
kill_xp >= xp_for_advance) {
199 advance_prob = prob_killed;
208 fight_xp * (prob_fought - prob_killed)
212 (
kill_xp * prob_killed + fight_xp * (prob_fought - prob_killed))
218 if (bc->get_attacker_stats().plagues) {
230 first_chance_kill = def.
hp_dist[0];
234 if (!defend_it->advances_to().empty() &&
235 def_avg_experience >= defend_it->experience_to_advance()) {
249 units.
move(m->second, m->first);
256 for(std::set<map_location>::const_iterator
i = attacks.begin();
i != attacks.end(); ++
i) {
286 LOG_AI <<
"attack option has base value " << value <<
" with exposure " << exposure <<
": "
288 value -= exposure*(1.0-aggression);
Various functions that implement attacks and attack calculations.
Managing the AI-Game interaction - AI actions and their results.
static lg::log_domain log_ai("ai/attack")
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
std::vector< std::pair< map_location, map_location > > movements
void analyze(const gamemap &map, unit_map &units, const readonly_context &ai_obj, const move_map &dstsrc, const move_map &srcdst, const move_map &enemy_dstsrc, double aggression)
bool uses_leader
Is true if this attack sequence makes use of the leader.
double target_value
The value of the unit being targeted.
double avg_damage_inflicted
The average hitpoints damage inflicted.
double chance_to_kill
Estimated % chance to kill the unit.
bool attack_close(const map_location &loc) const
double terrain_quality
The weighted average of the % chance to hit each attacking unit.
double avg_damage_taken
The average hitpoints damage taken.
double alternative_terrain_quality
The weighted average of the % defense of the best possible terrain that the attacking units could rea...
bool leader_threat
Is true if the unit is a threat to our leader.
double avg_losses
The value on average, of units lost in the combat.
double vulnerability
The vulnerability is the power projection of enemy units onto the hex we're standing on.
double resources_used
The sum of the values of units used in the attack.
double rating(double aggression, const readonly_context &ai_obj) const
int target_starting_damage
bool is_surrounded
Is true if the units involved in this attack sequence are surrounded.
std::set< map_location > recent_attacks
static manager & get_singleton()
game_info & get_ai_info()
Gets global AI-game info.
virtual const defensive_position & best_defensive_position(const map_location &unit, const move_map &dstsrc, const move_map &srcdst, const move_map &enemy_dstsrc) const =0
virtual unit_stats_cache_t & unit_stats_cache() const =0
virtual const team & current_team() const =0
virtual double get_caution() const =0
virtual double get_leader_aggression() const =0
Computes the statistics of a battle between an attacker and a defender unit.
Encapsulates the map of the game.
bool is_village(const map_location &loc) const
int gives_healing(const map_location &loc) const
bool is_enemy(int n) const
Container associating units to locations.
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
unit_iterator find(std::size_t id)
umap_retval_pair_t insert(const unit_ptr &p)
Inserts the unit pointed to by p into the map.
umap_retval_pair_t move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
@ STATE_POISONED
The unit is slowed - it moves slower and does less damage.
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).
A small explanation about what's going on here: Each action has access to two game_info objects First...
std::multimap< map_location, map_location > move_map
The standard way in which a map of possible moves is recorded.
std::string::const_iterator iterator
std::shared_ptr< unit > unit_ptr
std::vector< double > hp_dist
Resulting probability distribution (might be not as large as max_hp)
double average_hp(unsigned int healing=0) const
What's the average hp (weighted average of hp_dist).
Encapsulates the map of the game.