ai/manager.hpp

Go to the documentation of this file.
00001 /* $Id: manager.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
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  * Managing the AIs lifecycle - headers
00019  * @todo 1.9 Refactor history handling and internal commands.
00020  * @todo 1.9 AI Interface command to clear the history.
00021  */
00022 
00023 #ifndef AI_MANAGER_HPP_INCLUDED
00024 #define AI_MANAGER_HPP_INCLUDED
00025 
00026 #include "../config.hpp"
00027 #include "../generic_event.hpp"
00028 
00029 #include "game_info.hpp"
00030 
00031 #include <stack>
00032 #include <deque>
00033 
00034 
00035 namespace ai {
00036 
00037 class interface;
00038 
00039 class side_context;
00040 class readonly_context;
00041 class readwrite_context;
00042 class default_ai_context;
00043 class ai_context;
00044 
00045 class ai_composite;
00046 typedef boost::shared_ptr<ai_composite> composite_ai_ptr;
00047 
00048 /**
00049  * Base class that holds the AI and current AI parameters.
00050  * It is an implementation detail.
00051  * @todo 1.9 move it out of public view
00052  */
00053 class holder{
00054 public:
00055     holder(side_number side, const config &cfg);
00056 
00057     virtual ~holder();
00058 
00059     interface& get_ai_ref();
00060 
00061     const std::string describe_ai();
00062 
00063     void modify_ai_config_old( const config::const_child_itors &ai_parameters );
00064 
00065     config to_config() const;
00066 
00067     void modify_ai(const config& cfg);
00068 
00069 
00070     const std::string get_ai_overview();
00071 
00072 
00073     const std::string get_ai_structure();
00074 
00075 
00076     const std::string get_ai_identifier() const;
00077 
00078 private:
00079     void init( side_number side );
00080 
00081 
00082     composite_ai_ptr ai_;
00083     side_context *side_context_;
00084     readonly_context *readonly_context_;
00085     readwrite_context *readwrite_context_;
00086     default_ai_context *default_ai_context_;
00087     side_number side_;
00088     config cfg_;
00089 };
00090 
00091 /**
00092  * AI Command History Item. It is an implementation detail
00093  */
00094 class command_history_item{
00095 public:
00096 
00097     command_history_item(int number, const std::string &command)
00098         : number_(number), command_(command)
00099     {}
00100 
00101     int get_number() const { return number_; }
00102 
00103     const std::string& get_command() const { return command_; }
00104 
00105 private:
00106     int number_;
00107     std::string command_;
00108 
00109 };
00110 
00111 /**
00112  * Class that manages AIs for all sides and manages AI redeployment.
00113  * This class is responsible for managing the AI lifecycle
00114  * It can be accessed like this:   ai::manager::foo(...);
00115  */
00116 class manager
00117 {
00118 public:
00119 
00120     // =======================================================================
00121     // CONSTANTS
00122     // =======================================================================
00123 
00124     static const size_t MAX_HISTORY_SIZE = 200;
00125 
00126     static const std::string AI_TYPE_COMPOSITE_AI;
00127     static const std::string AI_TYPE_SAMPLE_AI;
00128     static const std::string AI_TYPE_IDLE_AI;
00129     static const std::string AI_TYPE_FORMULA_AI;
00130     static const std::string AI_TYPE_DFOOL_AI;
00131     static const std::string AI_TYPE_AI2;
00132     static const std::string AI_TYPE_DEFAULT;
00133 
00134 
00135     // =======================================================================
00136     // LIFECYCLE
00137     // =======================================================================
00138 
00139     /**
00140      * Sets AI information.
00141      * @param info ai_information to be set.
00142      */
00143     static void set_ai_info(const game_info& info);
00144 
00145 
00146     /**
00147      * Clears AI information.
00148      * Should be called in playsingle_controller 's destructor.
00149      */
00150     static void clear_ai_info();
00151 
00152 
00153     /**
00154      * Adds observer of game events.
00155      * Should be called in playsingle_controller 's constructor.
00156      */
00157     static void add_observer( events::observer* event_observer);
00158 
00159 
00160     /**
00161      * Removes an observer of game events.
00162      * Should be called in playsingle_controller 's destructor.
00163      */
00164     static void remove_observer( events::observer* event_observer );
00165 
00166 
00167     /**
00168      * Adds observer of game events except ai_user_interact event and ai_sync_network event
00169      */
00170     static void add_gamestate_observer( events::observer* event_observer);
00171 
00172 
00173     /**
00174      * Removes an observer of game events except ai_user_interact event and ai_sync_network event
00175      */
00176     static void remove_gamestate_observer( events::observer* event_observer );
00177 
00178 
00179     /**
00180      * Notifies all observers of 'ai_user_interact' event.
00181      * Function which should be called frequently to allow the user to interact
00182      * with the interface. This function will make sure that interaction
00183      * doesn't occur too often, so there is no problem with calling it very
00184      * regularly.
00185      */
00186     static void raise_user_interact();
00187 
00188     /**
00189      * Notifies all observers of 'ai_sync_network' event.
00190      * Basically a request from the AI to sync the network.
00191      */
00192     static void raise_sync_network();
00193 
00194 
00195     /**
00196      * Notifies all observers of 'ai_gamestate_changed' event.
00197      */
00198     static void raise_gamestate_changed();
00199 
00200 
00201     /**
00202      * Notifies all observers of 'ai_recruit_list_changed' event.
00203      */
00204     static void raise_recruit_list_changed();
00205 
00206 
00207     /**
00208      * Notifies all observers of 'ai_turn_started' event.
00209      */
00210     static void raise_turn_started();
00211 
00212 
00213     /**
00214      * Notifies all observers of 'ai_map_changed' event.
00215      */
00216     static void raise_map_changed();
00217 
00218 
00219     /**
00220      * Adds an observer of 'ai_map_changed' event.
00221      */
00222     static void add_map_changed_observer( events::observer* event_observer );
00223 
00224 
00225     /**
00226      * Adds an observer of 'ai_recruit_list_changed' event.
00227      */
00228     static void add_recruit_list_changed_observer( events::observer* event_observer );
00229 
00230 
00231     /**
00232      * Adds an observer of 'ai_turn_started' event.
00233      */
00234     static void add_turn_started_observer( events::observer* event_observer );
00235 
00236 
00237     /**
00238      * Deletes an observer of 'ai_map_changed' event.
00239      */
00240     static void remove_map_changed_observer( events::observer* event_observer );
00241 
00242 
00243 
00244     /**
00245      * Deletes an observer of 'ai_recruit_list_changed' event.
00246      */
00247     static void remove_recruit_list_changed_observer( events::observer* event_observer );
00248 
00249 
00250     /**
00251      * Deletes an observer of 'ai_turn_started' event.
00252      */
00253     static void remove_turn_started_observer( events::observer* event_observer );
00254 
00255 
00256 private:
00257 
00258     manager();
00259 
00260 
00261 public:
00262 
00263     // =======================================================================
00264     // EVALUATION
00265     // =======================================================================
00266 
00267     /**
00268      * Evaluates a string command using command AI.
00269      * @note Running this command may invalidate references previously returned
00270      *       by manager. Will intercept those commands which start with '!'
00271      *       and '?', and will try to evaluate them as internal commands.
00272      * @param side side number (1-based).
00273      * @param str string to evaluate.
00274      * @return string result of evaluation.
00275      */
00276     static const std::string evaluate_command( side_number side, const std::string& str );
00277 
00278 
00279     // =======================================================================
00280     // ADD, CREATE AIs, OR LIST AI TYPES
00281     // =======================================================================
00282 
00283     /**
00284      * Adds active AI for specified @a side from @a file.
00285      * @note Running this command may invalidate references previously returned
00286      *       by manager. AI is not initialized at this point.
00287      * @param side side number (1-based, as in game_info).
00288      * @param file file name, follows the usual WML convention.
00289      * @param replace should new ai replace the current ai or 'be placed on top of it'.
00290      * @return true if successful.
00291      */
00292     static bool add_ai_for_side_from_file( side_number side, const std::string& file, bool replace = true );
00293 
00294 
00295     /**
00296      * Adds active AI for specified @a side from @a cfg.
00297      * @note Running this command may invalidate references previously returned
00298      *       by manager. AI is not initialized at this point.
00299      * @param side side number (1-based, as in game_info).
00300      * @param cfg the config from which all ai parameters are to be read.
00301      * @param replace should new ai replace the current ai or 'be placed on top of it'.
00302      * @return true if successful.
00303      */
00304     static bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace = true);
00305 
00306 
00307     /**
00308      * Adds active AI for specified @a side from parameters.
00309      * @note Running this command may invalidate references previously returned
00310      *       by manager. AI is not initialized at this point.
00311      * @param side side number (1-based, as in game_info).
00312      * @param ai_algorithm_type type of AI algorithm to create.
00313      * @param replace should new ai replace the current ai or 'be placed on top of it'.
00314      * @return true if successful.
00315      */
00316     static bool add_ai_for_side( side_number side, const std::string& ai_algorithm_type, bool replace = true);
00317 
00318 
00319     /**
00320      * Returns a smart pointer to a new AI.
00321      * @param ai_algorithm_type type of AI algorithm to create
00322      * @param cfg a config of the ai
00323      * @param context context in which this ai is created
00324      * @return the reference to the created AI
00325      */
00326     static ai_ptr create_transient_ai( const std::string &ai_algorithm_type, const config &cfg, ai_context *ai_context);
00327 
00328 
00329     // =======================================================================
00330     // REMOVE
00331     // =======================================================================
00332 
00333     /**
00334      * Removes top-level AI from @a side.
00335      * @note Running this command may invalidate references previously returned
00336      *       by manager.
00337      * @param side side number (1-based, as in game_info).
00338      */
00339     static void remove_ai_for_side( side_number side );
00340 
00341 
00342     /**
00343      * Removes all AIs from @a side.
00344      * @note Running this command may invalidate references previously returned
00345      *       by manager.
00346      * @param side side number (1-based, as in game_info).
00347      */
00348     static void remove_all_ais_for_side( side_number side );
00349 
00350 
00351     /**
00352      * Clears all the AIs.
00353      * @note Running this command may invalidate references previously returned
00354      *       by manager. For example, this is called from the destructor of
00355      *       playsingle_controller. It is necessary to do this if any of the
00356      *       info structures used by the AI goes out of scope.
00357      */
00358     static void clear_ais();
00359 
00360     // =======================================================================
00361     // GET active AI parameters
00362     // =======================================================================
00363 
00364 
00365     /**
00366      * Gets AI info for active AI of the given @a side.
00367      * @param side side number (1-based).
00368      * @return a reference to active AI info.
00369      */
00370     static game_info& get_active_ai_info_for_side( side_number side );
00371 
00372 
00373     /**
00374      * Gets AI Overview for active AI of the given @a side
00375      * @param side side number (1-based)
00376      * @return an ai overview
00377      */
00378     static std::string get_active_ai_overview_for_side( side_number side);
00379 
00380 
00381     /**
00382      * Gets AI Structure for active AI of the given @a side
00383      * @param side side number (1-based)
00384      * @return an ai structure
00385      */
00386     static std::string get_active_ai_structure_for_side( side_number side);
00387 
00388     /**
00389      * Gets AI algorithm identifier for active AI of the given @a side.
00390      * @param side side number (1-based).
00391      * @return ai identifier for the active AI
00392      */
00393     static std::string get_active_ai_identifier_for_side( side_number side );
00394 
00395 
00396     /**
00397      * Gets AI config for active AI of the given @a side.
00398      * @param side side number (1-based).
00399      * @return a config object for the active AI
00400      */
00401     static config to_config( side_number side );
00402 
00403 
00404     /**
00405      * Gets global AI-game info
00406      * @return a reference to the AI-game info.
00407      */
00408     static game_info& get_ai_info();
00409 
00410 
00411     // =======================================================================
00412     // SET active AI parameters
00413     // =======================================================================
00414 
00415 
00416     /**
00417      * Modifies AI parameters for active AI of the given @a side.
00418      * This function is provided for backward-compatibility with [modify_side][ai]...[/ai][/modify_side]
00419      * It can only add new facets to aspects
00420      * @param side side_number (1-based, as in game_info).
00421      * @param ai_parameters AI parameters to be modified.
00422      */
00423     static void modify_active_ai_config_old_for_side ( side_number side, const config::const_child_itors &ai_parameters );
00424 
00425 
00426 
00427     /**
00428      * Modifies AI parameters for active AI of the given @a side.
00429      * This function is a backend for [modify_ai] tag
00430      * @param side side_number (1-based, as in game_info).
00431      * @param cfg - content of [modify_ai] tag
00432      */
00433 
00434     static void modify_active_ai_for_side( ai::side_number, const config &cfg );
00435 
00436     // =======================================================================
00437     // PROXY
00438     // =======================================================================
00439 
00440     /**
00441      * Plays a turn for the specified side using its active AI.
00442      * @param side side number (1-based, as in game_info).
00443      */
00444     static void play_turn(side_number side);
00445 
00446 
00447 private:
00448 
00449     typedef std::map< side_number, std::stack< holder > > AI_map_of_stacks;
00450     static AI_map_of_stacks ai_map_;
00451     static std::deque< command_history_item > history_;
00452     static long history_item_counter_;
00453     static game_info *ai_info_;
00454 
00455     static events::generic_event map_changed_;
00456     static events::generic_event recruit_list_changed_;
00457     static events::generic_event user_interact_;
00458     static events::generic_event sync_network_;
00459     static events::generic_event gamestate_changed_;
00460     static events::generic_event turn_started_;
00461     static int last_interact_;
00462     static int num_interact_;
00463 
00464 
00465 
00466     // =======================================================================
00467     // EVALUATION
00468     // =======================================================================
00469 
00470     /**
00471      * Evaluates an internal manager command.
00472      * @param side side number (1-based).
00473      * @param str string to evaluate.
00474      * @return string result of evaluation.
00475      * @todo 1.9 rewrite this function to use a fai or lua parser.
00476      */
00477     static const std::string internal_evaluate_command( side_number side, const std::string& str );
00478 
00479     /**
00480      * Determines if the command should be intercepted and evaluated as internal command.
00481      * @param str command string to check.
00482      * @return true if the command should be intercepted and evaluated.
00483      */
00484     static bool should_intercept( const std::string& str );
00485 
00486     // =======================================================================
00487     // AI STACKS
00488     // =======================================================================
00489 
00490 
00491     /**
00492      * Gets the AI stack for the specified side, create it if it doesn't exist.
00493      */
00494     static std::stack< holder >& get_or_create_ai_stack_for_side(side_number side);
00495 
00496     // =======================================================================
00497     // AI HOLDERS
00498     // =======================================================================
00499 
00500 
00501     /**
00502      * Gets active holder for specified @a side.
00503      */
00504     static holder& get_active_ai_holder_for_side( side_number side );
00505 
00506     // =======================================================================
00507     // AI POINTERS
00508     // =======================================================================
00509 
00510     /**
00511      * Gets active AI for specified side.
00512      * @note Running this command may invalidate references previously returned
00513      *       by manager.
00514      * @param side side number (1-based, as in game_info).
00515      * @return a reference to the active AI.
00516      * @note This reference may become invalid after specific manager operations.
00517      */
00518     static interface& get_active_ai_for_side( side_number side );
00519 
00520 
00521 };
00522 
00523 } //end of namespace ai
00524 
00525 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue May 22 2012 01:03:34 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs