The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
manager.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Yurii Chernyi <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Managing the AIs lifecycle - headers
18  * @todo 1.9 Refactor history handling and internal commands.
19  * @todo 1.9 AI Interface command to clear the history.
20  */
21 
22 #ifndef AI_MANAGER_HPP_INCLUDED
23 #define AI_MANAGER_HPP_INCLUDED
24 
25 #include "config.hpp" // for config, etc
26 #include "global.hpp"
27 #include "ai/game_info.hpp" // for side_number, ai_ptr
28 
29 #include <boost/shared_ptr.hpp> // for shared_ptr
30 #include <deque> // for deque
31 #include <map> // for map, map<>::value_compare
32 #include <stack> // for stack
33 #include <string> // for string
34 
35 namespace ai { class ai_composite; } // lines 45-45
36 namespace ai { class ai_context; } // lines 42-42
37 namespace ai { class component; } // lines 43-43
38 namespace ai { class default_ai_context; } // lines 41-41
39 namespace ai { class readonly_context; } // lines 39-39
40 namespace ai { class readwrite_context; } // lines 40-40
41 namespace ai { class side_context; } // lines 38-38
42 namespace events { class generic_event; }
43 namespace events { class observer; }
44 
45 
46 namespace ai {
47 
49 
50 /**
51  * Base class that holds the AI and current AI parameters.
52  * It is an implementation detail.
53  * @todo 1.9 move it out of public view
54  */
55 class holder{
56 public:
57  holder(side_number side, const config &cfg);
58 
59  virtual ~holder();
60 
62 
63  const std::string describe_ai();
64 
65  config to_config() const;
66 
67  void modify_ai(const config& cfg);
68  void modify_side_ai_config(config cfg);
69 
70 
72 
73 
75 
76 
77  const std::string get_ai_identifier() const;
78 
79  component* get_component(component *root, const std::string &path); // Ai debug method
80 
81 private:
82  void init( side_number side );
83 
84 
85  composite_ai_ptr ai_;
92 };
93 
94 /**
95  * AI Command History Item. It is an implementation detail
96  */
98 public:
99 
101  : number_(number), command_(command)
102  {}
103 
104  int get_number() const { return number_; }
105 
106  const std::string& get_command() const { return command_; }
107 
108 private:
109  int number_;
111 
112 };
113 
114 /**
115  * Class that manages AIs for all sides and manages AI redeployment.
116  * This class is responsible for managing the AI lifecycle
117  * It can be accessed like this: ai::manager::foo(...);
118  */
119 class manager
120 {
121 public:
122 
123  // =======================================================================
124  // CONSTANTS
125  // =======================================================================
126 
127  static const size_t MAX_HISTORY_SIZE = 200;
128 
134  static const std::string AI_TYPE_AI2;
136 
137 
138  // =======================================================================
139  // LIFECYCLE
140  // =======================================================================
141 
142  /**
143  * Sets AI information.
144  * @param info ai_information to be set.
145  */
146  static void set_ai_info(const game_info& info);
147 
148 
149  /**
150  * Clears AI information.
151  * Should be called in playsingle_controller 's destructor.
152  */
153  static void clear_ai_info();
154 
155 
156  /**
157  * Adds observer of game events.
158  * Should be called in playsingle_controller 's constructor.
159  */
160  static void add_observer( events::observer* event_observer);
161 
162 
163  /**
164  * Removes an observer of game events.
165  * Should be called in playsingle_controller 's destructor.
166  */
167  static void remove_observer( events::observer* event_observer );
168 
169 
170  /**
171  * Adds observer of game events except ai_user_interact event and ai_sync_network event
172  */
173  static void add_gamestate_observer( events::observer* event_observer);
174 
175 
176  /**
177  * Removes an observer of game events except ai_user_interact event and ai_sync_network event
178  */
179  static void remove_gamestate_observer( events::observer* event_observer );
180 
181 
182  /**
183  * Notifies all observers of 'ai_user_interact' event.
184  * Function which should be called frequently to allow the user to interact
185  * with the interface. This function will make sure that interaction
186  * doesn't occur too often, so there is no problem with calling it very
187  * regularly.
188  */
189  static void raise_user_interact();
190 
191  /**
192  * Notifies all observers of 'ai_sync_network' event.
193  * Basically a request from the AI to sync the network.
194  */
195  static void raise_sync_network();
196 
197 
198  /**
199  * Notifies all observers of 'ai_gamestate_changed' event.
200  */
201  static void raise_gamestate_changed();
202 
203 
204  /**
205  * Notifies all observers of 'ai_tod_changed' event.
206  */
207  static void raise_tod_changed();
208 
209 
210  /**
211  * Notifies all observers of 'ai_recruit_list_changed' event.
212  */
213  static void raise_recruit_list_changed();
214 
215 
216  /**
217  * Notifies all observers of 'ai_turn_started' event.
218  */
219  static void raise_turn_started();
220 
221 
222  /**
223  * Notifies all observers of 'ai_map_changed' event.
224  */
225  static void raise_map_changed();
226 
227 
228  /**
229  * Adds an observer of 'ai_map_changed' event.
230  */
231  static void add_map_changed_observer( events::observer* event_observer );
232 
233 
234  /**
235  * Adds an observer of 'ai_recruit_list_changed' event.
236  */
237  static void add_recruit_list_changed_observer( events::observer* event_observer );
238 
239 
240  /**
241  * Adds an observer of 'ai_turn_started' event.
242  */
243  static void add_turn_started_observer( events::observer* event_observer );
244 
245 
246  /**
247  * Adds an observer of 'ai_tod_changed' event.
248  */
249  static void add_tod_changed_observer( events::observer* event_observer );
250 
251 
252  /**
253  * Deletes an observer of 'ai_map_changed' event.
254  */
255  static void remove_map_changed_observer( events::observer* event_observer );
256 
257 
258 
259  /**
260  * Deletes an observer of 'ai_recruit_list_changed' event.
261  */
262  static void remove_recruit_list_changed_observer( events::observer* event_observer );
263 
264 
265  /**
266  * Deletes an observer of 'ai_turn_started' event.
267  */
268  static void remove_turn_started_observer( events::observer* event_observer );
269 
270 
271  /**
272  * Deletes an observer of 'ai_tod_changed' event.
273  */
274  static void remove_tod_changed_observer( events::observer* event_observer );
275 
276 
277 private:
278 
279  manager();
280 
281 
282 public:
283 
284  // =======================================================================
285  // EVALUATION
286  // =======================================================================
287 
288  /**
289  * Evaluates a string command using command AI.
290  * @note Running this command may invalidate references previously returned
291  * by manager. Will intercept those commands which start with '!'
292  * and '?', and will try to evaluate them as internal commands.
293  * @param side side number (1-based).
294  * @param str string to evaluate.
295  * @return string result of evaluation.
296  */
297  static const std::string evaluate_command( side_number side, const std::string& str );
298 
299 
300  // =======================================================================
301  // ADD, CREATE AIs, OR LIST AI TYPES
302  // =======================================================================
303 
304  /**
305  * Adds active AI for specified @a side from @a file.
306  * @note Running this command may invalidate references previously returned
307  * by manager. AI is not initialized at this point.
308  * @param side side number (1-based, as in game_info).
309  * @param file file name, follows the usual WML convention.
310  * @param replace should new ai replace the current ai or 'be placed on top of it'.
311  * @return true if successful.
312  */
313  static bool add_ai_for_side_from_file( side_number side, const std::string& file, bool replace = true );
314 
315 
316  /**
317  * Adds active AI for specified @a side from @a cfg.
318  * @note Running this command may invalidate references previously returned
319  * by manager. AI is not initialized at this point.
320  * @param side side number (1-based, as in game_info).
321  * @param cfg the config from which all ai parameters are to be read.
322  * @param replace should new ai replace the current ai or 'be placed on top of it'.
323  * @return true if successful.
324  */
325  static bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace = true);
326 
327 
328  /**
329  * Adds active AI for specified @a side from parameters.
330  * @note Running this command may invalidate references previously returned
331  * by manager. AI is not initialized at this point.
332  * @param side side number (1-based, as in game_info).
333  * @param ai_algorithm_type type of AI algorithm to create.
334  * @param replace should new ai replace the current ai or 'be placed on top of it'.
335  * @return true if successful.
336  */
337  static bool add_ai_for_side( side_number side, const std::string& ai_algorithm_type, bool replace = true);
338 
339 
340  // =======================================================================
341  // REMOVE
342  // =======================================================================
343 
344  /**
345  * Removes top-level AI from @a side.
346  * @note Running this command may invalidate references previously returned
347  * by manager.
348  * @param side side number (1-based, as in game_info).
349  */
350  static void remove_ai_for_side( side_number side );
351 
352 
353  /**
354  * Removes all AIs from @a side.
355  * @note Running this command may invalidate references previously returned
356  * by manager.
357  * @param side side number (1-based, as in game_info).
358  */
359  static void remove_all_ais_for_side( side_number side );
360 
361 
362  /**
363  * Clears all the AIs.
364  * @note Running this command may invalidate references previously returned
365  * by manager. For example, this is called from the destructor of
366  * playsingle_controller. It is necessary to do this if any of the
367  * info structures used by the AI goes out of scope.
368  */
369  static void clear_ais();
370 
371  // =======================================================================
372  // GET active AI parameters
373  // =======================================================================
374 
375 
376  /**
377  * Gets AI info for active AI of the given @a side.
378  * @param side side number (1-based).
379  * @return a reference to active AI info.
380  */
382 
383 
384  /**
385  * Gets AI Overview for active AI of the given @a side
386  * @param side side number (1-based)
387  * @return an ai overview
388  */
390 
391 
392  /**
393  * Gets AI Structure for active AI of the given @a side
394  * @param side side number (1-based)
395  * @return an ai structure
396  */
398 
399  /**
400  * Gets AI algorithm identifier for active AI of the given @a side.
401  * @param side side number (1-based).
402  * @return ai identifier for the active AI
403  */
405 
406  /**
407  * Gets the active AI holder for debug purposes.
408  * Will only work in debug mode, otherwise returns a reference to an empty holder
409  * @param side side number(1-based)
410  * @return debug ? active holder : empty holder
411  */
413 
414  /**
415  * Gets AI config for active AI of the given @a side.
416  * @param side side number (1-based).
417  * @return a config object for the active AI
418  */
419  static config to_config( side_number side );
420 
421 
422  /**
423  * Gets global AI-game info
424  * @return a reference to the AI-game info.
425  */
426  static game_info& get_ai_info();
427 
428 
429  // =======================================================================
430  // SET active AI parameters
431  // =======================================================================
432 
433 
434  /**
435  * Modifies AI parameters for active AI of the given @a side.
436  * This function is provided for backward-compatibility with [modify_side][ai]...[/ai][/modify_side]
437  * It can only add new facets to aspects
438  * @param side side_number (1-based, as in game_info).
439  * @param ai_parameters AI parameters to be modified.
440  */
441  static void modify_active_ai_config_old_for_side ( side_number side, const config::const_child_itors &ai_parameters );
442 
443 
444 
445  /**
446  * Modifies AI parameters for active AI of the given @a side.
447  * This function is a backend for [modify_ai] tag
448  * @param side side_number (1-based, as in game_info).
449  * @param cfg - content of [modify_ai] tag
450  */
451 
452  static void modify_active_ai_for_side( ai::side_number side, const config &cfg );
453 
454  // =======================================================================
455  // PROXY
456  // =======================================================================
457 
458  /**
459  * Plays a turn for the specified side using its active AI.
460  * @param side side number (1-based, as in game_info).
461  */
462  static void play_turn(side_number side);
463 
464 
465 private:
466 
467  typedef std::map< side_number, std::stack< holder > > AI_map_of_stacks;
468  static AI_map_of_stacks ai_map_;
469  static std::deque< command_history_item > history_;
472 
480  static int last_interact_;
481  static int num_interact_;
482 
483 
484 
485  // =======================================================================
486  // EVALUATION
487  // =======================================================================
488 
489  /**
490  * Evaluates an internal manager command.
491  * @param side side number (1-based).
492  * @param str string to evaluate.
493  * @return string result of evaluation.
494  * @todo 1.9 rewrite this function to use a fai or lua parser.
495  */
496  static const std::string internal_evaluate_command( side_number side, const std::string& str );
497 
498  /**
499  * Determines if the command should be intercepted and evaluated as internal command.
500  * @param str command string to check.
501  * @return true if the command should be intercepted and evaluated.
502  */
503  static bool should_intercept( const std::string& str );
504 
505  // =======================================================================
506  // AI STACKS
507  // =======================================================================
508 
509 
510  /**
511  * Gets the AI stack for the specified side, create it if it doesn't exist.
512  */
513  static std::stack< holder >& get_or_create_ai_stack_for_side(side_number side);
514 
515  // =======================================================================
516  // AI HOLDERS
517  // =======================================================================
518 
519 
520  /**
521  * Gets active holder for specified @a side.
522  */
524 
525  // =======================================================================
526  // AI POINTERS
527  // =======================================================================
528 
529  /**
530  * Gets active AI for specified side.
531  * @note Running this command may invalidate references previously returned
532  * by manager.
533  * @param side side number (1-based, as in game_info).
534  * @return a reference to the active AI.
535  * @note This reference may become invalid after specific manager operations.
536  */
538 
539 
540 };
541 
542 } //end of namespace ai
543 
544 #endif
static void add_observer(events::observer *event_observer)
Adds observer of game events.
Definition: manager.cpp:355
static const std::string AI_TYPE_DFOOL_AI
Definition: manager.hpp:133
static void raise_gamestate_changed()
Notifies all observers of 'ai_gamestate_changed' event.
Definition: manager.cpp:454
static void raise_map_changed()
Notifies all observers of 'ai_map_changed' event.
Definition: manager.cpp:474
readonly_context * readonly_context_
Definition: manager.hpp:87
logger & info()
Definition: log.cpp:91
static game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
Definition: manager.cpp:765
config cfg_
Definition: manager.hpp:91
static void add_turn_started_observer(events::observer *event_observer)
Adds an observer of 'ai_turn_started' event.
Definition: manager.cpp:408
holder(side_number side, const config &cfg)
Definition: manager.cpp:79
const std::string get_ai_identifier() const
Definition: manager.cpp:297
static events::generic_event gamestate_changed_
Definition: manager.hpp:478
Class that manages AIs for all sides and manages AI redeployment.
Definition: manager.hpp:119
config to_config() const
Definition: manager.cpp:215
void modify_side_ai_config(config cfg)
Definition: manager.cpp:154
const std::string number
template to number regex
static const std::string internal_evaluate_command(side_number side, const std::string &str)
Evaluates an internal manager command.
Definition: manager.cpp:526
Definitions for the interface to Wesnoth Markup Language (WML).
std::pair< const_child_iterator, const_child_iterator > const_child_itors
Definition: config.hpp:214
static void add_tod_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_tod_changed' event.
Definition: manager.cpp:385
command_history_item(int number, const std::string &command)
Definition: manager.hpp:100
composite_ai_ptr ai_
Definition: manager.hpp:85
static AI_map_of_stacks ai_map_
Definition: manager.hpp:468
const std::string get_ai_overview()
Definition: manager.cpp:253
void init(side_number side)
Definition: manager.cpp:86
static bool should_intercept(const std::string &str)
Determines if the command should be intercepted and evaluated as internal command.
Definition: manager.cpp:504
static std::stack< holder > & get_or_create_ai_stack_for_side(side_number side)
Gets the AI stack for the specified side, create it if it doesn't exist.
Definition: manager.cpp:807
static bool add_ai_for_side_from_file(side_number side, const std::string &file, bool replace=true)
Adds active AI for specified side from file.
Definition: manager.cpp:640
static void clear_ais()
Clears all the AIs.
Definition: manager.cpp:705
static void raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' event.
Definition: manager.cpp:469
const std::string get_ai_structure()
Definition: manager.cpp:288
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:57
static void remove_gamestate_observer(events::observer *event_observer)
Removes an observer of game events except ai_user_interact event and ai_sync_network event...
Definition: manager.cpp:378
const std::string & get_command() const
Definition: manager.hpp:106
GLsizei const char ** path
Definition: glew.h:4654
static std::deque< command_history_item > history_
Definition: manager.hpp:469
component * get_component(component *root, const std::string &path)
Definition: manager.cpp:302
static void remove_turn_started_observer(events::observer *event_observer)
Deletes an observer of 'ai_turn_started' event.
Definition: manager.cpp:426
static std::string get_active_ai_overview_for_side(side_number side)
Gets AI Overview for active AI of the given side.
Definition: manager.cpp:732
static void set_ai_info(const game_info &info)
Sets AI information.
Definition: manager.cpp:339
static events::generic_event user_interact_
Definition: manager.hpp:475
static bool add_ai_for_side(side_number side, const std::string &ai_algorithm_type, bool replace=true)
Adds active AI for specified side from parameters.
Definition: manager.cpp:667
static config to_config(side_number side)
Gets AI config for active AI of the given side.
Definition: manager.cpp:759
static const std::string AI_TYPE_AI2
Definition: manager.hpp:134
side_context * side_context_
Definition: manager.hpp:86
int get_number() const
Definition: manager.hpp:104
static void play_turn(side_number side)
Plays a turn for the specified side using its active AI.
Definition: manager.cpp:781
static void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
Definition: manager.cpp:722
void modify_ai(const config &cfg)
Definition: manager.cpp:180
static void remove_all_ais_for_side(side_number side)
Removes all AIs from side.
Definition: manager.cpp:694
static const std::string AI_TYPE_DEFAULT
Definition: manager.hpp:135
virtual ~holder()
Definition: manager.cpp:129
static const std::string AI_TYPE_IDLE_AI
Definition: manager.hpp:131
static void clear_ai_info()
Clears AI information.
Definition: manager.cpp:349
static void remove_ai_for_side(side_number side)
Removes top-level AI from side.
Definition: manager.cpp:685
boost::shared_ptr< ai_composite > composite_ai_ptr
Definition: manager.hpp:48
static const std::string evaluate_command(side_number side, const std::string &str)
Evaluates a string command using command AI.
Definition: manager.cpp:483
static events::generic_event sync_network_
Definition: manager.hpp:476
static void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
Definition: manager.cpp:431
static const std::string AI_TYPE_COMPOSITE_AI
Definition: manager.hpp:129
Game information for the AI.
static std::string get_active_ai_identifier_for_side(side_number side)
Gets AI algorithm identifier for active AI of the given side.
Definition: manager.cpp:744
static events::generic_event map_changed_
Definition: manager.hpp:473
static void add_recruit_list_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_recruit_list_changed' event.
Definition: manager.cpp:402
static void remove_tod_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_tod_changed' event.
Definition: manager.cpp:390
static game_info * ai_info_
Definition: manager.hpp:471
static events::generic_event turn_started_
Definition: manager.hpp:479
static long history_item_counter_
Definition: manager.hpp:470
default_ai_context * default_ai_context_
Definition: manager.hpp:89
static const size_t MAX_HISTORY_SIZE
Definition: manager.hpp:127
static bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
Definition: manager.cpp:651
std::string observer
Definition: game_config.cpp:84
static std::string get_active_ai_structure_for_side(side_number side)
Gets AI Structure for active AI of the given side.
Definition: manager.cpp:738
static events::generic_event tod_changed_
Definition: manager.hpp:477
readwrite_context * readwrite_context_
Definition: manager.hpp:88
std::map< side_number, std::stack< holder > > AI_map_of_stacks
Definition: manager.hpp:467
Handling of system events.
Definition: manager.hpp:42
std::string replace(std::string str, const std::string &src, const std::string &dst)
Replace all instances of src in str with dst.
const std::string describe_ai()
Definition: manager.cpp:241
static void remove_observer(events::observer *event_observer)
Removes an observer of game events.
Definition: manager.cpp:363
static const std::string AI_TYPE_FORMULA_AI
Definition: manager.hpp:132
ai_composite & get_ai_ref()
Definition: manager.cpp:143
static const std::string AI_TYPE_SAMPLE_AI
Definition: manager.hpp:130
static game_info & get_ai_info()
Gets global AI-game info.
Definition: manager.cpp:771
side_number side_
Definition: manager.hpp:90
static void add_gamestate_observer(events::observer *event_observer)
Adds observer of game events except ai_user_interact event and ai_sync_network event.
Definition: manager.cpp:371
static int num_interact_
Definition: manager.hpp:481
static void raise_sync_network()
Notifies all observers of 'ai_sync_network' event.
Definition: manager.cpp:449
static ai_composite & get_active_ai_for_side(side_number side)
Gets active AI for specified side.
Definition: manager.cpp:837
int side_number
Definition: game_info.hpp:44
static void raise_tod_changed()
Notifies all observers of 'ai_tod_changed' event.
Definition: manager.cpp:459
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
AI Command History Item.
Definition: manager.hpp:97
static ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
Definition: manager.cpp:749
static int last_interact_
Definition: manager.hpp:480
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static void remove_recruit_list_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_recruit_list_changed' event.
Definition: manager.cpp:414
static events::generic_event recruit_list_changed_
Definition: manager.hpp:474
static void raise_turn_started()
Notifies all observers of 'ai_turn_started' event.
Definition: manager.cpp:464
Base class that holds the AI and current AI parameters.
Definition: manager.hpp:55
static holder & get_active_ai_holder_for_side(side_number side)
Gets active holder for specified side.
Definition: manager.cpp:819
static void add_map_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_map_changed' event.
Definition: manager.cpp:396
static void modify_active_ai_config_old_for_side(side_number side, const config::const_child_itors &ai_parameters)
Modifies AI parameters for active AI of the given side.
Definition: manager.cpp:714
static void remove_map_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_map_changed' event.
Definition: manager.cpp:420