ai/contexts.hpp

Go to the documentation of this file.
00001 /* $Id: contexts.hpp 53846 2012-04-08 00:00:14Z nephro $ */
00002 /*
00003    Copyright (C) 2009 - 2012 by Yurii Chernyi <terraninfo@terraninfo.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file
00018  * Helper functions for the object which operates in the context of AI for specific side
00019  * this is part of AI interface
00020  */
00021 
00022 #ifndef AI_CONTEXTS_HPP_INCLUDED
00023 #define AI_CONTEXTS_HPP_INCLUDED
00024 
00025 #include "game_info.hpp"
00026 #include "../generic_event.hpp"
00027 #include "../config.hpp"
00028 
00029 
00030 //#include "../unit.hpp"
00031 
00032 #ifdef _MSC_VER
00033 #pragma warning(push)
00034 //silence "inherits via dominance" warnings
00035 #pragma warning(disable:4250)
00036 #endif
00037 
00038 class battle_context;
00039 struct battle_context_unit_stats;
00040 class game_display;
00041 class gamemap;
00042 class variant;
00043 class terrain_filter;
00044 class terrain_translation;
00045 class unit;
00046 class unit_type;
00047 
00048 namespace ai {
00049 
00050 class interface;
00051 class ai_context;
00052 
00053 typedef ai_context* ai_context_ptr;
00054 
00055 
00056 // recursion counter
00057 class recursion_counter {
00058 public:
00059     recursion_counter(int counter)
00060         : counter_(++counter)
00061     {
00062         if (counter > MAX_COUNTER_VALUE ) {
00063             throw game::game_error("maximum recursion depth reached!");
00064         }
00065     }
00066 
00067 
00068     /**
00069      * Get the current value of the recursion counter
00070      */
00071     int get_count() const
00072     {
00073         return counter_;
00074     }
00075 
00076 
00077     //max recursion depth
00078     static const int MAX_COUNTER_VALUE = 100;
00079 
00080 
00081     /**
00082      * Check if more recursion is allowed
00083      */
00084     bool is_ok() const
00085     {
00086         return counter_ < MAX_COUNTER_VALUE;
00087     }
00088 private:
00089 
00090     // recursion counter value
00091     int counter_;
00092 };
00093 
00094 //defensive position
00095 
00096 struct defensive_position {
00097     defensive_position() :
00098         loc(),
00099         chance_to_hit(0),
00100         vulnerability(0.0),
00101         support(0.0)
00102         {}
00103 
00104     map_location loc;
00105     int chance_to_hit;
00106     double vulnerability, support;
00107 };
00108 
00109 // keeps cache
00110 class keeps_cache : public events::observer
00111 {
00112 public:
00113     keeps_cache();
00114     ~keeps_cache();
00115     void handle_generic_event(const std::string& event_name);
00116     void clear();
00117     const std::set<map_location>& get();
00118     void init(gamemap &map);
00119 private:
00120     gamemap *map_;
00121     std::set<map_location> keeps_;
00122 };
00123 
00124 // side context
00125 
00126 class side_context;
00127 
00128 class side_context{
00129 public:
00130 
00131     /**
00132      * Get the side number
00133      */
00134     virtual side_number get_side() const  = 0;
00135 
00136 
00137     /**
00138      * Set the side number
00139      */
00140     virtual void set_side(side_number side) = 0;
00141 
00142 
00143     /**
00144      * empty destructor
00145      */
00146     virtual ~side_context(){}
00147 
00148 
00149     /**
00150      * empty constructor
00151      */
00152     side_context() {}
00153 
00154 
00155     /**
00156      * unwrap
00157      */
00158     virtual side_context& get_side_context() = 0;
00159 
00160 
00161     /**
00162      * serialize this context to config
00163      */
00164     virtual config to_side_context_config() const = 0;
00165 
00166 
00167     /**
00168      * Get the value of the recursion counter
00169      */
00170     virtual int get_recursion_count() const = 0;
00171 
00172 
00173 };
00174 
00175 class readonly_context;
00176 class readonly_context : public virtual side_context {
00177 public:
00178     readonly_context(){}
00179     virtual ~readonly_context(){}
00180     virtual readonly_context& get_readonly_context() = 0;
00181     virtual void on_readonly_context_create() = 0;
00182     virtual const team& current_team() const = 0;
00183     virtual void diagnostic(const std::string& msg) = 0;
00184     virtual void log_message(const std::string& msg) = 0;
00185     virtual attack_result_ptr check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) = 0;
00186     virtual move_result_ptr check_move_action(const map_location& from, const map_location& to, bool remove_movement=true) = 0;
00187     virtual recall_result_ptr check_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location) = 0;
00188     virtual recruit_result_ptr check_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location) = 0;
00189     virtual stopunit_result_ptr check_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) = 0;
00190     virtual void calculate_possible_moves(std::map<map_location,pathfind::paths>& possible_moves,
00191         move_map& srcdst, move_map& dstsrc, bool enemy,
00192         bool assume_full_movement=false,
00193         const terrain_filter* remove_destinations=NULL) const = 0;
00194     virtual void calculate_moves(const unit_map& units,
00195         std::map<map_location,pathfind::paths>& possible_moves, move_map& srcdst,
00196         move_map& dstsrc, bool enemy, bool assume_full_movement=false,
00197         const terrain_filter* remove_destinations=NULL,
00198         bool see_all=false) const = 0;
00199 
00200     virtual const game_info& get_info() const = 0;
00201 
00202 
00203     //@note: following part is in alphabetic order
00204     virtual defensive_position const& best_defensive_position(const map_location& unit,
00205             const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const = 0;
00206 
00207 
00208     virtual std::map<map_location,defensive_position>& defensive_position_cache() const = 0;
00209 
00210 
00211     virtual double get_aggression() const = 0;
00212 
00213 
00214     virtual int get_attack_depth() const = 0;
00215 
00216 
00217     virtual const aspect_map& get_aspects() const = 0;
00218 
00219 
00220     virtual aspect_map& get_aspects() = 0;
00221 
00222 
00223     virtual void add_facet(const std::string &id, const config &cfg) const = 0;
00224 
00225 
00226     virtual void add_aspects(std::vector< aspect_ptr > &aspects ) = 0;
00227 
00228 
00229     virtual const attacks_vector& get_attacks() const = 0;
00230 
00231 
00232     virtual const variant& get_attacks_as_variant() const = 0;
00233 
00234 
00235     virtual const terrain_filter& get_avoid() const = 0;
00236 
00237 
00238     virtual double get_caution() const = 0;
00239 
00240 
00241     virtual const move_map& get_dstsrc() const = 0;
00242 
00243 
00244     virtual const move_map& get_enemy_dstsrc() const = 0;
00245 
00246 
00247     virtual const moves_map& get_enemy_possible_moves() const = 0;
00248 
00249 
00250     virtual const move_map& get_enemy_srcdst() const = 0;
00251 
00252     /**
00253      * get engine by cfg, creating it if it is not created yet but known
00254      */
00255     virtual engine_ptr get_engine_by_cfg(const config& cfg) = 0;
00256 
00257 
00258     virtual const std::vector<engine_ptr>& get_engines() const = 0;
00259 
00260 
00261     virtual std::vector<engine_ptr>& get_engines() = 0;
00262 
00263 
00264     virtual std::string get_grouping() const = 0;
00265 
00266 
00267     virtual const std::vector<goal_ptr>& get_goals() const = 0;
00268 
00269 
00270     virtual std::vector<goal_ptr>& get_goals() = 0;
00271 
00272 
00273     virtual double get_leader_aggression() const = 0;
00274 
00275 
00276     virtual config get_leader_goal() const = 0;
00277 
00278 
00279     virtual double get_leader_value() const = 0;
00280 
00281 
00282     virtual double get_number_of_possible_recruits_to_force_recruit() const = 0;
00283 
00284 
00285     virtual bool get_passive_leader() const = 0;
00286 
00287 
00288     virtual bool get_passive_leader_shares_keep() const = 0;
00289 
00290 
00291     virtual const moves_map& get_possible_moves() const = 0;
00292 
00293 
00294     virtual const std::vector<unit>& get_recall_list() const = 0;
00295 
00296 
00297     virtual stage_ptr get_recruitment(ai_context &context) const = 0;
00298 
00299 
00300     virtual bool get_recruitment_ignore_bad_combat() const = 0;
00301 
00302 
00303     virtual bool get_recruitment_ignore_bad_movement() const = 0;
00304 
00305 
00306     virtual const std::vector<std::string> get_recruitment_pattern() const = 0;
00307 
00308 
00309     virtual double get_scout_village_targeting() const = 0;
00310 
00311 
00312     virtual bool get_simple_targeting() const = 0;
00313 
00314 
00315     virtual const move_map& get_srcdst() const = 0;
00316 
00317 
00318     virtual bool get_support_villages() const = 0;
00319 
00320 
00321     virtual double get_village_value() const = 0;
00322 
00323 
00324     virtual int get_villages_per_scout() const = 0;
00325 
00326 
00327     virtual bool is_active(const std::string &time_of_day, const std::string &turns) const = 0;
00328 
00329     virtual bool is_dst_src_valid_lua() const = 0;
00330     
00331     virtual bool is_dst_src_enemy_valid_lua() const = 0;
00332     
00333     virtual bool is_src_dst_valid_lua() const = 0;
00334     
00335     virtual bool is_src_dst_enemy_valid_lua() const = 0;
00336     
00337     virtual void invalidate_defensive_position_cache() const = 0;
00338 
00339 
00340     virtual void invalidate_move_maps() const = 0;
00341 
00342 
00343     virtual void invalidate_keeps_cache() const= 0;
00344 
00345 
00346     virtual const std::set<map_location>& keeps() const= 0;
00347 
00348 
00349     virtual bool leader_can_reach_keep() const = 0;
00350 
00351 
00352     virtual const map_location& nearest_keep(const map_location& loc) const = 0;
00353 
00354 
00355     /**
00356      * Function which finds how much 'power' a side can attack a certain location with.
00357      * This is basically the maximum hp of damage that can be inflicted upon a unit on loc
00358      * by full-health units, multiplied by the defense these units will have.
00359      * (if 'use_terrain' is false, then it will be multiplied by 0.5)
00360      *
00361      * Example: 'loc' can be reached by two units, one of whom has a 10-3 attack
00362      * and has 48/48 hp, and can defend at 40% on the adjacent grassland.
00363      * The other has a 8-2 attack, and has 30/40 hp, and can defend at 60% on the adjacent mountain.
00364      * The rating will be 10*3*1.0*0.4 + 8*2*0.75*0.6 = 19.2
00365      */
00366     virtual double power_projection(const map_location& loc, const move_map& dstsrc) const = 0;
00367 
00368 
00369     virtual void raise_user_interact() const = 0;
00370 
00371 
00372     virtual void recalculate_move_maps() const = 0;
00373 
00374 
00375     virtual void recalculate_move_maps_enemy() const = 0;
00376     
00377     virtual void set_src_dst_valid_lua() = 0;
00378     virtual void set_src_dst_enemy_valid_lua() = 0;
00379     virtual void set_dst_src_valid_lua() = 0;
00380     virtual void set_dst_src_enemy_valid_lua() = 0;
00381     
00382     /** get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return nearest occupied that can be reached in 1 turn, if none - return nearest keep, if none - return null_location */
00383     virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths ) = 0;
00384 
00385     /**
00386      * serialize to config
00387      */
00388     virtual config to_readonly_context_config() const = 0;
00389 
00390 
00391     virtual std::map<std::pair<map_location,const unit_type *>,
00392         std::pair<battle_context_unit_stats,battle_context_unit_stats> >& unit_stats_cache() const = 0;
00393 
00394 };
00395 
00396 class readwrite_context;
00397 class readwrite_context : public virtual readonly_context {
00398 public:
00399     readwrite_context(){}
00400 
00401 
00402     virtual ~readwrite_context(){}
00403 
00404 
00405     virtual readwrite_context& get_readwrite_context() = 0;
00406 
00407 
00408     virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon) = 0;
00409 
00410 
00411     virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true) = 0;
00412 
00413 
00414     virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location) = 0;
00415 
00416 
00417     virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location) = 0;
00418 
00419 
00420     virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false) = 0;
00421 
00422 
00423     virtual team& current_team_w() = 0;
00424 
00425 
00426     virtual void raise_gamestate_changed() const = 0;
00427 
00428 
00429     virtual game_info& get_info_w() = 0;
00430 
00431 
00432     /**
00433      * serialize this context to config
00434      */
00435     virtual config to_readwrite_context_config() const = 0;
00436 
00437 };
00438 
00439 //proxies
00440 
00441 class side_context_proxy : public virtual side_context {
00442 public:
00443     side_context_proxy()
00444         : target_(NULL)
00445     {
00446     }
00447 
00448     virtual ~side_context_proxy(){}
00449 
00450 
00451     void init_side_context_proxy(side_context &target)
00452     {
00453         target_= &target.get_side_context();
00454     }
00455 
00456     virtual side_number get_side() const
00457     {
00458         return target_->get_side();
00459     }
00460 
00461     virtual void set_side(side_number side)
00462     {
00463         return target_->set_side(side);
00464     }
00465 
00466     virtual side_context& get_side_context()
00467     {
00468         return target_->get_side_context();
00469     }
00470 
00471     virtual int get_recursion_count() const
00472     {
00473         return target_->get_recursion_count();
00474     }
00475 
00476 
00477     virtual config to_side_context_config() const
00478     {
00479         return target_->to_side_context_config();
00480     }
00481 
00482 
00483 private:
00484     side_context *target_;
00485 };
00486 
00487 
00488 class readonly_context_proxy : public virtual readonly_context, public virtual side_context_proxy {
00489 public:
00490     readonly_context_proxy()
00491         : target_(NULL)
00492     {
00493     }
00494 
00495     virtual ~readonly_context_proxy() {}
00496 
00497     void init_readonly_context_proxy(readonly_context &target)
00498     {
00499         init_side_context_proxy(target);
00500         target_ = &target.get_readonly_context();
00501     }
00502 
00503     virtual readonly_context& get_readonly_context()
00504     {
00505         return target_->get_readonly_context();
00506     }
00507 
00508 
00509     virtual void on_readonly_context_create()
00510     {
00511         return target_->on_readonly_context_create();
00512     }
00513 
00514 
00515     virtual const team& current_team() const
00516     {
00517         return target_->current_team();
00518     }
00519 
00520     virtual void diagnostic(const std::string& msg)
00521     {
00522         target_->diagnostic(msg);
00523     }
00524 
00525     virtual void log_message(const std::string& msg)
00526     {
00527         target_->log_message(msg);
00528     }
00529 
00530     virtual attack_result_ptr check_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon)
00531     {
00532         return target_->check_attack_action(attacker_loc, defender_loc, attacker_weapon);
00533     }
00534 
00535     virtual move_result_ptr check_move_action(const map_location &from, const map_location &to, bool remove_movement=true)
00536     {
00537         return target_->check_move_action(from, to, remove_movement);
00538     }
00539 
00540 
00541     virtual recall_result_ptr check_recall_action(const std::string &id, const map_location &where = map_location::null_location,
00542             const map_location &from = map_location::null_location)
00543     {
00544         return target_->check_recall_action(id, where, from);
00545     }
00546 
00547 
00548     virtual recruit_result_ptr check_recruit_action(const std::string &unit_name, const map_location &where = map_location::null_location,
00549             const map_location &from = map_location::null_location)
00550     {
00551         return target_->check_recruit_action(unit_name, where, from);
00552     }
00553 
00554     virtual stopunit_result_ptr check_stopunit_action(const map_location &unit_location, bool remove_movement = true, bool remove_attacks = false)
00555     {
00556         return target_->check_stopunit_action(unit_location, remove_movement, remove_attacks);
00557     }
00558 
00559     virtual void calculate_possible_moves(std::map<map_location,pathfind::paths>& possible_moves,
00560         move_map& srcdst, move_map& dstsrc, bool enemy,
00561         bool assume_full_movement=false,
00562         const terrain_filter* remove_destinations=NULL) const
00563     {
00564         target_->calculate_possible_moves(possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations);
00565     }
00566 
00567     virtual void calculate_moves(const unit_map& units,
00568         std::map<map_location,pathfind::paths>& possible_moves, move_map& srcdst,
00569         move_map& dstsrc, bool enemy, bool assume_full_movement=false,
00570         const terrain_filter* remove_destinations=NULL,
00571         bool see_all=false) const
00572     {
00573         target_->calculate_moves(units, possible_moves, srcdst, dstsrc, enemy, assume_full_movement, remove_destinations, see_all);
00574     }
00575 
00576     virtual const game_info& get_info() const
00577     {
00578         return target_->get_info();
00579     }
00580 
00581     virtual void raise_user_interact() const
00582     {
00583         target_->raise_user_interact();
00584     }
00585 
00586 
00587     virtual int get_recursion_count() const
00588     {
00589         return target_->get_recursion_count();
00590     }
00591 
00592     //@note: following part is in alphabetic order
00593     defensive_position const& best_defensive_position(const map_location& unit,
00594             const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const
00595     {
00596         return target_->best_defensive_position(unit,dstsrc,srcdst,enemy_dstsrc);
00597     }
00598 
00599 
00600     virtual std::map<map_location,defensive_position>& defensive_position_cache() const
00601     {
00602         return target_->defensive_position_cache();
00603     }
00604 
00605 
00606     virtual double get_aggression() const
00607     {
00608         return target_->get_aggression();
00609     }
00610 
00611 
00612     virtual int get_attack_depth() const
00613     {
00614         return target_->get_attack_depth();
00615     }
00616 
00617 
00618     virtual const aspect_map& get_aspects() const
00619     {
00620         return target_->get_aspects();
00621     }
00622 
00623 
00624     virtual aspect_map& get_aspects()
00625     {
00626         return target_->get_aspects();
00627     }
00628 
00629 
00630     virtual void add_aspects(std::vector< aspect_ptr > &aspects )
00631     {
00632         return target_->add_aspects(aspects);
00633     }
00634 
00635 
00636     virtual void add_facet(const std::string &id, const config &cfg) const
00637     {
00638         target_->add_facet(id,cfg);
00639     }
00640 
00641 
00642 
00643     virtual const attacks_vector& get_attacks() const
00644     {
00645         return target_->get_attacks();
00646     }
00647 
00648 
00649 
00650     virtual const variant& get_attacks_as_variant() const
00651     {
00652         return target_->get_attacks_as_variant();
00653     }
00654 
00655 
00656     virtual const terrain_filter& get_avoid() const
00657     {
00658         return target_->get_avoid();
00659     }
00660 
00661 
00662     virtual double get_caution() const
00663     {
00664         return target_->get_caution();
00665     }
00666 
00667 
00668     virtual const move_map& get_dstsrc() const
00669     {
00670         return target_->get_dstsrc();
00671     }
00672 
00673 
00674     virtual const move_map& get_enemy_dstsrc() const
00675     {
00676         return target_->get_enemy_dstsrc();
00677     }
00678 
00679 
00680     virtual const moves_map& get_enemy_possible_moves() const
00681     {
00682         return target_->get_enemy_possible_moves();
00683     }
00684 
00685 
00686     virtual const move_map& get_enemy_srcdst() const
00687     {
00688         return target_->get_enemy_srcdst();
00689     }
00690 
00691 
00692     virtual engine_ptr get_engine_by_cfg(const config &cfg)
00693     {
00694         return target_->get_engine_by_cfg(cfg);
00695     }
00696 
00697 
00698     virtual const std::vector<engine_ptr>& get_engines() const
00699     {
00700         return target_->get_engines();
00701     }
00702 
00703 
00704     virtual std::vector<engine_ptr>& get_engines()
00705     {
00706         return target_->get_engines();
00707     }
00708 
00709 
00710     virtual std::string get_grouping() const
00711     {
00712         return target_->get_grouping();
00713     }
00714 
00715 
00716     virtual const std::vector<goal_ptr>& get_goals() const
00717     {
00718         return target_->get_goals();
00719     }
00720 
00721 
00722     virtual std::vector<goal_ptr>& get_goals()
00723     {
00724         return target_->get_goals();
00725     }
00726 
00727 
00728     virtual double get_leader_aggression() const
00729     {
00730         return target_->get_leader_aggression();
00731     }
00732 
00733 
00734 
00735     virtual config get_leader_goal() const
00736     {
00737         return target_->get_leader_goal();
00738     }
00739 
00740 
00741     virtual double get_leader_value() const
00742     {
00743         return target_->get_leader_value();
00744     }
00745 
00746 
00747     virtual double get_number_of_possible_recruits_to_force_recruit() const
00748     {
00749         return target_->get_number_of_possible_recruits_to_force_recruit();
00750     }
00751 
00752 
00753     virtual bool get_passive_leader() const
00754     {
00755         return target_->get_passive_leader();
00756     }
00757 
00758 
00759     virtual bool get_passive_leader_shares_keep() const
00760     {
00761         return target_->get_passive_leader_shares_keep();
00762     }
00763 
00764 
00765     virtual const moves_map& get_possible_moves() const
00766     {
00767         return target_->get_possible_moves();
00768     }
00769 
00770 
00771     virtual double power_projection(const map_location& loc, const move_map& dstsrc) const
00772     {
00773         return target_->power_projection(loc,dstsrc);
00774     }
00775 
00776 
00777     virtual const std::vector<unit>& get_recall_list() const
00778     {
00779         return target_->get_recall_list();
00780     }
00781 
00782 
00783     virtual stage_ptr get_recruitment(ai_context &context) const
00784     {
00785         return target_->get_recruitment(context);
00786     }
00787 
00788 
00789     virtual bool get_recruitment_ignore_bad_combat() const
00790     {
00791         return target_->get_recruitment_ignore_bad_combat();
00792     }
00793 
00794 
00795     virtual bool get_recruitment_ignore_bad_movement() const
00796     {
00797         return target_->get_recruitment_ignore_bad_movement();
00798     }
00799 
00800 
00801     virtual const std::vector<std::string> get_recruitment_pattern() const
00802     {
00803         return target_->get_recruitment_pattern();
00804     }
00805 
00806 
00807     virtual const move_map& get_srcdst() const
00808     {
00809         return target_->get_srcdst();
00810     }
00811 
00812 
00813     virtual double get_scout_village_targeting() const
00814     {
00815         return target_->get_scout_village_targeting();
00816     }
00817 
00818 
00819     virtual bool get_simple_targeting() const
00820     {
00821         return target_->get_simple_targeting();
00822     }
00823 
00824 
00825     virtual bool get_support_villages() const
00826     {
00827         return target_->get_support_villages();
00828     }
00829 
00830 
00831     virtual double get_village_value() const
00832     {
00833         return target_->get_village_value();
00834     }
00835 
00836 
00837     virtual int get_villages_per_scout() const
00838     {
00839         return target_->get_villages_per_scout();
00840     }
00841 
00842 
00843 
00844     virtual bool is_active(const std::string &time_of_day, const std::string &turns) const
00845     {
00846         return target_->is_active(time_of_day, turns);
00847     }
00848     
00849     virtual bool is_dst_src_valid_lua() const
00850     {
00851         return target_->is_dst_src_valid_lua();
00852     }
00853     
00854     virtual bool is_dst_src_enemy_valid_lua() const
00855     {
00856         return target_->is_dst_src_enemy_valid_lua();
00857     }
00858 
00859     virtual bool is_src_dst_valid_lua() const
00860     {
00861         return target_->is_src_dst_valid_lua();
00862     }
00863     
00864     virtual bool is_src_dst_enemy_valid_lua() const
00865     {
00866         return target_->is_src_dst_enemy_valid_lua();
00867     }
00868 
00869     virtual void invalidate_defensive_position_cache() const
00870     {
00871         return target_->invalidate_defensive_position_cache();
00872     }
00873 
00874 
00875     virtual void invalidate_move_maps() const
00876     {
00877         target_->invalidate_move_maps();
00878     }
00879 
00880 
00881     virtual void invalidate_keeps_cache() const
00882     {
00883         return target_->invalidate_keeps_cache();
00884     }
00885 
00886 
00887     virtual const std::set<map_location>& keeps() const
00888     {
00889         return target_->keeps();
00890     }
00891 
00892 
00893     virtual bool leader_can_reach_keep() const
00894     {
00895         return target_->leader_can_reach_keep();
00896     }
00897 
00898 
00899     virtual const map_location& nearest_keep( const map_location& loc ) const
00900     {
00901         return target_->nearest_keep(loc);
00902     }
00903 
00904 
00905     virtual void recalculate_move_maps() const
00906     {
00907         target_->recalculate_move_maps();
00908     }
00909 
00910 
00911     virtual void recalculate_move_maps_enemy() const
00912     {
00913         target_->recalculate_move_maps_enemy();
00914     }
00915     
00916     virtual void set_dst_src_valid_lua() 
00917     {
00918         target_->set_dst_src_valid_lua();
00919     }
00920     
00921     virtual void set_dst_src_enemy_valid_lua() 
00922     {
00923         target_->set_dst_src_enemy_valid_lua();
00924     }
00925     
00926     virtual void set_src_dst_valid_lua() 
00927     {
00928         target_->set_src_dst_valid_lua();
00929     }
00930     
00931     virtual void set_src_dst_enemy_valid_lua() 
00932     {
00933         target_->set_src_dst_enemy_valid_lua();
00934     }   
00935 
00936     virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths )
00937     {
00938         return target_->suitable_keep(leader_location, leader_paths);
00939     }
00940 
00941 
00942     virtual config to_readonly_context_config() const
00943     {
00944         return target_->to_readonly_context_config();
00945     }
00946 
00947 
00948     virtual std::map<std::pair<map_location,const unit_type *>,
00949         std::pair<battle_context_unit_stats,battle_context_unit_stats> >& unit_stats_cache() const
00950     {
00951         return target_->unit_stats_cache();
00952     }
00953 
00954 
00955 private:
00956     readonly_context *target_;
00957 };
00958 
00959 
00960 class readwrite_context_proxy : public virtual readwrite_context, public virtual readonly_context_proxy {
00961 public:
00962     readwrite_context_proxy()
00963         : target_(NULL)
00964     {
00965     }
00966 
00967 
00968     void init_readwrite_context_proxy(readwrite_context &target)
00969     {
00970         init_readonly_context_proxy(target);
00971         target_ = &target.get_readwrite_context();
00972     }
00973 
00974 
00975     virtual readwrite_context& get_readwrite_context()
00976     {
00977         return target_->get_readwrite_context();
00978     }
00979 
00980 
00981     virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon)
00982     {
00983         return target_->execute_attack_action(attacker_loc,defender_loc,attacker_weapon);
00984     }
00985 
00986 
00987     virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true)
00988     {
00989         return target_->execute_move_action(from, to, remove_movement);
00990     }
00991 
00992 
00993     virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location)
00994     {
00995         return target_->execute_recall_action(id,where,from);
00996     }
00997 
00998 
00999     virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location)
01000     {
01001         return target_->execute_recruit_action(unit_name,where,from);
01002     }
01003 
01004 
01005     virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false)
01006     {
01007         return target_->execute_stopunit_action(unit_location,remove_movement,remove_attacks);
01008     }
01009 
01010 
01011     virtual team& current_team_w()
01012     {
01013         return target_->current_team_w();
01014     }
01015 
01016 
01017     virtual void raise_gamestate_changed() const
01018     {
01019         target_->raise_gamestate_changed();
01020     }
01021 
01022 
01023     virtual game_info& get_info_w()
01024     {
01025         return target_->get_info_w();
01026     }
01027 
01028 
01029     virtual int get_recursion_count() const
01030     {
01031         return target_->get_recursion_count();
01032     }
01033 
01034 
01035     virtual config to_readwrite_context_config() const
01036     {
01037         return target_->to_readwrite_context_config();
01038     }
01039 
01040 private:
01041     readwrite_context *target_;
01042 };
01043 
01044 
01045 //implementation
01046 class side_context_impl : public side_context {
01047 public:
01048     side_context_impl(side_number side, const config  &/*cfg*/)
01049         : side_(side), recursion_counter_(0)
01050     {
01051     }
01052 
01053     virtual ~side_context_impl(){}
01054 
01055     virtual side_number get_side() const
01056     {
01057         return side_;
01058     }
01059 
01060     virtual void set_side(side_number side)
01061     {
01062         side_ = side;
01063     }
01064 
01065 
01066     virtual side_context& get_side_context()
01067     {
01068         return *this;
01069     }
01070 
01071 
01072     virtual int get_recursion_count() const;
01073 
01074 
01075     virtual config to_side_context_config() const;
01076 
01077 private:
01078     side_number side_;
01079     recursion_counter recursion_counter_;
01080 };
01081 
01082 
01083 class readonly_context_impl : public virtual side_context_proxy, public readonly_context, public events::observer {
01084 public:
01085 
01086     /**
01087      * Constructor
01088      */
01089     readonly_context_impl(side_context &context, const config &cfg);
01090 
01091 
01092     /**
01093      * Destructor
01094      */
01095     virtual ~readonly_context_impl();
01096 
01097 
01098     /**
01099      * Unwrap - this class is not a proxy, so return *this
01100 :w
01101      */
01102     virtual readonly_context& get_readonly_context()
01103     {
01104         return *this;
01105     }
01106 
01107 
01108     virtual void on_readonly_context_create();
01109 
01110 
01111     /** Handle generic event */
01112     virtual void handle_generic_event(const std::string& event_name);
01113 
01114 
01115     /** Return a reference to the 'team' object for the AI. */
01116     const team& current_team() const;
01117 
01118 
01119     /** Show a diagnostic message on the screen. */
01120     void diagnostic(const std::string& msg);
01121 
01122 
01123     /** Display a debug message as a chat message. */
01124     void log_message(const std::string& msg);
01125 
01126 
01127     /**
01128      * Check if it is possible to attack enemy defender using our unit attacker from attackers current location,
01129      * @param attacker_loc location of attacker
01130      * @param defender_loc location of defender
01131      * @param attacker_weapon weapon of attacker
01132      * @retval possible result: ok
01133      * @retval possible result: something wrong
01134      * @retval possible result: attacker and/or defender are invalid
01135      * @retval possible result: attacker and/or defender are invalid
01136      * @retval possible result: attacker doesn't have the specified weapon
01137      */
01138     attack_result_ptr check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon);
01139 
01140 
01141     /**
01142      * Check if it is possible to move our unit from location 'from' to location 'to'
01143      * @param from location of our unit
01144      * @param to where to move
01145      * @param remove_movement set unit movement to 0 in case of successful move
01146      * @retval possible result: ok
01147      * @retval possible result: something wrong
01148      * @retval possible result: move is interrupted
01149      * @retval possible result: move is impossible
01150      */
01151     move_result_ptr check_move_action(const map_location& from, const map_location& to, bool remove_movement=true);
01152 
01153 
01154 
01155     /**
01156      * Check if it is possible to recall a unit for us on specified location
01157      * @param id the id of the unit to be recruited.
01158      * @param where location where the unit is to be recruited.
01159      * @retval possible result: ok
01160      * @retval possible_result: something wrong
01161      * @retval possible_result: leader not on keep
01162      * @retval possible_result: no free space on keep
01163      * @retval possible_result: not enough gold
01164      */
01165     recall_result_ptr check_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location);
01166 
01167 
01168     /**
01169      * Check if it is possible to recruit a unit for us on specified location
01170      * @param unit_name the name of the unit to be recruited.
01171      * @param where location where the unit is to be recruited.
01172      * @retval possible result: ok
01173      * @retval possible_result: something wrong
01174      * @retval possible_result: leader not on keep
01175      * @retval possible_result: no free space on keep
01176      * @retval possible_result: not enough gold
01177      */
01178     recruit_result_ptr check_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location);
01179 
01180 
01181     /**
01182      * Check if it is possible to remove unit movements and/or attack
01183      * @param unit_location the location of our unit
01184      * @param remove_movement set remaining movements to 0
01185      * @param remove_attacks set remaining attacks to 0
01186      * @retval possible result: ok
01187      * @retval possible_result: something wrong
01188      * @retval possible_result: nothing to do
01189      */
01190     stopunit_result_ptr check_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false);
01191 
01192 
01193     /**
01194      * Calculate the moves units may possibly make.
01195      *
01196      * @param possible_moves      A map which will be filled with the paths
01197      *                            each unit can take to get to every possible
01198      *                            destination. You probably don't want to use
01199      *                            this object at all, except to pass to
01200      *                            'move_unit'.
01201      * @param srcdst              A map of units to all their possible
01202      *                            destinations.
01203      * @param dstsrc              A map of destinations to all the units that
01204      *                            can move to that destination.
01205      * @param enemy               if true, a map of possible moves for enemies
01206      *                            will be calculated. If false, a map of
01207      *                            possible moves for units on the AI's side
01208      *                            will be calculated.  The AI's own leader will
01209      *                            not be included in this map.
01210      * @param assume_full_movement
01211      *                            If true, the function will operate on the
01212      *                            assumption that all units can move their full
01213      *                            movement allotment.
01214      * @param remove_destinations a pointer to a terrain filter for possible destinations
01215      *                            to omit.
01216      */
01217     void calculate_possible_moves(std::map<map_location,pathfind::paths>& possible_moves,
01218         move_map& srcdst, move_map& dstsrc, bool enemy,
01219         bool assume_full_movement=false,
01220         const terrain_filter* remove_destinations=NULL) const;
01221 
01222     /**
01223      * A more fundamental version of calculate_possible_moves which allows the
01224      * use of a speculative unit map.
01225      */
01226     void calculate_moves(const unit_map& units,
01227         std::map<map_location,pathfind::paths>& possible_moves, move_map& srcdst,
01228         move_map& dstsrc, bool enemy, bool assume_full_movement=false,
01229         const terrain_filter* remove_destinations=NULL,
01230         bool see_all=false) const;
01231 
01232 
01233     virtual const game_info& get_info() const;
01234 
01235     /**
01236      * Function which should be called frequently to allow the user to interact
01237      * with the interface. This function will make sure that interaction
01238      * doesn't occur too often, so there is no problem with calling it very
01239      * regularly.
01240      */
01241     void raise_user_interact() const;
01242 
01243 
01244     virtual int get_recursion_count() const;
01245 
01246 
01247     //@note: following functions are in alphabetic order
01248     defensive_position const& best_defensive_position(const map_location& unit,
01249             const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const;
01250 
01251 
01252     virtual std::map<map_location,defensive_position>& defensive_position_cache() const;
01253 
01254 
01255     virtual double get_aggression() const;
01256 
01257 
01258     virtual int get_attack_depth() const;
01259 
01260 
01261     virtual const aspect_map& get_aspects() const;
01262 
01263 
01264     virtual aspect_map& get_aspects();
01265 
01266 
01267     virtual const attacks_vector& get_attacks() const;
01268 
01269 
01270     virtual const variant& get_attacks_as_variant() const;
01271 
01272 
01273     virtual const terrain_filter& get_avoid() const;
01274 
01275 
01276     virtual double get_caution() const;
01277 
01278 
01279     virtual const move_map& get_dstsrc() const;
01280 
01281 
01282     virtual const move_map& get_enemy_dstsrc() const;
01283 
01284 
01285     virtual const moves_map& get_enemy_possible_moves() const;
01286 
01287 
01288     virtual const move_map& get_enemy_srcdst() const;
01289 
01290 
01291     virtual engine_ptr get_engine_by_cfg(const config& cfg);
01292 
01293 
01294     virtual const std::vector<engine_ptr>& get_engines() const;
01295 
01296 
01297     virtual std::vector<engine_ptr>& get_engines();
01298 
01299 
01300     virtual std::string get_grouping() const;
01301 
01302 
01303     virtual const std::vector<goal_ptr>& get_goals() const;
01304 
01305 
01306     virtual std::vector<goal_ptr>& get_goals();
01307 
01308 
01309     virtual double get_number_of_possible_recruits_to_force_recruit() const;
01310 
01311 
01312     virtual double get_leader_aggression() const;
01313 
01314 
01315     virtual config get_leader_goal() const;
01316 
01317 
01318     virtual double get_leader_value() const;
01319 
01320 
01321     virtual bool get_passive_leader() const;
01322 
01323 
01324     virtual bool get_passive_leader_shares_keep() const;
01325 
01326 
01327     virtual const moves_map& get_possible_moves() const;
01328 
01329 
01330     virtual const std::vector<unit>& get_recall_list() const;
01331 
01332 
01333     virtual stage_ptr get_recruitment(ai_context &context) const;
01334 
01335 
01336     virtual bool get_recruitment_ignore_bad_combat() const;
01337 
01338 
01339     virtual bool get_recruitment_ignore_bad_movement() const;
01340 
01341 
01342     virtual const std::vector<std::string> get_recruitment_pattern() const;
01343 
01344 
01345     virtual double get_scout_village_targeting() const;
01346 
01347 
01348     virtual bool get_simple_targeting() const;
01349 
01350 
01351     virtual const move_map& get_srcdst() const;
01352 
01353 
01354     virtual bool get_support_villages() const;
01355 
01356 
01357     virtual double get_village_value() const;
01358 
01359 
01360     virtual int get_villages_per_scout() const;
01361 
01362 
01363     virtual bool is_active(const std::string &time_of_day, const std::string &turns) const;
01364 
01365     virtual bool is_dst_src_valid_lua() const;
01366 
01367     virtual bool is_dst_src_enemy_valid_lua() const;
01368     
01369     virtual bool is_src_dst_valid_lua() const;
01370 
01371     virtual bool is_src_dst_enemy_valid_lua() const;
01372     
01373     virtual void invalidate_defensive_position_cache() const;
01374 
01375 
01376     virtual void invalidate_move_maps() const;
01377 
01378 
01379     virtual void invalidate_keeps_cache() const;
01380 
01381 
01382     virtual const std::set<map_location>& keeps() const;
01383 
01384 
01385     virtual bool leader_can_reach_keep() const;
01386 
01387 
01388     virtual const map_location& nearest_keep(const map_location& loc) const;
01389 
01390 
01391     virtual double power_projection(const map_location& loc, const move_map& dstsrc) const;
01392 
01393 
01394     virtual void recalculate_move_maps() const;
01395 
01396 
01397     virtual void recalculate_move_maps_enemy() const;
01398 
01399 
01400     virtual void add_aspects(std::vector< aspect_ptr > &aspects);
01401 
01402 
01403     virtual void add_facet(const std::string &id, const config &cfg) const;
01404 
01405 
01406     void on_create();
01407 
01408     virtual void set_dst_src_valid_lua();
01409     
01410     virtual void set_dst_src_enemy_valid_lua();
01411     
01412     virtual void set_src_dst_valid_lua();
01413     
01414     virtual void set_src_dst_enemy_valid_lua();
01415     
01416     virtual const map_location& suitable_keep( const map_location& leader_location, const pathfind::paths& leader_paths );
01417 
01418 
01419     virtual config to_readonly_context_config() const;
01420 
01421 
01422     virtual std::map<std::pair<map_location,const unit_type *>,
01423         std::pair<battle_context_unit_stats,battle_context_unit_stats> >& unit_stats_cache() const;
01424 
01425 private:
01426     template<typename T>
01427     void add_known_aspect(const std::string &name, boost::shared_ptr< typesafe_aspect <T> >& where);
01428 
01429     const config cfg_;
01430 
01431     /**
01432      * AI Support Engines
01433      */
01434     std::vector< engine_ptr > engines_;
01435 
01436     known_aspect_map known_aspects_;
01437 
01438     aspect_type<double>::typesafe_ptr aggression_;
01439     aspect_type<int>::typesafe_ptr attack_depth_;
01440     aspect_map aspects_;
01441     aspect_type< attacks_vector >::typesafe_ptr attacks_;
01442     mutable aspect_type<terrain_filter>::typesafe_ptr avoid_;
01443     aspect_type<double>::typesafe_ptr caution_;
01444     mutable std::map<map_location,defensive_position> defensive_position_cache_;
01445     mutable move_map dstsrc_;
01446     mutable move_map enemy_dstsrc_;
01447     mutable moves_map enemy_possible_moves_;
01448     mutable move_map enemy_srcdst_;
01449     aspect_type< std::string >::typesafe_ptr grouping_;
01450     std::vector< goal_ptr > goals_;
01451     mutable keeps_cache keeps_;
01452     aspect_type<double>::typesafe_ptr leader_aggression_;
01453     aspect_type< config >::typesafe_ptr leader_goal_;
01454     aspect_type< double >::typesafe_ptr leader_value_;
01455     mutable bool move_maps_enemy_valid_;
01456     mutable bool move_maps_valid_;
01457     mutable bool dst_src_valid_lua_;
01458     mutable bool dst_src_enemy_valid_lua_;
01459     mutable bool src_dst_valid_lua_;
01460     mutable bool src_dst_enemy_valid_lua_;
01461     aspect_type<double>::typesafe_ptr number_of_possible_recruits_to_force_recruit_;
01462     aspect_type<bool>::typesafe_ptr passive_leader_;
01463     aspect_type<bool>::typesafe_ptr passive_leader_shares_keep_;
01464     mutable moves_map possible_moves_;
01465     aspect_type< ministage >::typesafe_ptr recruitment_;
01466     aspect_type< bool >::typesafe_ptr recruitment_ignore_bad_combat_;
01467     aspect_type< bool >::typesafe_ptr recruitment_ignore_bad_movement_;
01468     aspect_type< std::vector<std::string> >::typesafe_ptr recruitment_pattern_;
01469     recursion_counter recursion_counter_;
01470     aspect_type< double >::typesafe_ptr scout_village_targeting_;
01471     aspect_type< bool >::typesafe_ptr simple_targeting_;
01472     mutable move_map srcdst_;
01473     aspect_type< bool >::typesafe_ptr support_villages_;
01474     mutable std::map<std::pair<map_location,const unit_type *>,
01475              std::pair<battle_context_unit_stats,battle_context_unit_stats> > unit_stats_cache_;
01476     aspect_type< double >::typesafe_ptr village_value_;
01477     aspect_type< int >::typesafe_ptr villages_per_scout_;
01478 
01479 
01480 };
01481 
01482 class readwrite_context_impl : public virtual readonly_context_proxy, public readwrite_context {
01483 public:
01484     /**
01485      * Unwrap - this class is not a proxy, so return *this
01486      */
01487     virtual readwrite_context& get_readwrite_context()
01488     {
01489         return *this;
01490     }
01491 
01492 
01493     /**
01494      * Ask the game to attack an enemy defender using our unit attacker from attackers current location,
01495      * @param attacker_loc location of attacker
01496      * @param defender_loc location of defender
01497      * @param attacker_weapon weapon of attacker
01498      * @retval possible result: ok
01499      * @retval possible result: something wrong
01500      * @retval possible result: attacker and/or defender are invalid
01501      * @retval possible result: attacker and/or defender are invalid
01502      * @retval possible result: attacker doesn't have the specified weapon
01503      */
01504     virtual attack_result_ptr execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon);
01505 
01506 
01507     /**
01508      * Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial move
01509      * @param from location of our unit
01510      * @param to where to move
01511      * @param remove_movement set unit movement to 0 in case of successful move
01512      * @retval possible result: ok
01513      * @retval possible result: something wrong
01514      * @retval possible result: move is interrupted
01515      * @retval possible result: move is impossible
01516      */
01517     virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true);
01518 
01519 
01520     /**
01521      * Ask the game to recall a unit for us on specified location
01522      * @param id the id of the unit to be recalled.
01523      * @param where location where the unit is to be recalled.
01524      * @retval possible result: ok
01525      * @retval possible_result: something wrong
01526      * @retval possible_result: leader not on keep
01527      * @retval possible_result: no free space on keep
01528      * @retval possible_result: not enough gold
01529      */
01530     virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location);
01531 
01532 
01533     /**
01534      * Ask the game to recruit a unit for us on specified location
01535      * @param unit_name the name of the unit to be recruited.
01536      * @param where location where the unit is to be recruited.
01537      * @retval possible result: ok
01538      * @retval possible_result: something wrong
01539      * @retval possible_result: leader not on keep
01540      * @retval possible_result: no free space on keep
01541      * @retval possible_result: not enough gold
01542      */
01543     virtual recruit_result_ptr execute_recruit_action(const std::string& unit_name, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location);
01544 
01545 
01546     /**
01547      * Ask the game to remove unit movements and/or attack
01548      * @param unit_location the location of our unit
01549      * @param remove_movement set remaining movements to 0
01550      * @param remove_attacks set remaining attacks to 0
01551      * @retval possible result: ok
01552      * @retval possible_result: something wrong
01553      * @retval possible_result: nothing to do
01554      */
01555     virtual stopunit_result_ptr execute_stopunit_action(const map_location& unit_location, bool remove_movement = true, bool remove_attacks = false);
01556 
01557 
01558     /** Return a reference to the 'team' object for the AI. */
01559     virtual team& current_team_w();
01560 
01561 
01562     /** Notifies all interested observers of the event respectively. */
01563     void raise_gamestate_changed() const;
01564 
01565 
01566     /**
01567      * Constructor.
01568      */
01569     readwrite_context_impl(readonly_context &context, const config &/*cfg*/)
01570         : recursion_counter_(context.get_recursion_count())
01571     {
01572         init_readonly_context_proxy(context);
01573     }
01574 
01575 
01576     virtual ~readwrite_context_impl()
01577     {
01578     }
01579 
01580     /**
01581      * Functions to retrieve the 'info' object.
01582      * Used by derived classes to discover all necessary game information.
01583      */
01584     virtual game_info& get_info_w();
01585 
01586 
01587     virtual int get_recursion_count() const;
01588 
01589 
01590     virtual config to_readwrite_context_config() const;
01591 
01592 private:
01593     recursion_counter recursion_counter_;
01594 };
01595 
01596 
01597 } //end of namespace ai
01598 
01599 #ifdef _MSC_VER
01600 #pragma warning(pop)
01601 #endif
01602 
01603 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:28 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs