The Battle for Wesnoth  1.19.0-dev
ai.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
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  * Composite AI with turn sequence which is a vector of stages
18  * @file
19  */
20 
21 #include "ai/composite/ai.hpp"
22 #include "ai/composite/aspect.hpp"
23 #include "ai/composite/engine.hpp"
24 #include "ai/composite/goal.hpp"
26 #include "ai/composite/stage.hpp"
27 #include "ai/configuration.hpp"
28 #include "actions/attack.hpp"
29 #include "log.hpp"
30 
31 #include <functional>
32 
33 namespace ai {
34 
35 static lg::log_domain log_ai_composite("ai/composite");
36 #define DBG_AI_COMPOSITE LOG_STREAM(debug, log_ai_composite)
37 #define LOG_AI_COMPOSITE LOG_STREAM(info, log_ai_composite)
38 #define ERR_AI_COMPOSITE LOG_STREAM(err, log_ai_composite)
39 
40 // =======================================================================
41 // COMPOSITE AI
42 // =======================================================================
43 std::string ai_composite::describe_self() const
44 {
45  return "[composite_ai]";
46 }
47 
49  : cfg_(cfg),stages_(),recursion_counter_(context.get_recursion_count())
50 {
52 }
53 
55 {
56  LOG_AI_COMPOSITE << "side "<< get_side() << " : "<<" created AI with id=["<<
57  cfg_["id"]<<"]";
58 
59  // init the composite ai stages
60  for (const config &cfg_element : cfg_.child_range("stage")) {
61  add_stage(cfg_element);
62  }
63 
64  config cfg;
65  cfg["engine"] = "fai";
66  engine_ptr e_ptr = get_engine_by_cfg(cfg);
67  if (e_ptr) {
68  e_ptr->set_ai_context(this);
69  }
70 
71  std::function<void(std::vector<engine_ptr>&, const config&)> factory_engines =
72  std::bind(&ai::ai_composite::create_engine, *this, std::placeholders::_1, std::placeholders::_2);
73 
74  std::function<void(std::vector<goal_ptr>&, const config&)> factory_goals =
75  std::bind(&ai::ai_composite::create_goal, *this, std::placeholders::_1, std::placeholders::_2);
76 
77  std::function<void(std::vector<stage_ptr>&, const config&)> factory_stages =
78  std::bind(&ai::ai_composite::create_stage, *this, std::placeholders::_1, std::placeholders::_2);
79 
80  std::function<void(std::map<std::string,aspect_ptr>&, const config&, std::string)> factory_aspects =
81  std::bind(&ai::ai_composite::replace_aspect,*this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
82 
83  register_vector_property(property_handlers(),"engine",get_engines(), factory_engines);
84  register_vector_property(property_handlers(),"goal",get_goals(), factory_goals);
85  register_vector_property(property_handlers(),"stage",stages_, factory_stages);
86  register_aspect_property(property_handlers(),"aspect",get_aspects(), factory_aspects);
87 
88 }
89 
90 void ai_composite::create_stage(std::vector<stage_ptr> &stages, const config &cfg)
91 {
92  engine::parse_stage_from_config(*this,cfg,std::back_inserter(stages));
93 }
94 
95 void ai_composite::create_goal(std::vector<goal_ptr> &goals, const config &cfg)
96 {
97  engine::parse_goal_from_config(*this,cfg,std::back_inserter(goals));
98 }
99 
100 void ai_composite::create_engine(std::vector<engine_ptr> &engines, const config &cfg)
101 {
102  engine::parse_engine_from_config(*this,cfg,std::back_inserter(engines));
103 }
104 
105 void ai_composite::replace_aspect(std::map<std::string,aspect_ptr> &aspects, const config &cfg, std::string id)
106 {
107  std::vector<aspect_ptr> temp_aspects;
108  engine::parse_aspect_from_config(*this,cfg,id,std::back_inserter(temp_aspects));
109  aspects[id] = temp_aspects.back();
110 }
111 
113 {
114 }
115 
117 {
118  std::vector< stage_ptr > stages;
119  create_stage(stages,cfg);
120  int j=0;
121  for (stage_ptr b : stages) {
122  stages_.push_back(b);
123  j++;
124  }
125  return (j>0);
126 }
127 
129 {
130  std::vector< goal_ptr > goals;
131  create_goal(goals,cfg);
132  int j=0;
133  for (goal_ptr b : goals) {
134  get_goals().push_back(b);
135  j++;
136  }
137  return (j>0);
138 }
139 
141  for (stage_ptr &s : stages_) {
142  s->play_stage();
143  }
144 }
145 
146 std::string ai_composite::get_id() const
147 {
148  return cfg_["id"];
149 }
150 
151 
152 std::string ai_composite::get_name() const
153 {
154  return cfg_["name"];
155 }
156 
157 std::string ai_composite::get_engine() const
158 {
159  return cfg_["engine"];
160 }
161 
162 std::string ai_composite::evaluate(const std::string& str)
163 {
164  config cfg;
165  cfg["engine"] = "fai";
166  engine_ptr e_ptr = get_engine_by_cfg(cfg);
167  if (!e_ptr) {
168  // This should be unreachable, but not entirely sure...
169  return "engine not found for evaluate command";
170  }
171  return e_ptr->evaluate(str);
172 }
173 
175 {
180  unit_stats_cache().clear();
181 }
182 
184 {
185  return recursion_counter_.get_count();
186 }
187 
189 {
190  set_side(side);
191 }
192 
194 {
195  return *this;
196 }
197 
199 {
200  config cfg;
201 
202  //serialize the composite ai stages
203  for (const stage_ptr &s : stages_) {
204  cfg.add_child("stage",s->to_config());
205  }
206 
207  return cfg;
208 }
209 
211 {
212  config temp_cfg, parsed_cfg;
213  temp_cfg.add_child("ai", cfg);
214  configuration::parse_side_config(ctx.get_side(), temp_cfg, parsed_cfg);
215  return parsed_cfg;
216 }
217 
218 } //end of namespace ai
Various functions that implement attacks and attack calculations.
void replace_aspect(std::map< std::string, aspect_ptr > &aspects, const config &cfg, std::string id)
Definition: ai.cpp:105
virtual void new_turn()
On new turn.
Definition: ai.cpp:174
void create_goal(std::vector< goal_ptr > &goals, const config &cfg)
Definition: ai.cpp:95
virtual bool add_goal(const config &cfg)
Definition: ai.cpp:128
int get_recursion_count() const
Get the value of the recursion counter.
Definition: ai.cpp:183
void create_stage(std::vector< stage_ptr > &stages, const config &cfg)
Definition: ai.cpp:90
void switch_side(side_number side)
Definition: ai.cpp:188
virtual std::string get_id() const
Definition: ai.cpp:146
std::vector< stage_ptr > stages_
Stages of the composite AI.
Definition: ai.hpp:103
static config preparse_cfg(ai_context &ctx, const config &cfg)
Definition: ai.cpp:210
virtual std::string get_name() const
Definition: ai.cpp:152
virtual ai_context & get_ai_context()
unwrap
Definition: ai.cpp:193
recursion_counter recursion_counter_
Recursion counter.
Definition: ai.hpp:108
virtual std::string evaluate(const std::string &str)
Evaluate command (using fai)
Definition: ai.cpp:162
const config & cfg_
Config of the AI.
Definition: ai.hpp:98
void on_create()
Definition: ai.cpp:54
virtual ~ai_composite()
Destructor.
Definition: ai.cpp:112
void create_engine(std::vector< engine_ptr > &engines, const config &cfg)
Definition: ai.cpp:100
virtual bool add_stage(const config &cfg)
Definition: ai.cpp:116
ai_composite(default_ai_context &context, const config &cfg)
Constructor.
Definition: ai.cpp:48
virtual config to_config() const
serialize
Definition: ai.cpp:198
void play_turn()
Play the turn.
Definition: ai.cpp:140
std::string describe_self() const
Definition: ai.cpp:43
virtual std::string get_engine() const
Definition: ai.cpp:157
property_handler_map & property_handlers()
Definition: component.cpp:116
static bool parse_side_config(side_number side, const config &original_cfg, config &cfg)
virtual void clear_additional_targets() const
Definition: contexts.hpp:177
void init_default_ai_context_proxy(default_ai_context &target)
Definition: contexts.cpp:57
static void parse_goal_from_config(readonly_context &context, const config &cfg, std::back_insert_iterator< std::vector< goal_ptr >> b)
Definition: engine.cpp:79
static void parse_aspect_from_config(readonly_context &context, const config &cfg, const std::string &id, std::back_insert_iterator< std::vector< aspect_ptr >> b)
Definition: engine.cpp:52
static void parse_stage_from_config(ai_context &context, const config &cfg, std::back_insert_iterator< std::vector< stage_ptr >> b)
Definition: engine.cpp:88
static void parse_engine_from_config(readonly_context &context, const config &cfg, std::back_insert_iterator< std::vector< engine_ptr >> b)
Definition: engine.cpp:70
virtual void invalidate_keeps_cache() const override
Definition: contexts.hpp:806
virtual const aspect_map & get_aspects() const override
Definition: contexts.hpp:556
virtual void recalculate_move_maps() const override
Definition: contexts.hpp:826
virtual engine_ptr get_engine_by_cfg(const config &cfg) override
get engine by cfg, creating it if it is not created yet but known
Definition: contexts.hpp:616
virtual const std::vector< goal_ptr > & get_goals() const override
Definition: contexts.hpp:636
virtual void invalidate_defensive_position_cache() const override
Definition: contexts.hpp:796
virtual const std::vector< engine_ptr > & get_engines() const override
Definition: contexts.hpp:621
virtual unit_stats_cache_t & unit_stats_cache() const override
Definition: contexts.hpp:866
int get_count() const
Get the current value of the recursion counter.
Definition: contexts.hpp:66
virtual void set_side(side_number side) override
Set the side number.
Definition: contexts.hpp:401
virtual side_number get_side() const override
Get the side number.
Definition: contexts.hpp:396
virtual side_number get_side() const =0
Get the side number.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
child_itors child_range(config_key_type key)
Definition: config.cpp:273
config & add_child(config_key_type key)
Definition: config.cpp:441
#define LOG_AI_COMPOSITE
Definition: ai.cpp:37
Composite AI with turn sequence which is a vector of stages.
Managing the AIs configuration - headers.
AI Support engine - creating specific ai components from config.
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:207
Standard logging facilities (interface).
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:59
std::shared_ptr< engine > engine_ptr
Definition: game_info.hpp:99
static void register_aspect_property(property_handler_map &property_handlers, const std::string &property, std::map< std::string, std::shared_ptr< X >> &aspects, std::function< void(std::map< std::string, std::shared_ptr< X >> &, const config &, std::string)> construction_factory)
static lg::log_domain log_ai_composite("ai/composite")
std::shared_ptr< goal > goal_ptr
Definition: game_info.hpp:100
std::shared_ptr< stage > stage_ptr
Definition: game_info.hpp:102
int side_number
Definition: game_info.hpp:40
static void register_vector_property(property_handler_map &property_handlers, const std::string &property, std::vector< std::shared_ptr< X >> &values, std::function< void(std::vector< std::shared_ptr< X >> &, const config &)> construction_factory)
Composite AI component.
Composite AI stages.
static map_location::DIRECTION s
#define b