AI Refactoring: moved struct attack_analysis out of ai_default

This commit is contained in:
Iurii Chernyi 2009-06-18 20:39:37 +00:00
parent 3cc9edcd15
commit 14381bbc29
4 changed files with 98 additions and 97 deletions

View File

@ -1971,7 +1971,7 @@ void ai_default::get_inputs(std::vector<game_logic::formula_input>* inputs) cons
}
variant ai_default::attack_analysis::get_value(const std::string& key) const
variant attack_analysis::get_value(const std::string& key) const
{
using namespace game_logic;
if(key == "target") {
@ -2026,7 +2026,7 @@ variant ai_default::attack_analysis::get_value(const std::string& key) const
}
}
void ai_default::attack_analysis::get_inputs(std::vector<game_logic::formula_input>* inputs) const
void attack_analysis::get_inputs(std::vector<game_logic::formula_input>* inputs) const
{
using namespace game_logic;
inputs->push_back(formula_input("target", FORMULA_READ_ONLY));

View File

@ -37,6 +37,89 @@ class formula_ai;
namespace ai {
struct attack_analysis : public game_logic::formula_callable
{
attack_analysis() :
game_logic::formula_callable(),
target(),
movements(),
target_value(0.0),
avg_losses(0.0),
chance_to_kill(0.0),
avg_damage_inflicted(0.0),
target_starting_damage(0),
avg_damage_taken(0.0),
resources_used(0.0),
terrain_quality(0.0),
alternative_terrain_quality(0.0),
vulnerability(0.0),
support(0.0),
leader_threat(false),
uses_leader(false),
is_surrounded(false)
{
}
void analyze(const gamemap& map, unit_map& units,
const std::vector<team>& teams,
const gamestatus& status, const tod_manager& tod_mng,
class ai_default& ai_obj,
const move_map& dstsrc, const move_map& srcdst,
const move_map& enemy_dstsrc, double aggression);
double rating(double aggression, class ai_default& ai_obj) const;
variant get_value(const std::string& key) const;
void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
map_location target;
std::vector<std::pair<map_location,map_location> > movements;
/** The value of the unit being targeted. */
double target_value;
/** The value on average, of units lost in the combat. */
double avg_losses;
/** Estimated % chance to kill the unit. */
double chance_to_kill;
/** The average hitpoints damage inflicted. */
double avg_damage_inflicted;
int target_starting_damage;
/** The average hitpoints damage taken. */
double avg_damage_taken;
/** The sum of the values of units used in the attack. */
double resources_used;
/** The weighted average of the % chance to hit each attacking unit. */
double terrain_quality;
/**
* The weighted average of the % defense of the best possible terrain
* that the attacking units could reach this turn, without attacking
* (good for comparison to see just how good/bad 'terrain_quality' is).
*/
double alternative_terrain_quality;
/**
* 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;
/** Is true if this attack sequence makes use of the leader. */
bool uses_leader;
/** Is true if the units involved in this attack sequence are surrounded. */
bool is_surrounded;
};
/** A trivial ai that sits around doing absolutely nothing. */
class idle_ai : public readwrite_context_proxy, public interface {
public:
@ -175,88 +258,6 @@ protected:
const std::map<location,paths>& possible_moves) const;
public:
struct attack_analysis : public game_logic::formula_callable
{
attack_analysis() :
game_logic::formula_callable(),
target(),
movements(),
target_value(0.0),
avg_losses(0.0),
chance_to_kill(0.0),
avg_damage_inflicted(0.0),
target_starting_damage(0),
avg_damage_taken(0.0),
resources_used(0.0),
terrain_quality(0.0),
alternative_terrain_quality(0.0),
vulnerability(0.0),
support(0.0),
leader_threat(false),
uses_leader(false),
is_surrounded(false)
{
}
void analyze(const gamemap& map, unit_map& units,
const std::vector<team>& teams,
const gamestatus& status, const tod_manager& tod_mng,
class ai_default& ai_obj,
const move_map& dstsrc, const move_map& srcdst,
const move_map& enemy_dstsrc, double aggression);
double rating(double aggression, class ai_default& ai_obj) const;
variant get_value(const std::string& key) const;
void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
map_location target;
std::vector<std::pair<map_location,map_location> > movements;
/** The value of the unit being targeted. */
double target_value;
/** The value on average, of units lost in the combat. */
double avg_losses;
/** Estimated % chance to kill the unit. */
double chance_to_kill;
/** The average hitpoints damage inflicted. */
double avg_damage_inflicted;
int target_starting_damage;
/** The average hitpoints damage taken. */
double avg_damage_taken;
/** The sum of the values of units used in the attack. */
double resources_used;
/** The weighted average of the % chance to hit each attacking unit. */
double terrain_quality;
/**
* The weighted average of the % defense of the best possible terrain
* that the attacking units could reach this turn, without attacking
* (good for comparison to see just how good/bad 'terrain_quality' is).
*/
double alternative_terrain_quality;
/**
* 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;
/** Is true if this attack sequence makes use of the leader. */
bool uses_leader;
/** Is true if the units involved in this attack sequence are surrounded. */
bool is_surrounded;
};
protected:

View File

@ -297,7 +297,7 @@ void ai_default::do_attack_analysis(
}
void ai_default::attack_analysis::analyze(const gamemap& map, unit_map& units,
void attack_analysis::analyze(const gamemap& map, unit_map& units,
const std::vector<team>& teams,
const gamestatus& status, const tod_manager& tod_mng,
class ai_default& ai_obj,
@ -353,7 +353,7 @@ void ai_default::attack_analysis::analyze(const gamemap& map, unit_map& units,
double prob_dead_already = 0.0;
assert(!movements.empty());
std::vector<std::pair<location,location> >::const_iterator m;
std::vector<std::pair<map_location,map_location> >::const_iterator m;
battle_context *prev_bc = NULL;
const combatant *prev_def = NULL;
@ -376,9 +376,9 @@ void ai_default::attack_analysis::analyze(const gamemap& map, unit_map& units,
// This cache is only about 99% correct, but speeds up evaluation by about 1000 times.
// We recalculate when we actually attack.
std::map<std::pair<location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >::iterator usc;
std::map<std::pair<map_location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >::iterator usc;
if(up->second.type()) {
usc = ai_obj.unit_stats_cache_.find(std::pair<location, const unit_type *>(target, up->second.type()));
usc = ai_obj.unit_stats_cache_.find(std::pair<map_location, const unit_type *>(target, up->second.type()));
} else {
usc = ai_obj.unit_stats_cache_.end();
}
@ -400,8 +400,8 @@ void ai_default::attack_analysis::analyze(const gamemap& map, unit_map& units,
prev_def = &bc->get_defender_combatant(prev_def);
if (!from_cache && up->second.type()) {
ai_obj.unit_stats_cache_.insert(std::pair<std::pair<location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >
(std::pair<location, const unit_type *>(target, up->second.type()),
ai_obj.unit_stats_cache_.insert(std::pair<std::pair<map_location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >
(std::pair<map_location, const unit_type *>(target, up->second.type()),
std::pair<battle_context::unit_stats,battle_context::unit_stats>(bc->get_attacker_stats(),
bc->get_defender_stats())));
}
@ -513,7 +513,7 @@ void ai_default::attack_analysis::analyze(const gamemap& map, unit_map& units,
}
}
double ai_default::attack_analysis::rating(double aggression, ai_default& ai_obj) const
double attack_analysis::rating(double aggression, ai_default& ai_obj) const
{
if(leader_threat) {
aggression = 1.0;
@ -599,7 +599,7 @@ double ai_default::attack_analysis::rating(double aggression, ai_default& ai_obj
return value;
}
std::vector<ai_default::attack_analysis> ai_default::analyze_targets(
std::vector<attack_analysis> ai_default::analyze_targets(
const move_map& srcdst, const move_map& dstsrc,
const move_map& enemy_srcdst, const move_map& enemy_dstsrc
)

View File

@ -573,7 +573,7 @@ public:
private:
variant execute(const formula_callable& variables) const {
variant attack = args()[0]->evaluate(variables);
ai::ai_default::attack_analysis* analysis = convert_variant<ai::ai_default::attack_analysis>(attack);
ai::attack_analysis* analysis = convert_variant<ai::attack_analysis>(attack);
unit_map units_with_moves(ai_.get_info().units);
typedef std::pair<map_location, map_location> mv;
foreach (const mv &m, analysis->movements) {
@ -2023,7 +2023,7 @@ bool formula_ai::execute_variant(const variant& var, bool commandline)
const move_callable* move = try_convert_variant<move_callable>(*i);
const move_partial_callable* move_partial = try_convert_variant<move_partial_callable>(*i);
const attack_callable* attack = try_convert_variant<attack_callable>(*i);
const ai_default::attack_analysis* attack_analysis = try_convert_variant<ai_default::attack_analysis>(*i);
const ai::attack_analysis* attack_analysis = try_convert_variant<ai::attack_analysis>(*i);
const recruit_callable* recruit_command = try_convert_variant<recruit_callable>(*i);
const set_var_callable* set_var_command = try_convert_variant<set_var_callable>(*i);
const set_unit_var_callable* set_unit_var_command = try_convert_variant<set_unit_var_callable>(*i);
@ -2258,10 +2258,10 @@ variant formula_ai::get_value(const std::string& key) const
return attacks_cache_;
}
std::vector<attack_analysis> attacks = const_cast<formula_ai*>(this)->analyze_targets(srcdst_, dstsrc_, enemy_srcdst_, enemy_dstsrc_);
std::vector<ai::attack_analysis> attacks = const_cast<formula_ai*>(this)->analyze_targets(srcdst_, dstsrc_, enemy_srcdst_, enemy_dstsrc_);
std::vector<variant> vars;
for(std::vector<attack_analysis>::const_iterator i = attacks.begin(); i != attacks.end(); ++i) {
vars.push_back(variant(new attack_analysis(*i)));
for(std::vector<ai::attack_analysis>::const_iterator i = attacks.begin(); i != attacks.end(); ++i) {
vars.push_back(variant(new ai::attack_analysis(*i)));
}
attacks_cache_ = variant(&vars);