AI improvements:
- made AI not leave its units idle when it has a large number of units - AI will try to defend its leader better
This commit is contained in:
parent
3b60f0443d
commit
a4d0c5e8fd
4 changed files with 66 additions and 9 deletions
11
src/ai.cpp
11
src/ai.cpp
|
@ -537,12 +537,15 @@ bool ai::retreat_units(std::map<gamemap::location,paths>& possible_moves, const
|
|||
void ai::move_to_targets(std::map<gamemap::location,paths>& possible_moves, move_map& srcdst, move_map& dstsrc, const move_map& enemy_srcdst, const move_map& enemy_dstsrc, unit_map::const_iterator leader)
|
||||
{
|
||||
std::cerr << "finding targets...\n";
|
||||
std::vector<target> targets = find_targets(leader != units_.end());
|
||||
targets.insert(targets.end(),additional_targets_.begin(),
|
||||
additional_targets_.end());
|
||||
std::vector<target> targets;
|
||||
for(;;) {
|
||||
if(targets.empty()) {
|
||||
break;
|
||||
targets = find_targets(leader,enemy_srcdst,enemy_dstsrc);
|
||||
targets.insert(targets.end(),additional_targets_.begin(),
|
||||
additional_targets_.end());
|
||||
if(targets.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "choosing move...\n";
|
||||
|
|
12
src/ai.hpp
12
src/ai.hpp
|
@ -34,6 +34,9 @@ public:
|
|||
|
||||
void do_move();
|
||||
|
||||
team& current_team();
|
||||
const team& current_team() const;
|
||||
|
||||
private:
|
||||
void do_attack(const location& u, const location& target, int weapon);
|
||||
|
||||
|
@ -53,8 +56,6 @@ private:
|
|||
|
||||
bool recruit(const std::string& usage);
|
||||
void move_unit(const location& from, const location& to, std::map<location,paths>& possible_moves);
|
||||
team& current_team();
|
||||
const team& current_team() const;
|
||||
|
||||
void calculate_possible_moves(std::map<location,paths>& moves, move_map& srcdst, move_map& dstsrc, bool enemy, bool assume_full_movement=false);
|
||||
|
||||
|
@ -97,7 +98,12 @@ private:
|
|||
//the strength of its most powerful attack
|
||||
double counter_strength_ratio;
|
||||
|
||||
//the vulnerability is the power projection of enemy units onto the hex
|
||||
//we're standing on. support is the power projection of friendly units.
|
||||
double vulnerability, support;
|
||||
|
||||
//is true if the unit is a threat to our leader
|
||||
bool leader_threat;
|
||||
};
|
||||
|
||||
void do_attack_analysis(
|
||||
|
@ -131,7 +137,7 @@ private:
|
|||
double value;
|
||||
};
|
||||
|
||||
std::vector<target> find_targets(bool has_leader);
|
||||
std::vector<target> find_targets(unit_map::const_iterator leader, const move_map& enemy_srcdst, const move_map& enemy_dstsrc);
|
||||
|
||||
std::pair<location,location> choose_move(std::vector<target>& targets,const move_map& dstsrc, const move_map& enemy_srcdst, const move_map& enemy_dstsrc);
|
||||
|
||||
|
|
|
@ -225,9 +225,22 @@ void ai::attack_analysis::analyze(const gamemap& map,
|
|||
const gamestatus& status,
|
||||
const game_data& info, int num_sims, ai& ai_obj)
|
||||
{
|
||||
const std::map<location,unit>::const_iterator defend_it = units.find(target);
|
||||
const unit_map::const_iterator defend_it = units.find(target);
|
||||
assert(defend_it != units.end());
|
||||
|
||||
//see if the target is a threat to our leader or an ally's leader
|
||||
gamemap::location adj[6];
|
||||
get_adjacent_tiles(target,adj);
|
||||
size_t tile;
|
||||
for(tile = 0; tile != 6; ++tile) {
|
||||
const unit_map::const_iterator leader = units.find(adj[tile]);
|
||||
if(leader != units.end() && leader->second.can_recruit() && ai_obj.current_team().is_enemy(leader->second.side()) == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
leader_threat = (tile != 6);
|
||||
|
||||
target_value = defend_it->second.type().cost();
|
||||
target_value += (double(defend_it->second.experience())/
|
||||
double(defend_it->second.max_experience()))*target_value;
|
||||
|
@ -384,6 +397,10 @@ void ai::attack_analysis::analyze(const gamemap& map,
|
|||
|
||||
double ai::attack_analysis::rating(double aggression) const
|
||||
{
|
||||
if(leader_threat) {
|
||||
aggression = 1.0;
|
||||
}
|
||||
|
||||
double value = chance_to_kill*target_value - avg_losses;
|
||||
|
||||
//prefer to attack already damaged targets
|
||||
|
@ -395,6 +412,10 @@ double ai::attack_analysis::rating(double aggression) const
|
|||
|
||||
value /= ((resources_used/2) + (resources_used/2)*terrain_quality);
|
||||
|
||||
if(leader_threat) {
|
||||
value *= 5.0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,12 +89,39 @@ private:
|
|||
|
||||
};
|
||||
|
||||
std::vector<ai::target> ai::find_targets(bool has_leader)
|
||||
std::vector<ai::target> ai::find_targets(unit_map::const_iterator leader, const move_map& enemy_srcdst, const move_map& enemy_dstsrc)
|
||||
{
|
||||
log_scope("finding targets...");
|
||||
|
||||
const bool has_leader = leader != units_.end();
|
||||
|
||||
std::vector<target> targets;
|
||||
|
||||
//if enemy units are in range of the leader, then we rally to the leader's defense
|
||||
if(has_leader) {
|
||||
const double threat = power_projection(leader->first,enemy_srcdst,enemy_dstsrc);
|
||||
if(threat > 0.0) {
|
||||
//find the specific tiles the enemy can reach, and set them as targets
|
||||
std::vector<gamemap::location> threatened_tiles;
|
||||
gamemap::location adj[6];
|
||||
get_adjacent_tiles(leader->first,adj);
|
||||
for(size_t n = 0; n != 6; ++n) {
|
||||
if(enemy_dstsrc.count(adj[n]) > 0) {
|
||||
threatened_tiles.push_back(adj[n]);
|
||||
}
|
||||
}
|
||||
|
||||
assert(threatened_tiles.size() > 0);
|
||||
|
||||
//divide the threat into the tiles the enemy can reach, and try to
|
||||
//get units to reach those tiles
|
||||
const double value = threat/double(threatened_tiles.size());
|
||||
for(std::vector<gamemap::location>::const_iterator i = threatened_tiles.begin(); i != threatened_tiles.end(); ++i) {
|
||||
targets.push_back(target(*i,value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(has_leader && current_team().village_value() > 0.0) {
|
||||
const std::vector<location>& towers = map_.towers();
|
||||
for(std::vector<location>::const_iterator t = towers.begin(); t != towers.end(); ++t) {
|
||||
|
|
Loading…
Add table
Reference in a new issue