AI refactoring: reworked search for target markers...
...to allow goals to select their own strategy of target marker selection.
This commit is contained in:
parent
5008957499
commit
e5921a8c49
5 changed files with 101 additions and 40 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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("");
|
||||
|
||||
// =======================================================================
|
||||
|
|
Loading…
Add table
Reference in a new issue