The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ai.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2017 by David White <dave@whitevine.net>
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  * Defines formula ai candidate actions - headers
18  */
19 
20 #include "ai/formula/ai.hpp"
21 
22 #include "ai/formula/callable_objects.hpp" // for unit_callable, etc
23 #include "chat_events.hpp" // for chat_handler, etc
24 #include "display_chat_manager.hpp"
25 #include "formula/function.hpp" // for formula_expression
26 #include "game_board.hpp" // for game_board
27 #include "game_display.hpp" // for game_display
28 #include "log.hpp" // for LOG_STREAM, logger, etc
29 #include "map/map.hpp" // for gamemap
30 #include "pathfind/pathfind.hpp" // for plain_route, etc
31 #include "pathfind/teleport.hpp" // for get_teleport_locations, etc
32 #include "recall_list_manager.hpp" // for recall_list_manager
33 #include "resources.hpp" // for gameboard, teams, units, etc
34 #include "serialization/string_utils.hpp" // for split
35 #include "team.hpp" // for team
36 #include "terrain/filter.hpp" // for terrain_filter
37 #include "time_of_day.hpp" // for time_of_day
38 #include "tod_manager.hpp" // for tod_manager
39 #include "tstring.hpp" // for t_string, operator+
40 #include "units/unit.hpp" // for unit
41 #include "units/formula_manager.hpp" // for unit_formula_manager
42 #include "units/ptr.hpp" // for unit_ptr
43 #include "units/types.hpp"
44 #include "formula/formula.hpp" // for formula_error, formula, etc
45 #include "map/location.hpp" // for map_location, etc
46 #include "ai/actions.hpp" // for recall_result, etc
47 #include "ai/manager.hpp" // for manager
49 #include "ai/composite/stage.hpp" // for stage
50 #include "ai/default/contexts.hpp" // for attack_analysis
51 #include "ai/formula/function_table.hpp" // for ai_function_symbol_table
52 #include "ai/game_info.hpp" // for move_result_ptr, move_map, etc
53 #include "ai/formula/candidates.hpp" // for base_candidate_action, etc
54 
55 #include <cassert> // for assert
56 #include <ctime> // for time
57 #include <map> // for multimap<>::const_iterator, etc
58 #include <sstream> // for operator<<, basic_ostream, etc
59 #include <stack> // for stack
60 #include <vector> // for vector, allocator, etc
61 
62 static lg::log_domain log_formula_ai("ai/engine/fai");
63 #define DBG_AI LOG_STREAM(debug, log_formula_ai)
64 #define LOG_AI LOG_STREAM(info, log_formula_ai)
65 #define WRN_AI LOG_STREAM(warn, log_formula_ai)
66 #define ERR_AI LOG_STREAM(err, log_formula_ai)
67 
68 
69 using namespace wfl;
70 
71 namespace ai {
72 
74 
76 {
77  ca_ptr new_ca;
78  const t_string &name = rc_action["name"];
79  try {
80  const t_string &type = rc_action["type"];
81 
82  if( type == "movement") {
83  new_ca = ca_ptr(new move_candidate_action(name, type, rc_action, &function_table_));
84  } else if( type == "attack") {
85  new_ca = ca_ptr(new attack_candidate_action(name, type, rc_action, &function_table_));
86  } else {
87  ERR_AI << "Unknown candidate action type: " << type << std::endl;
88  }
89  } catch(formula_error& e) {
90  handle_exception(e, "Error while registering candidate action '" + name + "'");
91  }
92  return new_ca;
93 }
94 
97 }
98 
99 
101  :
104  ai_ptr_(nullptr),
105  cfg_(cfg),
106  recursion_counter_(context.get_recursion_count()),
107  keeps_cache_(),
108  attacks_callable(*this, resources::gameboard->units()),
109 // infinite_loop_guardian_(),
110  vars_(),
111  function_table_(*this)
112 {
114  LOG_AI << "creating new formula ai"<< std::endl;
115 }
116 
118 {
119  handle_exception(e, "Error while parsing formula");
120 }
121 
122 void formula_ai::handle_exception(formula_error& e, const std::string& failed_operation) const
123 {
124  LOG_AI << failed_operation << ": " << e.formula << std::endl;
125  display_message(failed_operation + ": " + e.formula);
126  //if line number = 0, don't display info about filename and line number
127  if (e.line != 0) {
128  LOG_AI << e.type << " in " << e.filename << ":" << e.line << std::endl;
129  display_message(e.type + " in " + e.filename + ":" + std::to_string(e.line));
130  } else {
131  LOG_AI << e.type << std::endl;
133  }
134 }
135 
137 {
138  resources::screen->get_chat_manager().add_chat_message(time(nullptr), "wfl", get_side(), msg,
140 
141 }
142 
144  try{
145  return formula::create_optional_formula(formula_string, &function_table_);
146  }
147  catch(formula_error& e) {
148  handle_exception(e);
149  return wfl::formula_ptr();
150  }
151 }
152 
153 
155 {
156  ai_ptr_ = context;
157 }
158 
159 
161 {
162  try{
163 
164  formula f(formula_str, &function_table_);
165 
166  map_formula_callable callable(fake_ptr());
167 
168  //formula_debugger fdb;
169  const variant v = f.evaluate(callable,nullptr);
170 
171  if (ai_ptr_) {
172  variant var = variant(this->fake_ptr()).execute_variant(v);
173 
174  if ( !var.is_empty() ) {
175  return "Made move: " + var.to_debug_string();
176  }
177  }
178 
179  return v.to_debug_string();
180  }
181  catch(formula_error& e) {
182  e.line = 0;
183  handle_exception(e);
184  throw;
185  }
186 }
187 
189 {
190  if (!formula_) {
191  throw formula_error("null formula passed to make_action","","formula",0);
192  }
193  LOG_AI << "do move...\n";
194  const variant var = formula_->evaluate(variables);///@todo 1.9 add formula_debugger
195  variant res;
196 
197  if (ai_ptr_) {
198  res = variant(this->fake_ptr()).execute_variant(var);
199  } else {
200  ERR_AI << "skipped execution of action because ai context is not set correctly" << std::endl;
201  }
202 
203  return res;
204 }
205 
207  const map_location &dst, unit_map::iterator &unit_it,
208  pathfind::teleport_map& allowed_teleports) const
209 {
210  map_location destination = dst;
211 
212  unit_map &units_ = resources::gameboard->units();
214 
215  unit_map::const_iterator dst_un = units_.find(destination);
216 
217  map_location res;
218 
219  if( dst_un != units_.end() ) {
220  //there is unit standing at dst, let's try to find free hex to move to
221  const map_location::DIRECTION preferred = destination.get_relative_dir(src);
222 
223  int best_rating = 100;//smaller is better
224  map_location adj[6];
225  get_adjacent_tiles(destination,adj);
226 
227  for(size_t n = 0; n != 6; ++n) {
228  if(resources::gameboard->map().on_board(adj[n]) == false) {
229  continue;
230  }
231 
232  if(units_.find(adj[n]) != units_.end()) {
233  continue;
234  }
235 
236  static const size_t NDIRECTIONS = map_location::NDIRECTIONS;
237  unsigned int difference = std::abs(int(preferred - n));
238  if(difference > NDIRECTIONS/2) {
239  difference = NDIRECTIONS - difference;
240  }
241 
242  const int rating = difference * 2;
243  if(rating < best_rating || res.valid() == false) {
244  best_rating = rating;
245  res = adj[n];
246  }
247  }
248  }
249 
250  if( res != map_location() ) {
251  destination = res;
252  }
253 
254  pathfind::plain_route route = pathfind::a_star_search(src, destination, 1000.0, calc,
255  resources::gameboard->map().w(), resources::gameboard->map().h(), &allowed_teleports);
256 
257  return route;
258 }
259 
261 {
262  return pathfind::get_teleport_locations(*unit_it, current_team(), true);
263 }
264 
265 void formula_ai::add_formula_function(const std::string& name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector<std::string>& args)
266 {
267  formula_function_ptr fcn(new user_formula_function(name,formula,precondition,args));
268  function_table_.add_function(name, std::move(fcn));
269 }
270 
271 namespace {
272 template<typename Container>
273 variant villages_from_set(const Container& villages,
274  const std::set<map_location>* exclude=nullptr) {
275  std::vector<variant> vars;
276  for(const map_location& loc : villages) {
277  if(exclude && exclude->count(loc)) {
278  continue;
279  }
280  vars.emplace_back(std::make_shared<location_callable>(loc));
281  }
282 
283  return variant(vars);
284 }
285 }
286 
288 {
290 
291  if(key == "aggression")
292  {
293  return variant(get_aggression()*1000,variant::DECIMAL_VARIANT);
294 
295  } else if(key == "attack_depth")
296  {
297  return variant(get_attack_depth());
298 
299  } else if(key == "avoid")
300  {
301  std::set<map_location> av_locs;
302  get_avoid().get_locations(av_locs);
303  return villages_from_set(av_locs);
304 
305  } else if(key == "caution")
306  {
307  return variant(get_caution()*1000,variant::DECIMAL_VARIANT);
308 
309  } else if(key == "grouping")
310  {
311  return variant(get_grouping());
312 
313  } else if(key == "leader_aggression")
314  {
315  return variant(get_leader_aggression()*1000,variant::DECIMAL_VARIANT);
316 
317  } else if(key == "leader_ignores_keep")
318  {
320 
321  } else if(key == "leader_value")
322  {
323  return variant(get_leader_value()*1000,variant::DECIMAL_VARIANT);
324 
325  } else if(key == "passive_leader")
326  {
327  return variant(get_passive_leader());
328 
329  } else if(key == "passive_leader_shares_keep")
330  {
332 
333  } else if(key == "recruitment_pattern")
334  {
335  const std::vector<std::string> &rp = get_recruitment_pattern();
336  std::vector<variant> vars;
337  for(const std::string &i : rp) {
338  vars.emplace_back(i);
339  }
340  return variant(vars);
341 
342  } else if(key == "scout_village_targeting")
343  {
344  return variant(get_scout_village_targeting()*1000,variant::DECIMAL_VARIANT);
345 
346  } else if(key == "support_villages")
347  {
348  return variant(get_support_villages());
349 
350  } else if(key == "village_value")
351  {
352  return variant(get_village_value()*1000,variant::DECIMAL_VARIANT);
353 
354  } else if(key == "villages_per_scout")
355  {
357 
358  } else if(key == "attacks")
359  {
360  return get_attacks_as_variant();
361 
362  } else if(key == "turn")
363  {
364  return variant(resources::tod_manager->turn());
365 
366  } else if(key == "time_of_day")
367  {
368  return variant(resources::tod_manager->get_time_of_day().id);
369 
370  } else if(key == "my_side")
371  {
372  return variant(std::make_shared<team_callable>(resources::gameboard->get_team(get_side())));
373 
374  } else if(key == "my_side_number")
375  {
376  return variant(get_side()-1);
377 
378  } else if(key == "teams")
379  {
380  std::vector<variant> vars;
381  for(std::vector<team>::const_iterator i = resources::gameboard->teams().begin(); i != resources::gameboard->teams().end(); ++i) {
382  vars.emplace_back(std::make_shared<team_callable>(*i));
383  }
384  return variant(vars);
385 
386  } else if(key == "allies")
387  {
388  std::vector<variant> vars;
389  for( size_t i = 0; i < resources::gameboard->teams().size(); ++i) {
390  if ( !current_team().is_enemy( i+1 ) )
391  vars.emplace_back(i);
392  }
393  return variant(vars);
394 
395  } else if(key == "enemies")
396  {
397  std::vector<variant> vars;
398  for( size_t i = 0; i < resources::gameboard->teams().size(); ++i) {
399  if ( current_team().is_enemy( i+1 ) )
400  vars.emplace_back(i);
401  }
402  return variant(vars);
403 
404  } else if(key == "my_recruits")
405  {
406  std::vector<variant> vars;
407 
409 
410  const std::set<std::string>& recruits = current_team().recruits();
411  if(recruits.empty()) {
412  return variant(vars);
413  }
414  for(std::set<std::string>::const_iterator i = recruits.begin(); i != recruits.end(); ++i)
415  {
416  const unit_type *ut = unit_types.find(*i);
417  if (ut)
418  {
419  vars.emplace_back(std::make_shared<unit_type_callable>(*ut));
420  }
421  }
422  return variant(vars);
423 
424  } else if(key == "recruits_of_side")
425  {
426  std::vector<variant> vars;
427  std::vector< std::vector< variant> > tmp;
428 
430 
431  for( size_t i = 0; i<resources::gameboard->teams().size(); ++i)
432  {
433  std::vector<variant> v;
434  tmp.push_back( v );
435 
436  const std::set<std::string>& recruits = resources::gameboard->teams()[i].recruits();
437  if(recruits.empty()) {
438  continue;
439  }
440  for(std::set<std::string>::const_iterator str_it = recruits.begin(); str_it != recruits.end(); ++str_it)
441  {
442  const unit_type *ut = unit_types.find(*str_it);
443  if (ut)
444  {
445  tmp[i].emplace_back(std::make_shared<unit_type_callable>(*ut));
446  }
447  }
448  }
449 
450  for( size_t i = 0; i<tmp.size(); ++i)
451  vars.emplace_back(tmp[i]);
452  return variant(vars);
453 
454  } else if(key == "units")
455  {
456  std::vector<variant> vars;
457  for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
458  vars.emplace_back(std::make_shared<unit_callable>(*i));
459  }
460  return variant(vars);
461 
462  } else if(key == "units_of_side")
463  {
464  std::vector<variant> vars;
465  std::vector< std::vector< variant> > tmp;
466  for( size_t i = 0; i<resources::gameboard->teams().size(); ++i)
467  {
468  std::vector<variant> v;
469  tmp.push_back( v );
470  }
471  for(const unit &u : units) {
472  tmp[u.side() - 1].emplace_back(std::make_shared<unit_callable>(u));
473  }
474  for( size_t i = 0; i<tmp.size(); ++i)
475  vars.emplace_back(tmp[i]);
476  return variant(vars);
477 
478  } else if(key == "my_units")
479  {
480  std::vector<variant> vars;
481  for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
482  if (i->side() == get_side()) {
483  vars.emplace_back(std::make_shared<unit_callable>(*i));
484  }
485  }
486  return variant(vars);
487 
488  } else if(key == "enemy_units")
489  {
490  std::vector<variant> vars;
491  for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
492  if (current_team().is_enemy(i->side())) {
493  if (!i->incapacitated()) {
494  vars.emplace_back(std::make_shared<unit_callable>(*i));
495  }
496  }
497  }
498  return variant(vars);
499 
500  } else if(key == "my_moves")
501  {
502  return variant(std::make_shared<move_map_callable>(get_srcdst(), get_dstsrc(), units));
503 
504  } else if(key == "my_attacks")
505  {
507  } else if(key == "enemy_moves")
508  {
509  return variant(std::make_shared<move_map_callable>(get_enemy_srcdst(), get_enemy_dstsrc(), units));
510 
511  } else if(key == "my_leader")
512  {
514  if(i == units.end()) {
515  return variant();
516  }
517  return variant(std::make_shared<unit_callable>(*i));
518 
519  } else if(key == "recall_list")
520  {
521  std::vector<variant> tmp;
522 
523  for(std::vector<unit_ptr >::const_iterator i = current_team().recall_list().begin(); i != current_team().recall_list().end(); ++i) {
524  tmp.emplace_back(std::make_shared<unit_callable>(**i));
525  }
526 
527  return variant(tmp);
528 
529  } else if(key == "vars")
530  {
531  return variant(vars_.fake_ptr());
532  } else if(key == "keeps")
533  {
534  return get_keeps();
535  } else if(key == "map")
536  {
537  return variant(std::make_shared<gamemap_callable>(*resources::gameboard));
538  } else if(key == "villages")
539  {
540  return villages_from_set(resources::gameboard->map().villages());
541  } else if(key == "villages_of_side")
542  {
543  std::vector<variant> vars;
544  for(size_t i = 0; i<resources::gameboard->teams().size(); ++i)
545  {
546  vars.emplace_back();
547  }
548  for(size_t i = 0; i<vars.size(); ++i)
549  {
550  vars[i] = villages_from_set(resources::gameboard->teams()[i].villages());
551  }
552  return variant(vars);
553 
554  } else if(key == "my_villages")
555  {
556  return villages_from_set(current_team().villages());
557 
558  } else if(key == "enemy_and_unowned_villages")
559  {
560  return villages_from_set(resources::gameboard->map().villages(), &current_team().villages());
561  }
562 
563  return variant();
564 }
565 
567 {
568  add_input(inputs, "aggression");
569  add_input(inputs, "leader_aggression");
570  add_input(inputs, "caution");
571  add_input(inputs, "attacks");
572  add_input(inputs, "my_side");
573  add_input(inputs, "teams");
574  add_input(inputs, "turn");
575  add_input(inputs, "time_of_day");
576  add_input(inputs, "keeps");
577  add_input(inputs, "vars");
578  add_input(inputs, "allies");
579  add_input(inputs, "enemies");
580  add_input(inputs, "map");
581  add_input(inputs, "my_attacks");
582  add_input(inputs, "enemy_moves");
583  add_input(inputs, "my_leader");
584  add_input(inputs, "my_recruits");
585  //add_input(inputs, "recall_list");
586  add_input(inputs, "recruits_of_side");
587  add_input(inputs, "units");
588  add_input(inputs, "units_of_side");
589  add_input(inputs, "my_units");
590  add_input(inputs, "enemy_units");
591  add_input(inputs, "villages");
592  add_input(inputs, "my_villages");
593  add_input(inputs, "villages_of_side");
594  add_input(inputs, "enemy_and_unowned_villages");
595 }
596 
597 void formula_ai::set_value(const std::string& key, const variant& value) {
598  vars_.mutate_value(key, value);
599 }
600 
602 {
603  if(keeps_cache_.is_null()) {
604  std::vector<variant> vars;
605  for(size_t x = 0; x != size_t(resources::gameboard->map().w()); ++x) {
606  for(size_t y = 0; y != size_t(resources::gameboard->map().h()); ++y) {
607  const map_location loc(x,y);
608  if(resources::gameboard->map().is_keep(loc)) {
609  map_location adj[6];
610  get_adjacent_tiles(loc,adj);
611  for(size_t n = 0; n != 6; ++n) {
612  if(resources::gameboard->map().is_castle(adj[n])) {
613  vars.emplace_back(std::make_shared<location_callable>(loc));
614  break;
615  }
616  }
617  }
618  }
619  }
620  keeps_cache_ = variant(vars);
621  }
622 
623  return keeps_cache_;
624 }
625 
627  if (tiles_adjacent(unit_A,unit_B)) {
628  return true;
629  }
630  move_map::const_iterator i;
631  std::pair<move_map::const_iterator,
632  move_map::const_iterator> unit_moves;
633 
634  unit_moves = get_srcdst().equal_range(unit_A);
635  for(i = unit_moves.first; i != unit_moves.second; ++i) {
636  if (tiles_adjacent((*i).second,unit_B)) {
637  return true;
638  }
639  }
640  return false;
641 }
642 
644  //make sure we don't run out of refcount
645 
646  for(const config &func : cfg_.child_range("function"))
647  {
648  const t_string &name = func["name"];
649  const t_string &inputs = func["inputs"];
650  const t_string &formula_str = func["formula"];
651 
652  std::vector<std::string> args = utils::split(inputs);
653  try {
655  create_optional_formula(formula_str),
656  create_optional_formula(func["precondition"]),
657  args);
658  }
659  catch(formula_error& e) {
660  handle_exception(e, "Error while registering function '" + name + "'");
661  }
662  }
663 
664 
666  if (const config &ai_vars = cfg_.child("vars"))
667  {
668  variant var;
669  for(const config::attribute &i : ai_vars.attribute_range()) {
670  var.serialize_from_string(i.second);
671  vars_.add(i.first, var);
672  }
673  }
674 
675 
676 }
677 
678 
680 {
681  fai_ca->evaluate(this,resources::gameboard->units());
682 
683 }
684 
686 {
687  map_formula_callable callable(fake_ptr());
688  fai_ca->update_callable_map( callable );
689  const_formula_ptr move_formula(fai_ca->get_action());
690  return !make_action(move_formula, callable).is_empty();
691 }
692 
693 #if 0
694 formula_ai::gamestate_change_observer::gamestate_change_observer() :
695  set_var_counter_(), set_unit_var_counter_(), continue_counter_()
696 {
698 }
699 
700 formula_ai::gamestate_change_observer::~gamestate_change_observer() {
702 }
703 
704 void formula_ai::gamestate_change_observer::handle_generic_event(const std::string& /*event_name*/) {
705  set_var_counter_ = 0;
706  set_unit_var_counter_ = 0;
707  continue_counter_ = 0;
708 }
709 
710 //return false if number of calls exceeded MAX_CALLS
711 bool formula_ai::gamestate_change_observer::set_var_check() {
712  if(set_var_counter_ >= MAX_CALLS)
713  return false;
714 
715  set_var_counter_++;
716  return true;
717 }
718 
719 bool formula_ai::gamestate_change_observer::set_unit_var_check() {
720  if(set_unit_var_counter_ >= MAX_CALLS)
721  return false;
722 
723  set_unit_var_counter_++;
724  return true;
725 }
726 
727 bool formula_ai::gamestate_change_observer::continue_check() {
728  if(continue_counter_ >= MAX_CALLS)
729  return false;
730 
731  continue_counter_++;
732  return true;
733 }
734 #endif
735 
737 {
738  if (!cfg_)
739  {
740  return config();
741  }
742  DBG_AI << "formula_ai::to_config(): "<< cfg_<<std::endl;
743  config cfg = cfg_;
744 
745  //formula AI variables
746  cfg.clear_children("vars");
747  if (vars_.empty() == false) {
748  config &ai_vars = cfg.add_child("vars");
749 
750  std::string str;
752  {
753  try {
754  str = i->second.serialize_to_string();
755  } catch (type_error&) {
756  WRN_AI << "variable ["<< i->first <<"] is not serializable - it will not be persisted across savegames"<<std::endl;
757  continue;
758  }
759  if (!str.empty())
760  {
761  ai_vars[i->first] = str;
762  str.clear();
763  }
764  }
765  }
766 
767  return cfg;
768 }
769 
770 } // end of namespace ai
Defines formula ai.
variant execute_variant(const variant &to_exec)
Definition: variant.cpp:659
virtual std::string get_grouping() const override
Definition: contexts.hpp:742
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:363
::tod_manager * tod_manager
Definition: resources.cpp:30
virtual const move_map & get_enemy_srcdst() const override
Definition: contexts.hpp:718
virtual int get_villages_per_scout() const override
Definition: contexts.hpp:881
virtual const unit_map & units() const
Definition: game_board.hpp:97
unit_iterator end()
Definition: map.hpp:415
std::vector< char_t > string
formula_ai(const formula_ai &)=delete
Defines formula ai candidate actions - headers.
This class represents a single unit of a specific type.
Definition: unit.hpp:101
static variant evaluate(const const_formula_ptr &f, const formula_callable &variables, formula_debugger *fdb=nullptr, variant default_res=variant(0))
Definition: formula.hpp:39
std::string formula
Definition: formula.hpp:106
const std::set< std::string > & recruits() const
Definition: team.hpp:222
unit_iterator find_leader(int side)
Definition: map.cpp:329
bool execute_candidate_action(wfl::candidate_action_ptr fai_ca)
Execute the fai candidate action.
Definition: ai.cpp:685
const config cfg_
Definition: ai.hpp:159
std::string filename
Definition: formula.hpp:107
virtual double get_leader_value() const override
Definition: contexts.hpp:779
Managing the AI-Game interaction - AI actions and their results.
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.hpp:299
static lg::log_domain log_formula_ai("ai/engine/fai")
game_display * screen
Definition: resources.cpp:27
bool is_enemy(int n) const
Definition: team.hpp:241
child_itors child_range(config_key_type key)
Definition: config.cpp:306
wfl::candidate_action_ptr ca_ptr
Definition: ai.cpp:73
attribute_map::value_type attribute
Definition: config.hpp:254
virtual double get_village_value() const override
Definition: contexts.hpp:875
virtual const move_map & get_srcdst() const override
Definition: contexts.hpp:851
void handle_exception(wfl::formula_error &e) const
Definition: ai.cpp:117
unit_iterator begin()
Definition: map.hpp:405
std::vector< formula_input > formula_input_vector
void build_all(unit_type::BUILD_STATUS status)
Makes sure the all unit_types are built to the specified level.
Definition: types.cpp:1319
Composite AI stages.
unit_type_data unit_types
Definition: types.cpp:1455
std::string evaluate(const std::string &formula_str)
Definition: ai.cpp:160
formula_input_vector inputs() const
Definition: callable.hpp:62
virtual const std::vector< team > & teams() const
Definition: game_board.hpp:92
#define h
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
std::shared_ptr< formula_function > formula_function_ptr
Definition: function.hpp:224
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
Definition: location.cpp:225
void clear()
Definition: config.cpp:753
-file sdl_utils.hpp
wfl::formula_ptr create_optional_formula(const std::string &formula_string) const
Create a new formula from the string, using the symbol table which is stored in the AI...
Definition: ai.cpp:143
virtual wfl::variant get_value(const std::string &key) const override
Definition: ai.cpp:287
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
#define WRN_AI
Definition: ai.cpp:65
A single unit type that the player may recruit.
Definition: types.hpp:43
void on_create()
Definition: ai.cpp:643
const_iterator end() const
Definition: callable.hpp:270
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:58
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:357
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.hpp:339
Structure which holds a single route between one location and another.
Definition: pathfind.hpp:131
bool valid() const
Definition: location.hpp:72
void clear_children(T...keys)
Definition: config.hpp:507
map_formula_callable & add(const std::string &key, const variant &value)
Definition: callable.hpp:252
wfl::variant get_keeps() const
Definition: ai.cpp:601
void set_value(const std::string &key, const wfl::variant &value) override
Definition: ai.cpp:597
virtual double get_leader_aggression() const override
Definition: contexts.hpp:760
std::string type
Definition: formula.hpp:105
game_board * gameboard
Definition: resources.cpp:20
virtual bool get_passive_leader() const override
Definition: contexts.hpp:785
virtual bool get_passive_leader_shares_keep() const override
Definition: contexts.hpp:791
void serialize_from_string(const std::string &str)
Definition: variant.cpp:635
void evaluate_candidate_action(wfl::candidate_action_ptr fai_ca)
Evaluate the fai candidate action.
Definition: ai.cpp:679
virtual void add_formula_function(const std::string &name, wfl::const_formula_ptr formula, wfl::const_formula_ptr precondition, const std::vector< std::string > &args)
Definition: ai.cpp:265
virtual const move_map & get_enemy_dstsrc() const override
Definition: contexts.hpp:706
Managing the AIs lifecycle - headers.
virtual const std::vector< std::string > get_recruitment_pattern() const override
Definition: contexts.hpp:833
iterator end()
end iterator
pathfind::teleport_map get_allowed_teleports(unit_map::iterator &unit_it) const
Definition: ai.cpp:260
virtual int get_attack_depth() const override
Definition: contexts.hpp:644
wfl::attack_map_callable attacks_callable
Definition: ai.hpp:167
Encapsulates the map of the game.
Definition: location.hpp:40
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const size_t width, const size_t height, const teleport_map *teleports, bool border)
#define LOG_AI
Definition: ai.cpp:64
void get_locations(std::set< map_location > &locs, bool with_border=false) const
gets all locations on the map that match this filter
Definition: filter.hpp:59
static config unit_moves(reports::context &rc, const unit *u)
Definition: reports.cpp:581
bool is_empty() const
Definition: variant.cpp:271
formula_callable_ptr fake_ptr()
Definition: callable.hpp:41
int get_count() const
Get the current value of the recursion counter.
Definition: contexts.hpp:76
virtual const team & current_team() const override
Definition: contexts.hpp:536
virtual void get_inputs(wfl::formula_input_vector &inputs) const override
Definition: ai.cpp:566
wfl::map_formula_callable vars_
Definition: ai.hpp:170
Game information for the AI.
recursion_counter recursion_counter_
Definition: ai.hpp:160
bool can_reach_unit(map_location unit_A, map_location unit_B) const
Definition: ai.cpp:626
virtual config to_config() const
Definition: ai.cpp:736
Default AI contexts.
#define DBG_AI
Definition: ai.cpp:63
size_t i
Definition: function.cpp:933
virtual double get_scout_village_targeting() const override
Definition: contexts.hpp:857
#define ERR_AI
Definition: ai.cpp:66
virtual side_number get_side() const override
Get the side number.
Definition: contexts.hpp:477
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:42
int w
std::shared_ptr< const formula > const_formula_ptr
Definition: formula_fwd.hpp:23
virtual bool get_leader_ignores_keep() const override
Definition: contexts.hpp:773
bool is_null() const
Functions to test the type of the internal value.
Definition: variant.hpp:58
config & add_child(config_key_type key)
Definition: config.cpp:419
wfl::candidate_action_ptr load_candidate_action_from_config(const config &cfg)
Definition: ai.cpp:75
void mutate_value(const std::string &key, const variant &value)
Definition: callable.hpp:57
std::shared_ptr< base_candidate_action > candidate_action_ptr
Definition: candidates.hpp:36
display_chat_manager & get_chat_manager()
virtual const move_map & get_dstsrc() const override
Definition: contexts.hpp:700
std::map< std::string, variant >::const_iterator const_iterator
Definition: callable.hpp:267
virtual double get_aggression() const override
Definition: contexts.hpp:638
virtual const wfl::variant & get_attacks_as_variant() const override
Definition: contexts.hpp:682
#define f
Definition: contexts.hpp:42
wfl::ai_function_symbol_table function_table_
Definition: ai.hpp:173
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:350
Composite AI contexts.
Standard logging facilities (interface).
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definition: variant.cpp:649
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
Definition: teleport.cpp:259
recall_list_manager & recall_list()
Definition: team.hpp:214
void add_function(const std::string &name, formula_function_ptr &&fcn)
Definition: function.cpp:1429
Container associating units to locations.
Definition: map.hpp:99
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
Definition: types.cpp:1273
virtual bool get_support_villages() const override
Definition: contexts.hpp:869
#define e
virtual const terrain_filter & get_avoid() const override
Definition: contexts.hpp:688
wfl::variant keeps_cache_
Definition: ai.hpp:166
static void add_input(formula_input_vector &inputs, const std::string &key, FORMULA_ACCESS_TYPE access_type=FORMULA_READ_ONLY)
Definition: callable.hpp:135
unit_iterator find(size_t id)
Definition: map.cpp:311
void display_message(const std::string &msg) const
Definition: ai.cpp:136
int get_recursion_count() const override
Get the value of the recursion counter.
Definition: ai.cpp:95
const_iterator begin() const
Definition: callable.hpp:269
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
void add_chat_message(const time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
wfl::variant make_action(wfl::const_formula_ptr formula_, const wfl::formula_callable &variables)
Definition: ai.cpp:188
ai_context * ai_ptr_
Definition: ai.hpp:158
virtual double get_caution() const override
Definition: contexts.hpp:694
static map_location::DIRECTION n
This module contains various pathfinding functions and utilities.
void set_ai_context(ai_context *context)
Definition: ai.cpp:154
unit_map * units
Definition: resources.cpp:34
void init_readonly_context_proxy(readonly_context &target)
Definition: contexts.hpp:518
pathfind::plain_route shortest_path_calculator(const map_location &src, const map_location &dst, unit_map::iterator &unit_it, pathfind::teleport_map &allowed_teleports) const
Definition: ai.cpp:206
std::shared_ptr< formula > formula_ptr
Definition: formula_fwd.hpp:21