ai/composite/goal.cpp

Go to the documentation of this file.
00001 
00002 /* $Id: goal.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00003 /*
00004    Copyright (C) 2009 - 2012 by Yurii Chernyi <terraninfo@terraninfo.net>
00005    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY.
00013 
00014    See the COPYING file for more details.
00015 */
00016 
00017 /**
00018  * @file
00019  */
00020 
00021 #include "goal.hpp"
00022 #include "../lua/core.hpp"
00023 #include "../manager.hpp"
00024 #include "../../log.hpp"
00025 #include "../lua/lua_object.hpp"
00026 #include "../../gamestatus.hpp"
00027 #include "../../foreach.hpp"
00028 #include "../../resources.hpp"
00029 #include "../../scripting/lua.hpp"
00030 #include "../../terrain_filter.hpp"
00031 #include "../../unit.hpp"
00032 #include "../../unit_map.hpp"
00033 #include "../../team.hpp"
00034 #include "../../variable.hpp"
00035 
00036 #include <boost/lexical_cast.hpp>
00037 
00038 namespace ai {
00039 
00040 static lg::log_domain log_ai_goal("ai/goal");
00041 #define DBG_AI_GOAL LOG_STREAM(debug, log_ai_goal)
00042 #define LOG_AI_GOAL LOG_STREAM(info, log_ai_goal)
00043 #define ERR_AI_GOAL LOG_STREAM(err, log_ai_goal)
00044 
00045 goal::goal(readonly_context &context, const config &cfg)
00046     : readonly_context_proxy(), cfg_(cfg)
00047 {
00048     init_readonly_context_proxy(context);
00049 }
00050 
00051 
00052 
00053 void goal::on_create()
00054 {
00055 }
00056 
00057 void goal::on_create(boost::shared_ptr<ai::lua_ai_context>)
00058 {
00059 }
00060 
00061 
00062 goal::~goal()
00063 {
00064 }
00065 
00066 
00067 void goal::add_targets(std::back_insert_iterator< std::vector< target > > /*target_list*/)
00068 {
00069 }
00070 
00071 
00072 
00073 config goal::to_config() const
00074 {
00075     return cfg_;
00076 }
00077 
00078 std::string goal::get_id() const
00079 {
00080     return cfg_["id"];
00081 }
00082 
00083 std::string goal::get_name() const
00084 {
00085     return cfg_["id"];
00086 }
00087 
00088 std::string goal::get_engine() const
00089 {
00090     return cfg_["engine"];
00091 }
00092 
00093 
00094 bool goal::redeploy(const config &cfg)
00095 {
00096     cfg_ = cfg;
00097     on_create();
00098     return true;
00099 }
00100 
00101 
00102 bool goal::active() const
00103 {
00104     return is_active(cfg_["time_of_day"],cfg_["turns"]);
00105 }
00106 
00107 
00108 void target_unit_goal::on_create()
00109 {
00110     goal::on_create();
00111     if (const config::attribute_value *v = cfg_.get("value")) {
00112         try {
00113             value_ = boost::lexical_cast<double>(*v);
00114         } catch (boost::bad_lexical_cast){
00115             ERR_AI_GOAL << "bad value of goal"<<std::endl;
00116             value_ = 0;
00117         }
00118     }
00119 }
00120 
00121 void target_unit_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00122 {
00123     if (!(this)->active()) {
00124         return;
00125     }
00126 
00127     const config &criteria = cfg_.child("criteria");
00128     if (!criteria) return;
00129 
00130     //find the enemy leaders and explicit targets
00131     foreach (const unit &u, *resources::units) {
00132         if (u.matches_filter(vconfig(criteria), u.get_location())) {
00133             LOG_AI_GOAL << "found explicit target unit at ... " << u.get_location() << " with value: " << value() << "\n";
00134             *target_list = target(u.get_location(), value(), target::EXPLICIT);
00135         }
00136     }
00137 
00138 
00139 }
00140 
00141 
00142 target_unit_goal::target_unit_goal(readonly_context &context, const config &cfg)
00143     : goal(context,cfg)
00144     , value_(0.0)
00145 {
00146 }
00147 
00148 
00149 void target_location_goal::on_create()
00150 {
00151     goal::on_create();
00152     if (cfg_.has_attribute("value")) {
00153         try {
00154             value_ = boost::lexical_cast<double>(cfg_["value"]);
00155         } catch (boost::bad_lexical_cast){
00156             ERR_AI_GOAL << "bad value of goal"<<std::endl;
00157             value_ = 0;
00158         }
00159     }
00160     const config &criteria = cfg_.child("criteria");
00161     if (criteria) {
00162         filter_ptr_ = boost::shared_ptr<terrain_filter>(new terrain_filter(vconfig(criteria),*resources::units));
00163     }
00164 }
00165 
00166 void target_location_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00167 {
00168     if (!(this)->active()) {
00169         return;
00170     }
00171 
00172     if (!filter_ptr_) return;
00173 
00174     std::set<map_location> items;
00175     filter_ptr_->get_locations(items);
00176     foreach (const map_location &loc, items)
00177     {
00178         LOG_AI_GOAL << "found explicit target location ... " << loc << " with value: " << value() << std::endl;
00179         *target_list = target(loc, value(), target::EXPLICIT);
00180     }
00181 
00182 }
00183 
00184 target_location_goal::target_location_goal(readonly_context &context, const config &cfg)
00185     : goal(context,cfg)
00186     , filter_ptr_()
00187     , value_(0.0)
00188 {
00189 }
00190 
00191 
00192 
00193 void protect_goal::on_create()
00194 {
00195     goal::on_create();
00196     if (const config::attribute_value *v = cfg_.get("value")) {
00197         try {
00198             value_ = boost::lexical_cast<double>(*v);
00199         } catch (boost::bad_lexical_cast){
00200             ERR_AI_GOAL << "bad value of protect_goal"<<std::endl;
00201             value_ = 0;
00202         }
00203     }
00204     if (const config::attribute_value *v = cfg_.get("protect_radius")) {
00205         try {
00206             radius_ = boost::lexical_cast<int>(*v);
00207         } catch (boost::bad_lexical_cast){
00208             ERR_AI_GOAL << "bad protection radius of protect_goal"<<std::endl;
00209             radius_ = 1;
00210         }
00211     }
00212 
00213     if (radius_<1) {
00214         radius_=20;
00215     }
00216     const config &criteria = cfg_.child("criteria");
00217     if (criteria) {
00218         filter_ptr_ = boost::shared_ptr<terrain_filter>(new terrain_filter(vconfig(criteria),*resources::units));
00219     }
00220 
00221 
00222 }
00223 
00224 
00225 void protect_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00226 {
00227     std::string goal_type;
00228     if (protect_unit_) {
00229         if (protect_only_own_unit_) {
00230             goal_type = "protect_my_unit";
00231         } else {
00232             goal_type = "protect_unit";
00233         }
00234     } else {
00235         goal_type ="protect_location";
00236     }
00237 
00238     if (!(this)->active()) {
00239         LOG_AI_GOAL << "skipping " << goal_type << " goal - not active" << std::endl;
00240         return;
00241     }
00242 
00243     const config &criteria = cfg_.child("criteria");
00244     if (!criteria) {
00245         LOG_AI_GOAL << "skipping " << goal_type << " goal - no criteria given" << std::endl;
00246         return;
00247     } else {
00248         DBG_AI_GOAL << "side " << get_side() << ": "<< goal_type << " goal with criteria" << std::endl << cfg_.child("criteria") << std::endl;
00249     }
00250 
00251     unit_map &units = *resources::units;
00252 
00253     std::set<map_location> items;
00254     if (protect_unit_) {
00255         foreach (const unit &u, units)
00256         {
00257             if (protect_only_own_unit_ && u.side() != get_side()) {
00258                 continue;
00259             }
00260             //TODO: we will protect hidden units, by not testing for invisibility to current side
00261             if (u.matches_filter(vconfig(criteria), u.get_location())) {
00262                 DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": " << u.get_location() << " should be protected\n";
00263                 items.insert(u.get_location());
00264             }
00265         }
00266     } else {
00267         filter_ptr_->get_locations(items);
00268     }
00269     DBG_AI_GOAL << "side " << get_side() << ": seaching for threats in "+goal_type+" goal" << std::endl;
00270     // Look for directions to protect a specific location or specific unit.
00271     foreach (const map_location &loc, items)
00272     {
00273         foreach (const unit &u, units)
00274         {
00275             int distance = distance_between(u.get_location(), loc);
00276             if (current_team().is_enemy(u.side()) && distance < radius_ &&
00277                 !u.invisible(u.get_location()))
00278             {
00279                 DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": found threat target. " << u.get_location() << " is a threat to "<< loc << '\n';
00280                 *target_list = target(u.get_location(),
00281                     value_ * double(radius_ - distance) /
00282                     radius_, target::THREAT);
00283             }
00284         }
00285     }
00286 
00287 
00288 }
00289 
00290 
00291 protect_goal::protect_goal(readonly_context &context, const config &cfg, bool protect_only_own_unit, bool protect_unit)
00292     : goal(context,cfg)
00293     , filter_ptr_()
00294     , protect_only_own_unit_(protect_only_own_unit)
00295     , protect_unit_(protect_unit)
00296     , radius_(20) //this default radius is taken from old code
00297     , value_(1.0) //this default value taken from old code
00298 {
00299 }
00300 
00301 lua_goal::lua_goal(readonly_context &context, const config &cfg)
00302     : goal(context, cfg)
00303     , code_()
00304     , handler_()
00305 {
00306     if (cfg.has_attribute("code")) {
00307         code_ = cfg["code"].str();
00308     }
00309     else
00310     {
00311         // report failure
00312     }
00313 }
00314 
00315 void lua_goal::on_create(boost::shared_ptr<ai::lua_ai_context> l_ctx)
00316 {
00317     handler_ = boost::shared_ptr<lua_ai_action_handler>(resources::lua_kernel->create_lua_ai_action_handler(code_.c_str(), *l_ctx));
00318 }
00319 
00320 void lua_goal::add_targets(std::back_insert_iterator< std::vector< target > > target_list)
00321 {
00322     boost::shared_ptr< lua_object< std::vector < target > > > l_obj
00323         = boost::shared_ptr< lua_object< std::vector < target > > >(new lua_object< std::vector < target > >());
00324     config c = config();
00325     handler_->handle(c, true, l_obj);
00326     std::vector < target > targets = *(l_obj->get());
00327 
00328     foreach (target tg, targets)
00329     {
00330         *target_list = tg;
00331     }
00332 
00333 }
00334 
00335 
00336 
00337 } //end of namespace ai
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:43 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs