refactoring of ai component model to a more object-oriented approach.
[modify_ai] now works fully and uniformly, with less code duplication. added the ability to see all ai components from gamestate_inspector.
This commit is contained in:
parent
706395577b
commit
1462573062
29 changed files with 759 additions and 298 deletions
|
@ -65,6 +65,7 @@
|
|||
<Unit filename="..\..\src\ai\composite\engine_fai.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\goal.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\goal.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\property_handler.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\rca.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\rca.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\stage.cpp" />
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
<Unit filename="..\..\src\ai\composite\engine_fai.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\goal.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\goal.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\property_handler.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\rca.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\rca.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\stage.cpp" />
|
||||
|
|
|
@ -6194,6 +6194,10 @@
|
|||
RelativePath="..\..\src\ai\composite\goal.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\property_handler.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\rca.hpp"
|
||||
>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
|
@ -23,6 +24,9 @@
|
|||
#include "../../foreach.hpp"
|
||||
#include "../../log.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace ai {
|
||||
|
||||
static lg::log_domain log_ai_composite("ai/composite");
|
||||
|
@ -51,50 +55,76 @@ void ai_composite::on_create()
|
|||
|
||||
// init the composite ai stages
|
||||
foreach(const config &cfg_element, cfg_.child_range("stage")){
|
||||
add_stage(-1,cfg_element);
|
||||
add_stage(cfg_element);
|
||||
}
|
||||
|
||||
config cfg;
|
||||
cfg["engine"] = "fai";
|
||||
engine_ptr e_ptr = get_engine(cfg);
|
||||
engine_ptr e_ptr = get_engine_by_cfg(cfg);
|
||||
if (e_ptr) {
|
||||
e_ptr->set_ai_context(this);
|
||||
}
|
||||
|
||||
boost::function2<void, std::vector<engine_ptr>&, const config&> factory_engines =
|
||||
boost::bind(&ai::ai_composite::create_engine,*this,_1,_2);
|
||||
|
||||
boost::function2<void, std::vector<goal_ptr>&, const config&> factory_goals =
|
||||
boost::bind(&ai::ai_composite::create_goal,*this,_1,_2);
|
||||
|
||||
boost::function2<void, std::vector<stage_ptr>&, const config&> factory_stages =
|
||||
boost::bind(&ai::ai_composite::create_stage,*this,_1,_2);
|
||||
|
||||
register_vector_property("engine",get_engines(), factory_engines);
|
||||
register_vector_property("goal",get_goals(), factory_goals);
|
||||
register_vector_property("stage",stages_, factory_stages);
|
||||
|
||||
register_aspect_property("aspect",get_aspects());
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ai_composite::create_stage(std::vector<stage_ptr> &stages, const config &cfg)
|
||||
{
|
||||
engine::parse_stage_from_config(*this,cfg,std::back_inserter(stages));
|
||||
}
|
||||
|
||||
|
||||
void ai_composite::create_goal(std::vector<goal_ptr> &goals, const config &cfg)
|
||||
{
|
||||
engine::parse_goal_from_config(*this,cfg,std::back_inserter(goals));
|
||||
}
|
||||
|
||||
|
||||
void ai_composite::create_engine(std::vector<engine_ptr> &engines, const config &cfg)
|
||||
{
|
||||
engine::parse_engine_from_config(*this,cfg,std::back_inserter(engines));
|
||||
}
|
||||
|
||||
ai_composite::~ai_composite()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ai_composite::add_stage(int pos, const config &cfg)
|
||||
bool ai_composite::add_stage(const config &cfg)
|
||||
{
|
||||
if (pos<0) {
|
||||
pos = stages_.size();
|
||||
}
|
||||
std::vector< stage_ptr > stages;
|
||||
engine::parse_stage_from_config(*this,cfg,std::back_inserter(stages));
|
||||
create_stage(stages,cfg);
|
||||
int j=0;
|
||||
foreach (stage_ptr b, stages ){
|
||||
stages_.insert(stages_.begin()+pos+j,b);
|
||||
stages_.push_back(b);
|
||||
j++;
|
||||
}
|
||||
return (j>0);
|
||||
}
|
||||
|
||||
|
||||
bool ai_composite::add_goal(int pos, const config &cfg)
|
||||
bool ai_composite::add_goal(const config &cfg)
|
||||
{
|
||||
if (pos<0) {
|
||||
pos = get_goals().size();
|
||||
}
|
||||
std::vector< goal_ptr > goals;
|
||||
engine::parse_goal_from_config(*this,cfg,std::back_inserter(goals));
|
||||
create_goal(goals,cfg);
|
||||
int j=0;
|
||||
foreach (goal_ptr b, goals ){
|
||||
get_goals().insert(get_goals().begin()+pos+j,b);
|
||||
get_goals().push_back(b);
|
||||
j++;
|
||||
}
|
||||
return (j>0);
|
||||
|
@ -108,11 +138,30 @@ void ai_composite::play_turn(){
|
|||
}
|
||||
|
||||
|
||||
const std::string& ai_composite::get_id() const
|
||||
{
|
||||
return cfg_["id"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& ai_composite::get_name() const
|
||||
{
|
||||
return cfg_["name"];
|
||||
}
|
||||
|
||||
|
||||
const std::string& ai_composite::get_engine() const
|
||||
{
|
||||
return cfg_["engine"];
|
||||
}
|
||||
|
||||
|
||||
std::string ai_composite::evaluate(const std::string& str)
|
||||
{
|
||||
config cfg;
|
||||
cfg["engine"] = "fai";//@todo 1.9 : consider allowing other engines to evaluate
|
||||
engine_ptr e_ptr = get_engine(cfg);
|
||||
engine_ptr e_ptr = get_engine_by_cfg(cfg);
|
||||
if (!e_ptr) {
|
||||
return interface::evaluate(str);
|
||||
}
|
||||
|
@ -159,118 +208,4 @@ config ai_composite::to_config() const
|
|||
return cfg;
|
||||
}
|
||||
|
||||
component* ai_composite::get_child(const path_element &child)
|
||||
{
|
||||
if (child.property=="aspect") {
|
||||
//ASPECT
|
||||
aspect_map::const_iterator a = get_aspects().find(child.id);
|
||||
if (a!=get_aspects().end()){
|
||||
return &*a->second;
|
||||
}
|
||||
return NULL;
|
||||
} else if (child.property=="stage") {
|
||||
//std::vector< stage_ptr >::iterator i = std::find_if(stages_.begin(),stages_.end(),path_element_matches< stage_ptr >(child));
|
||||
//if (i!=stages_.end()){
|
||||
// return &*(*i);
|
||||
//}
|
||||
return NULL;
|
||||
} else if (child.property=="engine") {
|
||||
//ENGINE
|
||||
//@todo 1.7.5 implement
|
||||
return NULL;
|
||||
} else if (child.property=="goal") {
|
||||
//std::vector< goal_ptr >::iterator i = std::find_if(get_goals().begin(),get_goals().end(),path_element_matches< goal_ptr >(child));
|
||||
//if (i!=get_goals().end()){
|
||||
// return &*(*i);
|
||||
//}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//OOPS
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool ai_composite::add_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
if (child.property=="aspect") {
|
||||
//ASPECT
|
||||
return false;//adding aspects directly is not supported - aspect['foo'].facet should be added instead
|
||||
} else if (child.property=="stage") {
|
||||
std::vector< stage_ptr >::iterator i = std::find_if(stages_.begin(),stages_.end(),path_element_matches< stage_ptr >(child));
|
||||
return add_stage(i-stages_.begin(),cfg);
|
||||
} else if (child.property=="engine") {
|
||||
//ENGINE
|
||||
//@todo 1.7.5 implement
|
||||
return false;
|
||||
} else if (child.property=="goal") {
|
||||
std::vector< goal_ptr >::iterator i = std::find_if(get_goals().begin(),get_goals().end(),path_element_matches< goal_ptr >(child));
|
||||
return add_goal(i-get_goals().begin(),cfg);
|
||||
}
|
||||
|
||||
//OOPS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ai_composite::change_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
if (child.property=="aspect") {
|
||||
//ASPECT
|
||||
return false;//changing aspects directly is not supported - aspect['foo'].facet should be changed instead
|
||||
} else if (child.property=="stage") {
|
||||
std::vector< stage_ptr >::iterator i = std::find_if(stages_.begin(),stages_.end(),path_element_matches< stage_ptr >(child));
|
||||
if (i!=stages_.end()) {
|
||||
//@todo 1.7.5 implement
|
||||
//return (*i)->redeploy(cfg);
|
||||
}
|
||||
return false;
|
||||
|
||||
} else if (child.property=="engine") {
|
||||
//ENGINE
|
||||
//@todo 1.7.5 implement
|
||||
return false;
|
||||
} else if (child.property=="goal") {
|
||||
std::vector< goal_ptr >::iterator i = std::find_if(get_goals().begin(),get_goals().end(),path_element_matches< goal_ptr >(child));
|
||||
if (i!=get_goals().end()) {
|
||||
return (*i)->redeploy(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
//OOPS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ai_composite::delete_child(const path_element &child)
|
||||
{
|
||||
if (child.property=="aspect") {
|
||||
//ASPECT
|
||||
return false;//deleting aspects directly is not supported - aspect['foo'].facet should be deleted instead
|
||||
} else if (child.property=="stage") {
|
||||
std::vector< stage_ptr >::iterator i = std::find_if(stages_.begin(),stages_.end(),path_element_matches< stage_ptr >(child));
|
||||
if (i!=stages_.end()) {
|
||||
stages_.erase(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (child.property=="engine") {
|
||||
//ENGINE
|
||||
//@todo 1.7.5 implement
|
||||
return false;
|
||||
} else if (child.property=="goal") {
|
||||
std::vector< goal_ptr >::iterator i = std::find_if(get_goals().begin(),get_goals().end(),path_element_matches< goal_ptr >(child));
|
||||
if (i!=get_goals().end()) {
|
||||
get_goals().erase(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//OOPS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -90,10 +90,19 @@ public:
|
|||
void switch_side(side_number side);
|
||||
|
||||
|
||||
virtual bool add_goal(int pos, const config &cfg);
|
||||
virtual bool add_goal(const config &cfg);
|
||||
|
||||
|
||||
virtual bool add_stage(int pos, const config &cfg);
|
||||
virtual bool add_stage(const config &cfg);
|
||||
|
||||
|
||||
void create_stage(std::vector<stage_ptr> &stages, const config &cfg);
|
||||
|
||||
|
||||
void create_goal(std::vector<goal_ptr> &goals, const config &cfg);
|
||||
|
||||
|
||||
void create_engine(std::vector<engine_ptr> &engines, const config &cfg);
|
||||
|
||||
|
||||
void on_create();
|
||||
|
@ -104,16 +113,13 @@ public:
|
|||
virtual ai_context& get_ai_context();
|
||||
|
||||
|
||||
virtual component* get_child(const path_element &child);
|
||||
const std::string& get_id() const;
|
||||
|
||||
|
||||
virtual bool add_child(const path_element &child, const config &cfg);
|
||||
const std::string& get_name() const;
|
||||
|
||||
|
||||
virtual bool change_child(const path_element &child, const config &cfg);
|
||||
|
||||
|
||||
virtual bool delete_child(const path_element &child);
|
||||
const std::string& get_engine() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -76,6 +76,13 @@ const std::string& aspect::get_name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
|
||||
const std::string& aspect::get_engine() const
|
||||
{
|
||||
return engine_;
|
||||
}
|
||||
|
||||
|
||||
bool aspect::redeploy(const config &cfg, const std::string& /*id*/)
|
||||
{
|
||||
if (invalidate_on_turn_start_) {
|
||||
|
@ -135,6 +142,11 @@ config aspect::to_config() const
|
|||
}
|
||||
|
||||
|
||||
bool aspect::delete_all_facets()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
known_aspect::known_aspect(const std::string &name)
|
||||
: name_(name)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/pointer_cast.hpp>
|
||||
|
||||
|
@ -82,6 +83,9 @@ public:
|
|||
virtual config to_config() const;
|
||||
|
||||
|
||||
virtual bool delete_all_facets();
|
||||
|
||||
|
||||
void handle_generic_event(const std::string &/*event_name*/)
|
||||
{
|
||||
invalidate();
|
||||
|
@ -100,6 +104,9 @@ public:
|
|||
const std::string& get_id() const;
|
||||
|
||||
|
||||
const std::string& get_engine() const;
|
||||
|
||||
|
||||
static lg::log_domain& log();
|
||||
|
||||
protected:
|
||||
|
@ -242,7 +249,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
boost::shared_ptr<typesafe_aspect <T> > &where_;
|
||||
aspect_map &aspects_;
|
||||
|
@ -272,11 +278,29 @@ public:
|
|||
default_ = b;
|
||||
}
|
||||
}
|
||||
|
||||
boost::function2<void, typename aspect_type<T>::typesafe_ptr_vector&, const config&> factory_facets =
|
||||
boost::bind(&ai::composite_aspect<T>::create_facet,*this,_1,_2);
|
||||
|
||||
register_vector_property("facet",facets_, factory_facets);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void create_facet( typename aspect_type<T>::typesafe_ptr_vector &facets, const config &cfg)
|
||||
{
|
||||
std::vector<aspect_ptr> facets_base;
|
||||
engine::parse_aspect_from_config(*this,cfg,this->get_id(),std::back_inserter(facets_base));
|
||||
foreach (aspect_ptr a, facets_base ){
|
||||
typename aspect_type<T>::typesafe_ptr b = boost::dynamic_pointer_cast< typesafe_aspect<T> > (a);
|
||||
facets.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void recalculate() const
|
||||
{
|
||||
//@todo 1.7.5 optimize in case of an aspect which returns variant
|
||||
//@todo 1.9 optimize in case of an aspect which returns variant
|
||||
//typedef std::vector< boost::shared_ptr< typesafe_aspect < T > > >::reverse_const_iterator Iter;
|
||||
|
||||
foreach (const typename aspect_type<T>::typesafe_ptr &f, make_pair(facets_.rbegin(),facets_.rend())) {
|
||||
|
@ -321,55 +345,11 @@ public:
|
|||
}
|
||||
|
||||
|
||||
virtual component* get_child(const path_element &child)
|
||||
virtual bool delete_all_facets()
|
||||
{
|
||||
if (child.property!="facet") {
|
||||
return NULL;
|
||||
}
|
||||
typename aspect_type<T>::typesafe_ptr_vector::iterator i = std::find_if(facets_.begin(),facets_.end(),path_element_matches< typename aspect_type<T>::typesafe_ptr >(child));
|
||||
if (i!=facets_.end()){
|
||||
return &*(*i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
virtual bool add_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
if (child.property!="facet") {
|
||||
return false;
|
||||
}
|
||||
typename aspect_type<T>::typesafe_ptr_vector::iterator i = std::find_if(facets_.begin(),facets_.end(),path_element_matches< typename aspect_type<T>::typesafe_ptr >(child));
|
||||
LOG_STREAM(info, aspect::log()) << "adding a new child facet to composite aspect["<<this->get_id()<<"]"<< std::endl;
|
||||
return add_facet(i-facets_.begin(),cfg);
|
||||
}
|
||||
|
||||
|
||||
virtual bool change_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
if (child.property!="facet") {
|
||||
return false;
|
||||
}
|
||||
typename aspect_type<T>::typesafe_ptr_vector::iterator i = std::find_if(facets_.begin(),facets_.end(),path_element_matches< typename aspect_type<T>::typesafe_ptr >(child));
|
||||
if (i!=facets_.end()){
|
||||
return (*i)->redeploy(cfg,this->get_id());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool delete_child(const path_element &child)
|
||||
{
|
||||
if (child.property!="facet") {
|
||||
return false;
|
||||
}
|
||||
typename aspect_type<T>::typesafe_ptr_vector::iterator i = std::find_if(facets_.begin(),facets_.end(),path_element_matches< typename aspect_type<T>::typesafe_ptr >(child));
|
||||
if (i!=facets_.end()) {
|
||||
facets_.erase(i);
|
||||
this->invalidate();//@todo: invalidate only if facet was active
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool b = !facets_.empty();
|
||||
facets_.clear();
|
||||
return b;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
#include "component.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "../formula/ai.hpp"
|
||||
#include "../../log.hpp"
|
||||
#include "../../foreach.hpp"
|
||||
|
||||
#include "../formula/ai.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
@ -33,32 +35,6 @@ static lg::log_domain log_ai_composite_component("ai/composite/component");
|
|||
#define ERR_AI_COMPOSITE LOG_STREAM(err, log_ai_composite_component)
|
||||
|
||||
|
||||
component* component::get_child(const path_element &/*child*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool component::add_child(const path_element &/*child*/, const config &/*cfg*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool component::change_child(const path_element &/*child*/, const config &/*cfg*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool component::delete_child(const path_element &/*child*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[modify_ai]
|
||||
path = "stage[fallback]
|
||||
|
@ -85,6 +61,68 @@ bool component::delete_child(const path_element &/*child*/)
|
|||
*/
|
||||
|
||||
|
||||
component* component::get_child(const path_element &child)
|
||||
{
|
||||
std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
|
||||
if (i!=property_handlers_.end()) {
|
||||
return i->second->handle_get(child);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool component::add_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
|
||||
if (i!=property_handlers_.end()) {
|
||||
return i->second->handle_add(child,cfg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool component::change_child(const path_element &child, const config &cfg)
|
||||
{
|
||||
std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
|
||||
if (i!=property_handlers_.end()) {
|
||||
return i->second->handle_change(child,cfg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool component::delete_child(const path_element &child)
|
||||
{
|
||||
std::map<std::string, property_handler_ptr>::iterator i = property_handlers_.find(child.property);
|
||||
if (i!=property_handlers_.end()) {
|
||||
return i->second->handle_delete(child);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::vector<component*> component::get_children(const std::string &type)
|
||||
{
|
||||
std::vector<component*> components;
|
||||
property_handler_map::iterator i = property_handlers_.find(type);
|
||||
if (i!=property_handlers_.end()) {
|
||||
return i->second->handle_get_children();
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> component::get_children_types()
|
||||
{
|
||||
std::vector<std::string> types;
|
||||
foreach (property_handler_map::value_type &ph, property_handlers_) {
|
||||
types.push_back(ph.first);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
static component *find_component(component *root, const std::string &path, path_element &tail)
|
||||
{
|
||||
if (root==NULL) {
|
||||
|
@ -115,7 +153,7 @@ static component *find_component(component *root, const std::string &path, path_
|
|||
pe.position = -2;
|
||||
}
|
||||
}
|
||||
DBG_AI_COMPOSITE << "adding path element: "<< pe << std::endl;
|
||||
//DBG_AI_COMPOSITE << "adding path element: "<< pe << std::endl;
|
||||
elements.push_back(pe);
|
||||
}
|
||||
if (elements.size()<1) {
|
||||
|
@ -177,8 +215,47 @@ bool component_manager::delete_component(component *root, const std::string &pat
|
|||
}
|
||||
|
||||
|
||||
static void print_component(component *root, const std::string &type, std::stringstream &s, int offset)
|
||||
{
|
||||
std::stringstream offset_ss;
|
||||
for (int i=0;i<offset;++i) {
|
||||
offset_ss<<" ";
|
||||
}
|
||||
const std::string &offset_str = offset_ss.str();
|
||||
|
||||
const std::vector<std::string> &t_list = root->get_children_types();
|
||||
|
||||
s << offset_str << type<<"["<<root->get_id() <<"] "<<root->get_engine()<<" "<<root->get_name()<< std::endl;
|
||||
|
||||
foreach (std::string t, t_list) {
|
||||
std::vector<component*> c_list = root->get_children(t);
|
||||
foreach (component *c, c_list) {
|
||||
print_component(c,t,s,offset+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string component_manager::print_component_tree(component *root, const std::string &path)
|
||||
{
|
||||
path_element tail;
|
||||
component *c;
|
||||
if (!path.empty()) {
|
||||
c = find_component(root,path,tail);
|
||||
if (c==NULL) {
|
||||
ERR_AI_COMPOSITE << "unable to find component" <<std::endl;
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
c = root;
|
||||
}
|
||||
std::stringstream s;
|
||||
print_component(c, "", s, 0);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} //end of namespace ai
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const ai::path_element &e)
|
||||
{
|
||||
o << "property["<<e.property<<"] id["<<e.id <<"] position["<<e.position<<"]"<<std::endl;
|
||||
|
|
|
@ -20,11 +20,14 @@
|
|||
#ifndef AI_COMPOSITE_COMPONENT_HPP_INCLUDED
|
||||
#define AI_COMPOSITE_COMPONENT_HPP_INCLUDED
|
||||
|
||||
#include "../../global.hpp"
|
||||
|
||||
#include "../game_info.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "property_handler.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
|
@ -35,29 +38,37 @@
|
|||
//============================================================================
|
||||
namespace ai {
|
||||
|
||||
|
||||
struct path_element {
|
||||
path_element()
|
||||
: property()
|
||||
, id()
|
||||
, position(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string property;
|
||||
std::string id;
|
||||
int position;
|
||||
};
|
||||
|
||||
|
||||
class component {
|
||||
public:
|
||||
component() {};
|
||||
virtual const std::string& get_id() const = 0;
|
||||
virtual const std::string& get_name() const = 0;
|
||||
virtual const std::string& get_engine() const = 0;
|
||||
virtual ~component() {};
|
||||
virtual component* get_child(const path_element &child);
|
||||
virtual std::vector<component*> get_children(const std::string &type);
|
||||
virtual std::vector<std::string> get_children_types();
|
||||
virtual bool change_child(const path_element &child, const config &cfg);
|
||||
virtual bool add_child(const path_element &child, const config &cfg);
|
||||
virtual bool delete_child(const path_element &child);
|
||||
|
||||
template<typename X>
|
||||
void register_vector_property(const std::string &property, std::vector< boost::shared_ptr<X> > &values_, boost::function2<void, std::vector< boost::shared_ptr<X> >&, const config&> construction_factory)
|
||||
{
|
||||
property_handlers_.insert(make_pair(property,property_handler_ptr(new vector_property_handler<X>(property,values_,construction_factory))));
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
void register_aspect_property(const std::string &property, std::map< std::string, boost::shared_ptr<X> > &aspects_)
|
||||
{
|
||||
property_handlers_.insert(make_pair(property,property_handler_ptr(new aspect_property_handler<X>(property,aspects_))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef std::map<std::string,property_handler_ptr> property_handler_map;
|
||||
private:
|
||||
property_handler_map property_handlers_;
|
||||
};
|
||||
|
||||
class component_manager {
|
||||
|
@ -65,40 +76,12 @@ public:
|
|||
static bool add_component(component *root, const std::string &path, const config &cfg);
|
||||
static bool change_component(component *root, const std::string &path, const config &cfg);
|
||||
static bool delete_component(component *root, const std::string &path);
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
class path_element_matches{
|
||||
public:
|
||||
path_element_matches(const path_element &element)
|
||||
: count_(0), element_(element)
|
||||
{
|
||||
}
|
||||
virtual ~path_element_matches(){}
|
||||
|
||||
bool operator()(const T& t)
|
||||
{
|
||||
if ( (!element_.id.empty()) && (element_.id == t->get_id()) ) {
|
||||
return true;
|
||||
}
|
||||
if (count_ == element_.position) {
|
||||
return true;
|
||||
}
|
||||
count_++;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
int count_;
|
||||
path_element element_;
|
||||
static std::string print_component_tree(component *root, const std::string &path);
|
||||
};
|
||||
|
||||
|
||||
} //end of namespace ai
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const ai::path_element &e);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -31,9 +31,9 @@ static lg::log_domain log_ai_composite_engine("ai/composite/engine");
|
|||
#define ERR_AI_COMPOSITE_ENGINE LOG_STREAM(err, log_ai_composite_engine)
|
||||
|
||||
engine::engine( readonly_context &context, const config &cfg )
|
||||
: ai_(context), engine_(cfg["engine"])
|
||||
: ai_(context), engine_(cfg["engine"]), id_(cfg["id"]), name_(cfg["name"])
|
||||
{
|
||||
LOG_AI_COMPOSITE_ENGINE << "side "<< ai_.get_side() << " : "<<" created engine with name=["<<cfg["name"]<<"]"<<std::endl;
|
||||
LOG_AI_COMPOSITE_ENGINE << "side "<< ai_.get_side() << " : "<<" created engine with name=["<<name_<<"]"<<std::endl;
|
||||
}
|
||||
|
||||
engine::~engine()
|
||||
|
@ -43,7 +43,7 @@ engine::~engine()
|
|||
|
||||
void engine::parse_aspect_from_config( readonly_context &context, const config &cfg, const std::string &id, std::back_insert_iterator< std::vector< aspect_ptr > > b )
|
||||
{
|
||||
engine_ptr eng = context.get_engine(cfg);
|
||||
engine_ptr eng = context.get_engine_by_cfg(cfg);
|
||||
if (eng){
|
||||
//do not override that method in subclasses which cannot create aspects
|
||||
eng->do_parse_aspect_from_config(cfg, id, b);
|
||||
|
@ -52,7 +52,7 @@ void engine::parse_aspect_from_config( readonly_context &context, const config &
|
|||
|
||||
void engine::parse_candidate_action_from_config( rca_context &context, const config &cfg, std::back_insert_iterator<std::vector< candidate_action_ptr > > b )
|
||||
{
|
||||
engine_ptr eng = context.get_engine(cfg);
|
||||
engine_ptr eng = context.get_engine_by_cfg(cfg);
|
||||
if (eng){
|
||||
//do not override that method in subclasses which cannot create candidate actions
|
||||
eng->do_parse_candidate_action_from_config(context, cfg, b);
|
||||
|
@ -61,7 +61,7 @@ void engine::parse_candidate_action_from_config( rca_context &context, const con
|
|||
|
||||
void engine::parse_engine_from_config( readonly_context &context, const config &cfg, std::back_insert_iterator<std::vector< engine_ptr > > b )
|
||||
{
|
||||
engine_ptr eng = context.get_engine(cfg);
|
||||
engine_ptr eng = context.get_engine_by_cfg(cfg);
|
||||
if (eng){
|
||||
//do not override that method in subclasses which cannot create engines
|
||||
eng->do_parse_engine_from_config(cfg, b);
|
||||
|
@ -71,7 +71,7 @@ void engine::parse_engine_from_config( readonly_context &context, const config &
|
|||
|
||||
void engine::parse_goal_from_config( readonly_context &context, const config &cfg, std::back_insert_iterator<std::vector< goal_ptr > > b )
|
||||
{
|
||||
engine_ptr eng = context.get_engine(cfg);
|
||||
engine_ptr eng = context.get_engine_by_cfg(cfg);
|
||||
if (eng){
|
||||
//do not override that method in subclasses which cannot create goals
|
||||
eng->do_parse_goal_from_config(cfg, b);
|
||||
|
@ -81,7 +81,7 @@ void engine::parse_goal_from_config( readonly_context &context, const config &cf
|
|||
|
||||
void engine::parse_stage_from_config( ai_context &context, const config &cfg, std::back_insert_iterator<std::vector< stage_ptr > > b )
|
||||
{
|
||||
engine_ptr eng = context.get_engine(cfg);
|
||||
engine_ptr eng = context.get_engine_by_cfg(cfg);
|
||||
if (eng){
|
||||
//do not override that method in subclasses which cannot create stages
|
||||
eng->do_parse_stage_from_config(context, cfg, b);
|
||||
|
@ -120,9 +120,16 @@ std::string engine::evaluate(const std::string& /*str*/)
|
|||
|
||||
|
||||
|
||||
std::string engine::get_name() const
|
||||
const std::string& engine::get_name() const
|
||||
{
|
||||
return "null";
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& engine::get_engine() const
|
||||
{
|
||||
return engine_;
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,4 +147,10 @@ config engine::to_config() const
|
|||
}
|
||||
|
||||
|
||||
const std::string& engine::get_id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "../../global.hpp"
|
||||
|
||||
#include "component.hpp"
|
||||
#include "../contexts.hpp"
|
||||
#include "../game_info.hpp"
|
||||
#include "../../config.hpp"
|
||||
|
@ -38,7 +39,7 @@ class rca_context;
|
|||
class ai_context;
|
||||
class component;
|
||||
|
||||
class engine {
|
||||
class engine : public component {
|
||||
public:
|
||||
engine( readonly_context &context, const config &cfg );
|
||||
|
||||
|
@ -82,7 +83,7 @@ public:
|
|||
virtual std::string evaluate(const std::string& str);
|
||||
|
||||
|
||||
virtual std::string get_name() const;
|
||||
virtual const std::string& get_name() const;
|
||||
|
||||
/**
|
||||
* set ai context (which is not available during early initialization)
|
||||
|
@ -95,12 +96,19 @@ public:
|
|||
*/
|
||||
virtual config to_config() const;
|
||||
|
||||
|
||||
virtual const std::string& get_id() const;
|
||||
|
||||
|
||||
virtual const std::string& get_engine() const;
|
||||
|
||||
protected:
|
||||
readonly_context &ai_;
|
||||
|
||||
/** name of the engine which has created this engine*/
|
||||
std::string engine_;
|
||||
|
||||
std::string id_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ static lg::log_domain log_ai_composite_engine_cpp("ai/composite/engine/cpp");
|
|||
engine_cpp::engine_cpp( readonly_context &context, const config &cfg )
|
||||
: engine(context,cfg)
|
||||
{
|
||||
name_ = "cpp";
|
||||
}
|
||||
|
||||
engine_cpp::~engine_cpp()
|
||||
|
@ -112,9 +113,4 @@ void engine_cpp::do_parse_goal_from_config(const config &cfg, std::back_insert_i
|
|||
}
|
||||
|
||||
|
||||
std::string engine_cpp::get_name() const
|
||||
{
|
||||
return "cpp";
|
||||
}
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -49,8 +49,6 @@ public:
|
|||
virtual void do_parse_goal_from_config(const config &cfg, std::back_insert_iterator<std::vector< goal_ptr > > b );
|
||||
|
||||
|
||||
virtual std::string get_name() const;
|
||||
|
||||
};
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -75,6 +75,7 @@ private:
|
|||
engine_fai::engine_fai( readonly_context &context, const config &cfg )
|
||||
: engine(context,cfg), formula_ai_(context,cfg.child_or_empty("formula_ai"))
|
||||
{
|
||||
name_ = "fai";
|
||||
formula_ai_.on_create();
|
||||
}
|
||||
|
||||
|
@ -124,11 +125,6 @@ std::string engine_fai::evaluate(const std::string &str)
|
|||
}
|
||||
|
||||
|
||||
std::string engine_fai::get_name() const
|
||||
{
|
||||
return "fai";
|
||||
}
|
||||
|
||||
void engine_fai::set_ai_context(ai_context *context)
|
||||
{
|
||||
if (context!=NULL) {
|
||||
|
|
|
@ -42,8 +42,6 @@ public:
|
|||
|
||||
virtual std::string evaluate(const std::string &str);
|
||||
|
||||
virtual std::string get_name() const;
|
||||
|
||||
virtual config to_config() const;
|
||||
|
||||
virtual void set_ai_context(ai_context *context);
|
||||
|
|
|
@ -67,6 +67,20 @@ const std::string& goal::get_id() const
|
|||
}
|
||||
|
||||
|
||||
|
||||
const std::string& goal::get_name() const
|
||||
{
|
||||
return cfg_["id"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& goal::get_engine() const
|
||||
{
|
||||
return cfg_["engine"];
|
||||
}
|
||||
|
||||
|
||||
bool goal::redeploy(const config &cfg)
|
||||
{
|
||||
cfg_ = cfg;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
//included for 'target' markers
|
||||
#include "../default/contexts.hpp"
|
||||
|
||||
#include "component.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
@ -42,7 +44,7 @@
|
|||
|
||||
namespace ai {
|
||||
|
||||
class goal : public readonly_context_proxy {
|
||||
class goal : public readonly_context_proxy, public component {
|
||||
public:
|
||||
goal(readonly_context &context, const config &cfg);
|
||||
|
||||
|
@ -65,6 +67,12 @@ public:
|
|||
const std::string& get_id() const;
|
||||
|
||||
|
||||
const std::string& get_name() const;
|
||||
|
||||
|
||||
const std::string& get_engine() const;
|
||||
|
||||
|
||||
bool redeploy(const config &cfg);
|
||||
|
||||
|
||||
|
|
245
src/ai/composite/property_handler.hpp
Normal file
245
src/ai/composite/property_handler.hpp
Normal file
|
@ -0,0 +1,245 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Composite AI component
|
||||
* @file ai/composite/property_handler.hpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AI_COMPOSITE_PROPERTY_HANDLER_HPP_INCLUDED
|
||||
#define AI_COMPOSITE_PROPERTY_HANDLER_HPP_INCLUDED
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../foreach.hpp"
|
||||
|
||||
namespace ai{
|
||||
|
||||
struct path_element {
|
||||
path_element()
|
||||
: property()
|
||||
, id()
|
||||
, position(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string property;
|
||||
std::string id;
|
||||
int position;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
class path_element_matches{
|
||||
public:
|
||||
path_element_matches(const path_element &element)
|
||||
: count_(0), element_(element)
|
||||
{
|
||||
}
|
||||
virtual ~path_element_matches(){}
|
||||
|
||||
bool operator()(const T& t)
|
||||
{
|
||||
if ( (!element_.id.empty()) && (element_.id == t->get_id()) ) {
|
||||
return true;
|
||||
}
|
||||
if (count_ == element_.position) {
|
||||
return true;
|
||||
}
|
||||
count_++;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
int count_;
|
||||
path_element element_;
|
||||
};
|
||||
|
||||
|
||||
class component;
|
||||
|
||||
class base_property_handler {
|
||||
public:
|
||||
virtual component* handle_get(const path_element &child) = 0;
|
||||
virtual bool handle_change(const path_element &child, const config &cfg) = 0;
|
||||
virtual bool handle_add(const path_element &child, const config &cfg) = 0;
|
||||
virtual bool handle_delete(const path_element &child) = 0;
|
||||
virtual std::vector< component* > handle_get_children() = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr< base_property_handler > property_handler_ptr;
|
||||
|
||||
|
||||
template<typename T>
|
||||
class vector_property_handler : public base_property_handler {
|
||||
public:
|
||||
typedef boost::shared_ptr<T> t_ptr;
|
||||
typedef std::vector< boost::shared_ptr<T> > t_ptr_vector;
|
||||
|
||||
vector_property_handler(const std::string &property, t_ptr_vector &values, boost::function2<void, t_ptr_vector&, const config&> &construction_factory)
|
||||
: factory_(construction_factory), property_(property), values_(values){}
|
||||
|
||||
|
||||
component* handle_get(const path_element &child)
|
||||
{
|
||||
typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
|
||||
if (i!=values_.end()){
|
||||
return &*(*i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bool handle_change(const path_element &child, const config &cfg)
|
||||
{
|
||||
if (!handle_delete(child)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return handle_add(child,cfg);
|
||||
}
|
||||
bool handle_add(const path_element &child, const config &cfg)
|
||||
{
|
||||
//if the id is not empty, try to delete all with this id
|
||||
if (!cfg["id"].empty()) {
|
||||
path_element with_same_id;
|
||||
with_same_id.id=cfg["id"];
|
||||
with_same_id.property = property_;
|
||||
with_same_id.position=-1;
|
||||
handle_delete(with_same_id);
|
||||
}
|
||||
|
||||
typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
|
||||
return do_add(i-values_.begin(),cfg);
|
||||
}
|
||||
|
||||
bool handle_delete(const path_element &child)
|
||||
{
|
||||
//* is a special case - 'delete all'
|
||||
if (child.id == "*") {
|
||||
values_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
|
||||
if (i!=values_.end()){
|
||||
values_.erase(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::vector<component*> handle_get_children()
|
||||
{
|
||||
std::vector<component*> children;
|
||||
foreach (t_ptr v, values_) {
|
||||
children.push_back(&*v);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
private:
|
||||
bool do_add(int pos, const config &cfg)
|
||||
{
|
||||
if (pos<0) {
|
||||
pos = values_.size();
|
||||
}
|
||||
t_ptr_vector values;
|
||||
factory_(values,cfg);
|
||||
int j=0;
|
||||
foreach (t_ptr b, values ){
|
||||
values_.insert(values_.begin()+pos+j,b);
|
||||
j++;
|
||||
}
|
||||
return (j>0);
|
||||
}
|
||||
|
||||
boost::function2<void, t_ptr_vector&, const config&> factory_;
|
||||
const std::string property_;
|
||||
t_ptr_vector &values_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
class aspect_property_handler : public base_property_handler {
|
||||
public:
|
||||
typedef boost::shared_ptr<T> t_ptr;
|
||||
typedef std::map< std::string, t_ptr > aspect_map;
|
||||
|
||||
aspect_property_handler(const std::string &property, aspect_map &aspects)
|
||||
: property_(property), aspects_(aspects)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
component* handle_get(const path_element &child)
|
||||
{
|
||||
typename aspect_map::const_iterator a = aspects_.find(child.id);
|
||||
if (a!=aspects_.end()){
|
||||
return &*a->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool handle_change(const path_element &child, const config &cfg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool handle_add(const path_element &child, const config &cfg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool handle_delete(const path_element &child)
|
||||
{
|
||||
//* is a special case - 'delete all facets'
|
||||
if (child.id == "*") {
|
||||
bool b = false;
|
||||
foreach(typename aspect_map::value_type a, aspects_) {
|
||||
b |= a.second->delete_all_facets();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::vector<component*> handle_get_children()
|
||||
{
|
||||
std::vector<component*> children;
|
||||
foreach(typename aspect_map::value_type a, aspects_) {
|
||||
children.push_back(&*a.second);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const std::string &property_;
|
||||
aspect_map &aspects_;
|
||||
|
||||
};
|
||||
|
||||
} //of namespace ai
|
||||
|
||||
#endif
|
|
@ -34,7 +34,7 @@ const double candidate_action::BAD_SCORE = 0;
|
|||
const double candidate_action::HIGH_SCORE = 100000;
|
||||
|
||||
candidate_action::candidate_action(rca_context &context, const config &cfg)
|
||||
: recursion_counter_(context.get_recursion_count()), enabled_(utils::string_bool(cfg["enabled"],true)), engine_(cfg["engine"]), score_(lexical_cast_default<double>(cfg["score"],BAD_SCORE)),max_score_(lexical_cast_default<double>(cfg["max_score"],HIGH_SCORE)),name_(cfg["name"]),type_(cfg["type"])
|
||||
: recursion_counter_(context.get_recursion_count()), enabled_(utils::string_bool(cfg["enabled"],true)), engine_(cfg["engine"]), score_(lexical_cast_default<double>(cfg["score"],BAD_SCORE)),max_score_(lexical_cast_default<double>(cfg["max_score"],HIGH_SCORE)),id_(cfg["id"]),name_(cfg["name"]),type_(cfg["type"])
|
||||
{
|
||||
init_rca_context_proxy(context);
|
||||
}
|
||||
|
@ -90,6 +90,18 @@ const std::string& candidate_action::get_type() const
|
|||
}
|
||||
|
||||
|
||||
const std::string& candidate_action::get_id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
|
||||
const std::string& candidate_action::get_engine() const
|
||||
{
|
||||
return engine_;
|
||||
}
|
||||
|
||||
|
||||
config candidate_action::to_config() const
|
||||
{
|
||||
config cfg;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "../../config.hpp"
|
||||
|
||||
#include "component.hpp"
|
||||
#include "contexts.hpp"
|
||||
#include "../contexts.hpp"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
@ -39,7 +40,7 @@
|
|||
//============================================================================
|
||||
namespace ai {
|
||||
|
||||
class candidate_action : public virtual rca_context_proxy {
|
||||
class candidate_action : public virtual rca_context_proxy, public component {
|
||||
public:
|
||||
//this is a score guaranteed to be <=0, thus candidate action with this score will not be selected for execution
|
||||
static const double BAD_SCORE;
|
||||
|
@ -111,6 +112,12 @@ public:
|
|||
const std::string& get_type() const;
|
||||
|
||||
|
||||
const std::string& get_id() const;
|
||||
|
||||
|
||||
const std::string& get_engine() const;
|
||||
|
||||
|
||||
int get_recursion_count() const;
|
||||
|
||||
|
||||
|
@ -125,14 +132,22 @@ private:
|
|||
|
||||
bool enabled_;
|
||||
|
||||
|
||||
std::string engine_;
|
||||
|
||||
|
||||
double score_;
|
||||
|
||||
|
||||
double max_score_;
|
||||
|
||||
|
||||
std::string id_;
|
||||
|
||||
|
||||
std::string name_;
|
||||
|
||||
|
||||
std::string type_;
|
||||
|
||||
};
|
||||
|
|
|
@ -77,6 +77,22 @@ const std::string& stage::get_id() const
|
|||
return cfg_["id"];
|
||||
}
|
||||
|
||||
|
||||
const std::string& stage::get_engine() const
|
||||
{
|
||||
return cfg_["engine"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& stage::get_name() const
|
||||
{
|
||||
return cfg_["name"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// COMPOSITE AI IDLE STAGE
|
||||
// =======================================================================
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "../../global.hpp"
|
||||
|
||||
#include "component.hpp"
|
||||
#include "contexts.hpp"
|
||||
#include "../contexts.hpp"
|
||||
#include "../../config.hpp"
|
||||
|
@ -39,7 +40,7 @@ namespace ai {
|
|||
|
||||
class ai_composite;
|
||||
|
||||
class stage : public virtual ai_context_proxy {
|
||||
class stage : public virtual ai_context_proxy, public component {
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -78,6 +79,15 @@ public:
|
|||
|
||||
|
||||
virtual const std::string& get_id() const;
|
||||
|
||||
|
||||
virtual const std::string& get_name() const;
|
||||
|
||||
|
||||
virtual const std::string& get_engine() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Play the turn - implementation
|
||||
|
|
|
@ -487,6 +487,12 @@ const aspect_map& readonly_context_impl::get_aspects() const
|
|||
}
|
||||
|
||||
|
||||
aspect_map& readonly_context_impl::get_aspects()
|
||||
{
|
||||
return aspects_;
|
||||
}
|
||||
|
||||
|
||||
const attacks_vector& readonly_context_impl::get_attacks() const
|
||||
{
|
||||
if (attacks_) {
|
||||
|
@ -562,7 +568,7 @@ const move_map& readonly_context_impl::get_enemy_srcdst() const
|
|||
}
|
||||
|
||||
|
||||
engine_ptr readonly_context_impl::get_engine(const config& cfg)
|
||||
engine_ptr readonly_context_impl::get_engine_by_cfg(const config& cfg)
|
||||
{
|
||||
std::string engine_name = cfg["engine"];
|
||||
if (engine_name.empty()) {
|
||||
|
@ -597,6 +603,19 @@ engine_ptr readonly_context_impl::get_engine(const config& cfg)
|
|||
return engines_.back();
|
||||
}
|
||||
|
||||
|
||||
const std::vector<engine_ptr>& readonly_context_impl::get_engines() const
|
||||
{
|
||||
return engines_;
|
||||
}
|
||||
|
||||
|
||||
std::vector<engine_ptr>& readonly_context_impl::get_engines()
|
||||
{
|
||||
return engines_;
|
||||
}
|
||||
|
||||
|
||||
std::string readonly_context_impl::get_grouping() const
|
||||
{
|
||||
if (grouping_) {
|
||||
|
|
|
@ -207,6 +207,9 @@ public:
|
|||
virtual const aspect_map& get_aspects() const = 0;
|
||||
|
||||
|
||||
virtual aspect_map& get_aspects() = 0;
|
||||
|
||||
|
||||
virtual void add_facet(const std::string &id, const config &cfg) const = 0;
|
||||
|
||||
|
||||
|
@ -239,7 +242,13 @@ public:
|
|||
/**
|
||||
* get engine by cfg, creating it if it is not created yet but known
|
||||
*/
|
||||
virtual engine_ptr get_engine(const config& cfg) = 0;
|
||||
virtual engine_ptr get_engine_by_cfg(const config& cfg) = 0;
|
||||
|
||||
|
||||
virtual const std::vector<engine_ptr>& get_engines() const = 0;
|
||||
|
||||
|
||||
virtual std::vector<engine_ptr>& get_engines() = 0;
|
||||
|
||||
|
||||
virtual std::string get_grouping() const = 0;
|
||||
|
@ -588,6 +597,12 @@ public:
|
|||
}
|
||||
|
||||
|
||||
virtual aspect_map& get_aspects()
|
||||
{
|
||||
return target_->get_aspects();
|
||||
}
|
||||
|
||||
|
||||
virtual void add_aspects(std::vector< aspect_ptr > &aspects )
|
||||
{
|
||||
return target_->add_aspects(aspects);
|
||||
|
@ -650,9 +665,21 @@ public:
|
|||
}
|
||||
|
||||
|
||||
virtual engine_ptr get_engine(const config &cfg)
|
||||
virtual engine_ptr get_engine_by_cfg(const config &cfg)
|
||||
{
|
||||
return target_->get_engine(cfg);
|
||||
return target_->get_engine_by_cfg(cfg);
|
||||
}
|
||||
|
||||
|
||||
virtual const std::vector<engine_ptr>& get_engines() const
|
||||
{
|
||||
return target_->get_engines();
|
||||
}
|
||||
|
||||
|
||||
virtual std::vector<engine_ptr>& get_engines()
|
||||
{
|
||||
return target_->get_engines();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1173,6 +1200,9 @@ public:
|
|||
virtual const aspect_map& get_aspects() const;
|
||||
|
||||
|
||||
virtual aspect_map& get_aspects();
|
||||
|
||||
|
||||
virtual const attacks_vector& get_attacks() const;
|
||||
|
||||
|
||||
|
@ -1197,7 +1227,13 @@ public:
|
|||
virtual const move_map& get_enemy_srcdst() const;
|
||||
|
||||
|
||||
virtual engine_ptr get_engine(const config& cfg);
|
||||
virtual engine_ptr get_engine_by_cfg(const config& cfg);
|
||||
|
||||
|
||||
virtual const std::vector<engine_ptr>& get_engines() const;
|
||||
|
||||
|
||||
virtual std::vector<engine_ptr>& get_engines();
|
||||
|
||||
|
||||
virtual std::string get_grouping() const;
|
||||
|
|
|
@ -248,6 +248,17 @@ const std::string holder::get_ai_overview()
|
|||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string holder::get_ai_structure()
|
||||
{
|
||||
if (!this->ai_) {
|
||||
get_ai_ref();
|
||||
}
|
||||
return component_manager::print_component_tree(&*this->ai_,"");
|
||||
}
|
||||
|
||||
|
||||
const std::string holder::get_ai_identifier() const
|
||||
{
|
||||
return cfg_["id"];
|
||||
|
@ -667,6 +678,13 @@ std::string manager::get_active_ai_overview_for_side( side_number side)
|
|||
return get_active_ai_holder_for_side(side).get_ai_overview();
|
||||
}
|
||||
|
||||
|
||||
std::string manager::get_active_ai_structure_for_side( side_number side)
|
||||
{
|
||||
return get_active_ai_holder_for_side(side).get_ai_structure();
|
||||
}
|
||||
|
||||
|
||||
std::string manager::get_active_ai_identifier_for_side( side_number side )
|
||||
{
|
||||
return get_active_ai_holder_for_side(side).get_ai_identifier();
|
||||
|
|
|
@ -73,6 +73,9 @@ public:
|
|||
const std::string get_ai_overview();
|
||||
|
||||
|
||||
const std::string get_ai_structure();
|
||||
|
||||
|
||||
const std::string get_ai_identifier() const;
|
||||
|
||||
private:
|
||||
|
@ -377,6 +380,14 @@ public:
|
|||
*/
|
||||
static std::string get_active_ai_overview_for_side( side_number side);
|
||||
|
||||
|
||||
/**
|
||||
* Gets AI Structure for active AI of the given @a side
|
||||
* @param side side number (1-based)
|
||||
* @return an ai structure
|
||||
*/
|
||||
static std::string get_active_ai_structure_for_side( side_number side);
|
||||
|
||||
/**
|
||||
* Gets AI algorithm identifier for active AI of the given @a side.
|
||||
* @param side side number (1-based).
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "../../foreach.hpp"
|
||||
#include "../../log.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace ai {
|
||||
|
||||
namespace testing_ai_default {
|
||||
|
@ -45,8 +47,20 @@ void candidate_action_evaluation_loop::on_create()
|
|||
foreach(const config &cfg_element, cfg_.child_range("candidate_action")){
|
||||
engine::parse_candidate_action_from_config(*this,cfg_element,back_inserter(candidate_actions_));
|
||||
}
|
||||
|
||||
boost::function2<void, std::vector<candidate_action_ptr>&, const config&> factory_candidate_actions =
|
||||
boost::bind(&testing_ai_default::candidate_action_evaluation_loop::create_candidate_action,*this,_1,_2);
|
||||
|
||||
register_vector_property("candidate_action",candidate_actions_, factory_candidate_actions);
|
||||
|
||||
}
|
||||
|
||||
void candidate_action_evaluation_loop::create_candidate_action(std::vector<candidate_action_ptr> &candidate_actions, const config &cfg)
|
||||
{
|
||||
engine::parse_candidate_action_from_config(*this,cfg,std::back_inserter(candidate_actions));
|
||||
}
|
||||
|
||||
|
||||
config candidate_action_evaluation_loop::to_config() const
|
||||
{
|
||||
config cfg = stage::to_config();
|
||||
|
@ -135,6 +149,25 @@ candidate_action_evaluation_loop::~candidate_action_evaluation_loop()
|
|||
{
|
||||
}
|
||||
|
||||
bool candidate_action_evaluation_loop::add_child(const path_element &/*child*/, const config &/*cfg*/)
|
||||
{
|
||||
//if (child.property=="candidate_action") {
|
||||
// std::vector< candidate_action_ptr >::iterator i = std::find_if(candidate_actions_.begin(),candidate_actions_.end(),path_element_matches< candidate_action_ptr >(child));
|
||||
//return add_candidate_action(i-candidate_actions_.begin(),cfg);
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool candidate_action_evaluation_loop::change_child(const path_element &/*child*/, const config &/*cfg*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool candidate_action_evaluation_loop::delete_child(const path_element &/*child*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end of namespace testing_ai_default
|
||||
|
||||
} // end of namespace ai
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "../../global.hpp"
|
||||
|
||||
#include "../composite/contexts.hpp"
|
||||
#include "../composite/component.hpp"
|
||||
#include "../composite/rca.hpp"
|
||||
#include "../composite/stage.hpp"
|
||||
#include "../../config.hpp"
|
||||
|
@ -54,6 +55,15 @@ public:
|
|||
|
||||
rca_context& get_rca_context();
|
||||
|
||||
virtual bool add_child(const path_element &child, const config &cfg);
|
||||
|
||||
virtual bool change_child(const path_element &child, const config &cfg);
|
||||
|
||||
virtual bool delete_child(const path_element &child);
|
||||
|
||||
|
||||
void create_candidate_action(std::vector<candidate_action_ptr> &candidate_actions, const config &cfg);
|
||||
|
||||
private:
|
||||
std::vector<candidate_action_ptr> candidate_actions_;
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ public:
|
|||
model_.add_row_to_stuff_list("ai config full","ai config full");
|
||||
model_.add_row_to_stuff_list("recall list overview","recall list overview");
|
||||
model_.add_row_to_stuff_list("recall list full","recall list full");
|
||||
model_.add_row_to_stuff_list("ai component structure","ai component structure");
|
||||
model_.set_inspect_window_text("");
|
||||
|
||||
}
|
||||
|
@ -287,6 +288,11 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (selected==5) {
|
||||
model_.set_inspect_window_text(ai::manager::get_active_ai_structure_for_side(side_));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual void update_view_from_model()
|
||||
|
|
Loading…
Add table
Reference in a new issue