The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
manager.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Yurii Chernyi <terraninfo@terraninfo.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16/**
17 * @file
18 * Managing the AIs lifecycle - headers
19 * TODO: Refactor history handling and internal commands.
20 * TODO: AI Interface command to clear the history.
21 */
22
23#pragma once
24
25#include "ai/game_info.hpp" // for side_number, ai_ptr
26#include "config.hpp" // for config, etc
27#include "generic_event.hpp" // for generic_event, etc
28
29#include <deque> // for deque
30#include <map> // for map, map<>::value_compare
31#include <stack> // for stack
32#include <string> // for string
33
34class game_launcher;
35namespace ai { class unit_advancements_aspect; } // lines 45-45
36namespace ai { class ai_composite; } // lines 45-45
37namespace ai { class component; } // lines 43-43
38namespace ai { class default_ai_context; } // lines 41-41
39namespace ai { class readonly_context; } // lines 39-39
40namespace ai { class readwrite_context; } // lines 40-40
41namespace ai { class side_context; } // lines 38-38
42
43namespace ai
44{
45
46/**
47 * Base class that holds the AI and current AI parameters.
48 * It is an implementation detail.
49 */
50class holder{
51public:
52 holder(side_number side, const config &cfg);
53
54 virtual ~holder();
55
57
58 std::string describe_ai() const;
59
60 config to_config() const;
61
62 void modify_ai(const config& cfg);
63 void micro_ai(const config& cfg);
64
65 void append_ai(const config& cfg);
66
67 std::string get_ai_overview();
68
69 std::string get_ai_structure();
70
71 std::string get_ai_identifier() const;
72
73 component* get_component(component *root, const std::string &path); // Ai debug method
74
75private:
76 void init( side_number side );
77
79 std::unique_ptr<side_context> side_context_;
80 std::unique_ptr<readonly_context> readonly_context_;
81 std::unique_ptr<readwrite_context> readwrite_context_;
82 std::unique_ptr<default_ai_context> default_ai_context_;
85};
86
87/**
88 * AI Command History Item. It is an implementation detail. See TODOs above.
89 */
91public:
92
93 command_history_item(int number, const std::string &command)
94 : number_(number), command_(command)
95 {}
96
97 int get_number() const { return number_; }
98
99 const std::string& get_command() const { return command_; }
100
101private:
103 std::string command_;
104};
105
106/**
107 * Class that manages AIs for all sides and manages AI redeployment.
108 * This class is responsible for managing the AI lifecycle.
109 */
111{
112public:
113
114 // =======================================================================
115 // CONSTANTS
116 // =======================================================================
117
118 static const std::size_t MAX_HISTORY_SIZE = 200;
119
120 static const std::string AI_TYPE_COMPOSITE_AI;
121 static const std::string AI_TYPE_SAMPLE_AI;
122 static const std::string AI_TYPE_IDLE_AI;
123 static const std::string AI_TYPE_FORMULA_AI;
124 static const std::string AI_TYPE_DFOOL_AI;
125 static const std::string AI_TYPE_AI2;
126 static const std::string AI_TYPE_DEFAULT;
127
128 // =======================================================================
129 // CONSTRUCTORS AND DESTRUCTORS
130 // =======================================================================
131
132 manager();
133
134 ~manager();
135
136 // =======================================================================
137 // ACCESS TO MANAGER
138 // =======================================================================
139
141 {
142 assert(singleton_ != nullptr);
143 return *singleton_;
144 }
145
146 static bool has_manager()
147 {
148 return singleton_ != nullptr;
149 }
150
151 // =======================================================================
152 // LIFECYCLE
153 // =======================================================================
154
155 /**
156 * Adds observer of game events.
157 * Should be called in playsingle_controller 's constructor.
158 */
159 void add_observer( events::observer* event_observer);
160
161 /**
162 * Removes an observer of game events.
163 * Should be called in playsingle_controller 's destructor.
164 */
165 void remove_observer( events::observer* event_observer );
166
167 /**
168 * Adds observer of game events except ai_user_interact event and ai_sync_network event
169 */
170 void add_gamestate_observer( events::observer* event_observer);
171
172 /**
173 * Removes an observer of game events except ai_user_interact event and ai_sync_network event
174 */
175 void remove_gamestate_observer( events::observer* event_observer );
176
177 /**
178 * Notifies all observers of 'ai_user_interact' event.
179 * Function which should be called frequently to allow the user to interact
180 * with the interface. This function will make sure that interaction
181 * doesn't occur too often, so there is no problem with calling it very
182 * regularly.
183 */
184 void raise_user_interact();
185
186 /**
187 * Notifies all observers of 'ai_sync_network' event.
188 * Basically a request from the AI to sync the network.
189 */
190 void raise_sync_network();
191
192 /**
193 * Notifies all observers of 'ai_gamestate_changed' event.
194 */
196
197 /**
198 * Notifies all observers of 'ai_tod_changed' event.
199 */
200 void raise_tod_changed();
201
202 /**
203 * Notifies all observers of 'ai_recruit_list_changed' event.
204 */
206
207 /**
208 * Notifies all observers of 'ai_turn_started' event.
209 */
210 void raise_turn_started();
211
212 /**
213 * Notifies all observers of 'ai_map_changed' event.
214 */
215 void raise_map_changed();
216
217 /**
218 * Adds an observer of 'ai_map_changed' event.
219 */
220 void add_map_changed_observer( events::observer* event_observer );
221
222 /**
223 * Adds an observer of 'ai_recruit_list_changed' event.
224 */
226
227 /**
228 * Adds an observer of 'ai_turn_started' event.
229 */
230 void add_turn_started_observer( events::observer* event_observer );
231
232 /**
233 * Adds an observer of 'ai_tod_changed' event.
234 */
235 void add_tod_changed_observer( events::observer* event_observer );
236
237 /**
238 * Deletes an observer of 'ai_map_changed' event.
239 */
240 void remove_map_changed_observer( events::observer* event_observer );
241
242
243 /**
244 * Deletes an observer of 'ai_recruit_list_changed' event.
245 */
247
248 /**
249 * Deletes an observer of 'ai_turn_started' event.
250 */
251 void remove_turn_started_observer( events::observer* event_observer );
252
253 /**
254 * Deletes an observer of 'ai_tod_changed' event.
255 */
256 void remove_tod_changed_observer( events::observer* event_observer );
257
258public:
259
260 // =======================================================================
261 // ADD, CREATE AIs, OR LIST AI TYPES
262 // =======================================================================
263
264 /**
265 * Adds active AI for specified @a side from @a file.
266 * @note Running this command may invalidate references previously returned
267 * by manager. AI is not initialized at this point.
268 * @param side side number (1-based, as in game_info).
269 * @param file file name, follows the usual WML convention.
270 * @param replace should new ai replace the current ai or 'be placed on top of it'.
271 * @return true if successful.
272 */
273 bool add_ai_for_side_from_file( side_number side, const std::string& file, bool replace = true );
274
275 /**
276 * Adds active AI for specified @a side from @a cfg.
277 * @note Running this command may invalidate references previously returned
278 * by manager. AI is not initialized at this point.
279 * @param side side number (1-based, as in game_info).
280 * @param cfg the config from which all ai parameters are to be read.
281 * @param replace should new ai replace the current ai or 'be placed on top of it'.
282 * @return true if successful.
283 */
284 bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace = true);
285
286 // =======================================================================
287 // REMOVE
288 // =======================================================================
289
290 /**
291 * Removes top-level AI from @a side.
292 * @note Running this command may invalidate references previously returned
293 * by manager.
294 * @param side side number (1-based, as in game_info).
295 */
296 void remove_ai_for_side( side_number side );
297
298 /**
299 * Removes all AIs from @a side.
300 * @note Running this command may invalidate references previously returned
301 * by manager.
302 * @param side side number (1-based, as in game_info).
303 */
305
306 /**
307 * Clears all the AIs.
308 * @note Running this command may invalidate references previously returned
309 * by manager. For example, this is called from the destructor of
310 * playsingle_controller. It is necessary to do this if any of the
311 * info structures used by the AI goes out of scope.
312 */
313 void clear_ais();
314
315 // =======================================================================
316 // GET active AI parameters
317 // =======================================================================
318
319 /**
320 * Gets AI info for active AI of the given @a side.
321 * @param side side number (1-based).
322 * @return a reference to active AI info.
323 */
325
326 /**
327 * Gets AI Overview for active AI of the given @a side
328 * @param side side number (1-based)
329 * @return an ai overview
330 */
332
333 /**
334 * Gets AI Structure for active AI of the given @a side
335 * @param side side number (1-based)
336 * @return an ai structure
337 */
339
340 /**
341 * Gets AI algorithm identifier for active AI of the given @a side.
342 * @param side side number (1-based).
343 * @return ai identifier for the active AI
344 */
346
347 /**
348 * Gets the active AI holder for debug purposes.
349 * Will only work in debug mode, otherwise returns a reference to an empty holder
350 * @param side side number(1-based)
351 * @return debug ? active holder : empty holder
352 */
354
355 /**
356 * Gets AI config for active AI of the given @a side.
357 * @param side side number (1-based).
358 * @return a config object for the active AI
359 */
361
362 /**
363 * Gets global AI-game info
364 * @return a reference to the AI-game info.
365 */
367
369
370 // =======================================================================
371 // SET active AI parameters
372 // =======================================================================
373
374 /**
375 * Modifies AI parameters for active AI of the given @a side.
376 * This function is a backend for [modify_ai] tag
377 * @param side side_number (1-based, as in game_info).
378 * @param cfg - content of [modify_ai] tag
379 */
380
382
383 /**
384 * Appends AI parameters to active AI of the given @a side.
385 * This function is a backend for [modify_side][ai] tag
386 * @param side side_number (1-based, as in game_info).
387 * @param cfg - content of [modify_side][ai] tag
388 */
389
391
392 // =======================================================================
393 // PROXY
394 // =======================================================================
395
396 /**
397 * Plays a turn for the specified side using its active AI.
398 * @param side side number (1-based, as in game_info).
399 */
400 void play_turn(side_number side);
401
402private:
403
404 typedef std::map< side_number, std::stack< holder >> AI_map_of_stacks;
405
406 std::deque< command_history_item > history_;
409
417 std::chrono::steady_clock::time_point last_interact_;
419
421
423
424 // =======================================================================
425 // AI STACKS
426 // =======================================================================
427
428 /**
429 * Gets the AI stack for the specified side, create it if it doesn't exist.
430 */
431 std::stack< holder >& get_or_create_ai_stack_for_side(side_number side);
432
433 // =======================================================================
434 // AI HOLDERS
435 // =======================================================================
436
437 /**
438 * Gets active holder for specified @a side.
439 */
441
442 // =======================================================================
443 // AI POINTERS
444 // =======================================================================
445
446 /**
447 * Gets active AI for specified side.
448 * @note Running this command may invalidate references previously returned
449 * by manager.
450 * @param side side number (1-based, as in game_info).
451 * @return a reference to the active AI.
452 * @note This reference may become invalid after specific manager operations.
453 */
455
456 friend class ::game_launcher;
457};
458
459} //end of namespace ai
AI Command History Item.
Definition manager.hpp:90
const std::string & get_command() const
Definition manager.hpp:99
command_history_item(int number, const std::string &command)
Definition manager.hpp:93
Base class that holds the AI and current AI parameters.
Definition manager.hpp:50
std::string describe_ai() const
Definition manager.cpp:244
std::string get_ai_structure()
Definition manager.cpp:297
config to_config() const
Definition manager.cpp:221
composite_ai_ptr ai_
Definition manager.hpp:78
std::string get_ai_identifier() const
Definition manager.cpp:305
void micro_ai(const config &cfg)
Definition manager.cpp:147
void modify_ai(const config &cfg)
Definition manager.cpp:160
config cfg_
Definition manager.hpp:84
ai_composite & get_ai_ref()
Definition manager.cpp:137
virtual ~holder()
Definition manager.cpp:128
component * get_component(component *root, const std::string &path)
Definition manager.cpp:310
std::unique_ptr< side_context > side_context_
Definition manager.hpp:79
side_number side_
Definition manager.hpp:83
std::unique_ptr< readwrite_context > readwrite_context_
Definition manager.hpp:81
std::string get_ai_overview()
Definition manager.cpp:253
std::unique_ptr< readonly_context > readonly_context_
Definition manager.hpp:80
void init(side_number side)
Definition manager.cpp:80
void append_ai(const config &cfg)
Definition manager.cpp:189
std::unique_ptr< default_ai_context > default_ai_context_
Definition manager.hpp:82
Class that manages AIs for all sides and manages AI redeployment.
Definition manager.hpp:111
static const std::string AI_TYPE_SAMPLE_AI
Definition manager.hpp:121
events::generic_event map_changed_
Definition manager.hpp:410
static manager & get_singleton()
Definition manager.hpp:140
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:542
void clear_ais()
Clears all the AIs.
Definition manager.cpp:517
std::string get_active_ai_overview_for_side(side_number side)
Gets AI Overview for active AI of the given side.
Definition manager.cpp:532
ai_composite & get_active_ai_for_side(side_number side)
Gets active AI for specified side.
Definition manager.cpp:634
void raise_tod_changed()
Notifies all observers of 'ai_tod_changed' event.
Definition manager.cpp:452
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:482
config to_config(side_number side)
Gets AI config for active AI of the given side.
Definition manager.cpp:557
events::generic_event user_interact_
Definition manager.hpp:412
void remove_all_ais_for_side(side_number side)
Removes all AIs from side.
Definition manager.cpp:507
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:380
void remove_observer(events::observer *event_observer)
Removes an observer of game events.
Definition manager.cpp:367
void raise_turn_started()
Notifies all observers of 'ai_turn_started' event.
Definition manager.cpp:456
static manager * singleton_
Definition manager.hpp:422
static const std::string AI_TYPE_IDLE_AI
Definition manager.hpp:122
static const std::string AI_TYPE_COMPOSITE_AI
Definition manager.hpp:120
static const std::size_t MAX_HISTORY_SIZE
Definition manager.hpp:118
static const std::string AI_TYPE_DFOOL_AI
Definition manager.hpp:124
void raise_gamestate_changed()
Notifies all observers of 'ai_gamestate_changed' event.
Definition manager.cpp:448
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:374
void append_active_ai_for_side(ai::side_number side, const config &cfg)
Appends AI parameters to active AI of the given side.
Definition manager.cpp:527
AI_map_of_stacks ai_map_
Definition manager.hpp:420
std::map< side_number, std::stack< holder > > AI_map_of_stacks
Definition manager.hpp:404
std::string get_active_ai_structure_for_side(side_number side)
Gets AI Structure for active AI of the given side.
Definition manager.cpp:537
events::generic_event sync_network_
Definition manager.hpp:413
void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
Definition manager.cpp:424
static const std::string AI_TYPE_FORMULA_AI
Definition manager.hpp:123
events::generic_event recruit_list_changed_
Definition manager.hpp:411
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:605
holder & get_active_ai_holder_for_side(side_number side)
Gets active holder for specified side.
Definition manager.cpp:617
void add_recruit_list_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_recruit_list_changed' event.
Definition manager.cpp:399
game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
Definition manager.cpp:562
void add_map_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_map_changed' event.
Definition manager.cpp:394
static const std::string AI_TYPE_AI2
Definition manager.hpp:125
void add_turn_started_observer(events::observer *event_observer)
Adds an observer of 'ai_turn_started' event.
Definition manager.cpp:404
static const std::string AI_TYPE_DEFAULT
Definition manager.hpp:126
std::deque< command_history_item > history_
Definition manager.hpp:406
static bool has_manager()
Definition manager.hpp:146
game_info & get_ai_info()
Gets global AI-game info.
Definition manager.cpp:567
game_info ai_info_
Definition manager.hpp:408
events::generic_event gamestate_changed_
Definition manager.hpp:415
const ai::unit_advancements_aspect & get_advancement_aspect_for_side(side_number side)
Definition manager.cpp:572
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:472
events::generic_event turn_started_
Definition manager.hpp:416
void remove_ai_for_side(side_number side)
Removes top-level AI from side.
Definition manager.cpp:499
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:522
int num_interact_
Definition manager.hpp:418
void play_turn(side_number side)
Plays a turn for the specified side using its active AI.
Definition manager.cpp:581
std::chrono::steady_clock::time_point last_interact_
Definition manager.hpp:417
long history_item_counter_
Definition manager.hpp:407
void raise_map_changed()
Notifies all observers of 'ai_map_changed' event.
Definition manager.cpp:464
void raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' event.
Definition manager.cpp:460
void remove_turn_started_observer(events::observer *event_observer)
Deletes an observer of 'ai_turn_started' event.
Definition manager.cpp:419
ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
Definition manager.cpp:547
void raise_sync_network()
Notifies all observers of 'ai_sync_network' event.
Definition manager.cpp:444
events::generic_event tod_changed_
Definition manager.hpp:414
void remove_map_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_map_changed' event.
Definition manager.cpp:414
void add_tod_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_tod_changed' event.
Definition manager.cpp:386
void remove_tod_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_tod_changed' event.
Definition manager.cpp:390
void add_observer(events::observer *event_observer)
Adds observer of game events.
Definition manager.cpp:360
void remove_recruit_list_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_recruit_list_changed' event.
Definition manager.cpp:409
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
Game information for the AI.
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition actions.cpp:59
int side_number
Definition game_info.hpp:40
std::unique_ptr< ai_composite > composite_ai_ptr
Definition game_info.hpp:49