AI refactoring: reworked search for target markers...

...to allow goals to select their own strategy of target marker selection.
This commit is contained in:
Iurii Chernyi 2009-12-16 23:24:08 +00:00
parent 5008957499
commit e5921a8c49
5 changed files with 101 additions and 40 deletions

View file

@ -32,7 +32,7 @@ static lg::log_domain log_ai_composite_goal("ai/composite/goal");
#define ERR_AI_COMPOSITE_GOAL LOG_STREAM(err, log_ai_composite_goal)
goal::goal(readonly_context &context, const config &cfg)
: readonly_context_proxy(), cfg_(cfg), value_()
: readonly_context_proxy(), cfg_(cfg)
{
init_readonly_context_proxy(context);
}
@ -41,14 +41,6 @@ goal::goal(readonly_context &context, const config &cfg)
void goal::on_create()
{
if (cfg_.has_attribute("value")) {
try {
value_ = boost::lexical_cast<double>(cfg_["value"]);
} catch (boost::bad_lexical_cast){
ERR_AI_COMPOSITE_GOAL << "bad value of goal"<<std::endl;
value_ = 0;
}
}
}
@ -57,20 +49,12 @@ goal::~goal()
}
//@todo: push to subclass
bool goal::matches_unit(unit_map::const_iterator u)
void goal::add_targets(std::back_insert_iterator< std::vector< target > > /*target_list*/)
{
if (!u.valid()) {
return false;
}
const config &criteria = cfg_.child("criteria");
if (!criteria) {
return false;
}
return u->second.matches_filter(vconfig(criteria),u->first);
}
config goal::to_config() const
{
return cfg_;
@ -96,4 +80,59 @@ bool goal::active() const
return is_active(cfg_["time_of_day"],cfg_["turns"]);
}
void target_unit_goal::on_create()
{
goal::on_create();
if (cfg_.has_attribute("value")) {
try {
value_ = boost::lexical_cast<double>(cfg_["value"]);
} catch (boost::bad_lexical_cast){
ERR_AI_COMPOSITE_GOAL << "bad value of goal"<<std::endl;
value_ = 0;
}
}
}
bool target_unit_goal::matches_unit(unit_map::const_iterator u)
{
if (!u.valid()) {
return false;
}
const config &criteria = cfg_.child("criteria");
if (!criteria) {
return false;
}
return u->second.matches_filter(vconfig(criteria),u->first);
}
void target_unit_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
{
if (!(this)->active()) {
return;
}
unit_map &units = get_info().units;
//find the enemy leaders and explicit targets
unit_map::const_iterator u;
for(u = units.begin(); u != units.end(); ++u) {
if (this->matches_unit(u)) {
LOG_AI_COMPOSITE_GOAL << "found explicit target... " << u->first << " with value: " << this->value() << "\n";
*target_list = target(u->first,this->value(),target::EXPLICIT);
}
}
}
target_unit_goal::target_unit_goal(readonly_context &context, const config &cfg)
: goal(context,cfg)
{
}
} //end of namespace ai

View file

@ -32,6 +32,8 @@
#include "../contexts.hpp"
#include "../game_info.hpp"
//included for 'target' markers
#include "../default/contexts.hpp"
#include <map>
#include <stack>
@ -48,7 +50,7 @@ public:
virtual ~goal();
virtual bool matches_unit(unit_map::const_iterator u);
virtual void add_targets(std::back_insert_iterator< std::vector< target > > target_list);
config to_config() const;
@ -66,18 +68,35 @@ public:
bool redeploy(const config &cfg);
protected:
config cfg_;
};
class target_unit_goal : public goal {
public:
target_unit_goal(readonly_context &context, const config &cfg);
virtual void add_targets(std::back_insert_iterator< std::vector< target > > target_list);
virtual void on_create();
private:
virtual bool matches_unit(unit_map::const_iterator u);
double value()
{
return value_;
}
private:
config cfg_;
double value_;
};
class goal_factory{
public:
typedef boost::shared_ptr< goal_factory > factory_ptr;

View file

@ -230,6 +230,8 @@ std::vector<target> default_ai_context_impl::find_targets(unit_map::const_iterat
move_map friends_srcdst, friends_dstsrc;
calculate_possible_moves(friends_possible_moves,friends_srcdst,friends_dstsrc,false,true);
//=== start getting targets
//if enemy units are in range of the leader, then we target the enemies who are in range.
if(has_leader) {
const double threat = power_projection(leader->first,enemy_dstsrc);
@ -313,8 +315,8 @@ std::vector<target> default_ai_context_impl::find_targets(unit_map::const_iterat
//find the enemy leaders and explicit targets
unit_map::const_iterator u;
for(u = units_.begin(); u != units_.end(); ++u) {
if (get_leader_value()>0.0) {
if (get_leader_value()>0.0) {
for(u = units_.begin(); u != units_.end(); ++u) {
//is a visible enemy leader
if (u->second.can_recruit() && current_team().is_enemy(u->second.side())
&& !u->second.invisible(u->first, units_, teams_)) {
@ -323,22 +325,22 @@ std::vector<target> default_ai_context_impl::find_targets(unit_map::const_iterat
targets.push_back(target(u->first,get_leader_value(),target::LEADER));
}
}
//explicit targets for this team
for(std::vector<goal_ptr>::iterator j = goals.begin();
j != goals.end(); ++j) {
if (!(*j)->active()) {
continue;
}
if ((*j)->matches_unit(u)) {
LOG_AI << "found explicit target... " << u->first << " with value: " << (*j)->value() << "\n";
targets.push_back(target(u->first,(*j)->value(),target::EXPLICIT));
}
}
}
//explicit targets for this team
for(std::vector<goal_ptr>::iterator j = goals.begin();
j != goals.end(); ++j) {
if (!(*j)->active()) {
continue;
}
(*j)->add_targets(std::back_inserter(targets));
}
//=== end getting targets
std::vector<double> new_values;
for(std::vector<target>::iterator i = targets.begin();

View file

@ -44,6 +44,7 @@ struct target {
double value;
TYPE type;
//TODO ai goals: this is a 'target' marker class which should be expanded with additional information which is generic enough to apply to all targets.
};

View file

@ -119,7 +119,7 @@ static register_candidate_action_factory<testing_ai_default::leader_control_phas
// Goals
// =======================================================================
static register_goal_factory<goal>
static register_goal_factory<target_unit_goal>
goal_factory("");
// =======================================================================