The Battle for Wesnoth  1.15.11+dev
contexts.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Yurii Chernyi <terraninfo@terraninfo.net>
3  Part of the Battle for Wesnoth Project https://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  * Helper functions for the object which operates in the context of AI for specific side
17  * This is part of AI interface
18  * @file
19  */
20 
21 #include "ai/contexts.hpp"
22 
23 #include "actions/attack.hpp"
24 
25 #include "ai/actions.hpp" // for actions
26 #include "ai/composite/aspect.hpp" // for typesafe_aspect, aspect, etc
27 #include "ai/composite/engine.hpp" // for engine, engine_factory, etc
28 #include "ai/composite/goal.hpp" // for goal
29 #include "ai/composite/stage.hpp" // for ministage
30 #include "ai/game_info.hpp" // for typesafe_aspect_ptr, etc
32 #include "ai/manager.hpp" // for manager
33 
34 #include "chat_events.hpp" // for chat_handler, etc
35 #include "config.hpp" // for config, etc
36 #include "display_chat_manager.hpp"
37 #include "game_board.hpp" // for game_board
38 #include "game_config.hpp" // for debug
39 #include "game_display.hpp" // for game_display
40 #include "log.hpp" // for LOG_STREAM, logger, etc
41 #include "map/map.hpp" // for gamemap
42 #include "pathfind/pathfind.hpp" // for paths::dest_vect, paths, etc
43 #include "resources.hpp" // for units, gameboard, etc
44 #include "serialization/string_utils.hpp" // for split, etc
45 #include "team.hpp" // for team
46 #include "terrain/filter.hpp" // for terrain_filter
47 #include "terrain/translation.hpp" // for terrain_code
48 #include "time_of_day.hpp" // for time_of_day
49 #include "tod_manager.hpp" // for tod_manager
50 #include "units/unit.hpp" // for unit
51 #include "units/map.hpp" // for unit_map::iterator_base, etc
52 #include "units/ptr.hpp" // for unit_ptr
53 #include "units/types.hpp" // for attack_type, unit_type, etc
54 #include "formula/variant.hpp" // for variant
55 
56 #include <algorithm> // for find, count, max, fill_n
57 #include <cmath> // for sqrt
58 #include <cstdlib> // for abs
59 #include <ctime> // for time
60 #include <iterator> // for back_inserter
61 #include <ostream> // for operator<<, basic_ostream, etc
62 
63 static lg::log_domain log_ai("ai/general");
64 #define DBG_AI LOG_STREAM(debug, log_ai)
65 #define LOG_AI LOG_STREAM(info, log_ai)
66 #define WRN_AI LOG_STREAM(warn, log_ai)
67 #define ERR_AI LOG_STREAM(err, log_ai)
68 
69 // =======================================================================
70 //
71 // =======================================================================
72 namespace ai {
73 
75 {
77 }
78 
80 {
82 }
83 
85 {
87 }
88 
90 {
92 }
93 
95 {
97 }
98 
100 {
102 }
103 
104 attack_result_ptr readwrite_context_impl::execute_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){
106  double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression();
107  return actions::execute_attack_action(get_side(),true,attacker_loc,defender_loc,attacker_weapon, m_aggression);
108 }
109 
110 attack_result_ptr readonly_context_impl::check_attack_action(const map_location& attacker_loc, const map_location& defender_loc, int attacker_weapon){
112  double m_aggression = i.valid() && i->can_recruit() ? get_leader_aggression() : get_aggression();
113  return actions::execute_attack_action(get_side(),false,attacker_loc,defender_loc,attacker_weapon, m_aggression);
114 }
115 
116 move_result_ptr readwrite_context_impl::execute_move_action(const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok){
117  return actions::execute_move_action(get_side(),true,from,to,remove_movement,unreach_is_ok);
118 }
119 
120 move_result_ptr readonly_context_impl::check_move_action(const map_location& from, const map_location& to, bool remove_movement, bool unreach_is_ok){
121  return actions::execute_move_action(get_side(),false,from,to,remove_movement,unreach_is_ok);
122 }
123 
125  return actions::execute_recall_action(get_side(),true,id,where,from);
126 }
127 
129  return actions::execute_recruit_action(get_side(),true,unit_name,where,from);
130 }
131 
133  return actions::execute_recall_action(get_side(),false,id,where,from);
134 }
135 
137  return actions::execute_recruit_action(get_side(),false,unit_name,where,from);
138 }
139 
140 stopunit_result_ptr readwrite_context_impl::execute_stopunit_action(const map_location& unit_location, bool remove_movement, bool remove_attacks){
141  return actions::execute_stopunit_action(get_side(),true,unit_location,remove_movement,remove_attacks);
142 }
143 
144 stopunit_result_ptr readonly_context_impl::check_stopunit_action(const map_location& unit_location, bool remove_movement, bool remove_attacks){
145  return actions::execute_stopunit_action(get_side(),false,unit_location,remove_movement,remove_attacks);
146 }
147 
149  return actions::execute_synced_command_action(get_side(),true,lua_code,location);
150 }
151 
153  return actions::execute_synced_command_action(get_side(),false,lua_code,location);
154 }
155 
156 template<typename T>
158 {
159  known_aspects_.emplace(name, std::make_shared<typesafe_known_aspect<T>>(name, where, aspects_));
160 }
161 
163  : cfg_(cfg),
164  engines_(),
165  known_aspects_(),
166  advancements_(),
167  aggression_(),
168  aspects_(),
169  attacks_(),
170  avoid_(),
171  caution_(),
172  defensive_position_cache_(),
173  dstsrc_(),enemy_dstsrc_(),
174  enemy_possible_moves_(),
175  enemy_srcdst_(),
176  grouping_(),
177  goals_(),
178  keeps_(),
179  leader_aggression_(),
180  leader_goal_(),
181  leader_ignores_keep_(),
182  leader_value_(),
183  move_maps_enemy_valid_(false),
184  move_maps_valid_(false),
185  dst_src_valid_lua_(false),
186  dst_src_enemy_valid_lua_(false),
187  src_dst_valid_lua_(false),
188  src_dst_enemy_valid_lua_(false),
189  passive_leader_(),
190  passive_leader_shares_keep_(),
191  possible_moves_(),
192  recruitment_diversity_(),
193  recruitment_instructions_(),
194  recruitment_more_(),
195  recruitment_pattern_(),
196  recruitment_randomness_(),
197  recruitment_save_gold_(),
199  retreat_enemy_weight_(),
200  retreat_factor_(),
201  scout_village_targeting_(),
202  simple_targeting_(),
203  srcdst_(),
204  support_villages_(),
205  unit_stats_cache_(),
206  village_value_(),
207  villages_per_scout_()
208 {
209  init_side_context_proxy(context);
211 
212  add_known_aspect("advancements", advancements_);
213  add_known_aspect("aggression",aggression_);
214  add_known_aspect("attacks",attacks_);
215  add_known_aspect("avoid",avoid_);
216  add_known_aspect("caution",caution_);
217  add_known_aspect("grouping",grouping_);
218  add_known_aspect("leader_aggression",leader_aggression_);
219  add_known_aspect("leader_goal",leader_goal_);
220  add_known_aspect("leader_ignores_keep",leader_ignores_keep_);
221  add_known_aspect("leader_value",leader_value_);
222  add_known_aspect("passive_leader",passive_leader_);
223  add_known_aspect("passive_leader_shares_keep",passive_leader_shares_keep_);
224  add_known_aspect("recruitment_diversity",recruitment_diversity_);
225  add_known_aspect("recruitment_instructions",recruitment_instructions_);
226  add_known_aspect("recruitment_more",recruitment_more_);
227  add_known_aspect("recruitment_pattern",recruitment_pattern_);
228  add_known_aspect("recruitment_randomness",recruitment_randomness_);
229  add_known_aspect("recruitment_save_gold",recruitment_save_gold_);
230  add_known_aspect("retreat_enemy_weight",retreat_enemy_weight_);
231  add_known_aspect("retreat_factor",retreat_factor_);
232  add_known_aspect("scout_village_targeting",scout_village_targeting_);
233  add_known_aspect("simple_targeting",simple_targeting_);
234  add_known_aspect("support_villages",support_villages_);
235  add_known_aspect("village_value",village_value_);
236  add_known_aspect("villages_per_scout",villages_per_scout_);
238 }
239 
241  //init the composite ai engines
242  for(const config &cfg_element : cfg_.child_range("engine")) {
243  engine::parse_engine_from_config(*this,cfg_element,std::back_inserter(engines_));
244  }
245 
246  // init the composite ai aspects
247  for(const config &cfg_element : cfg_.child_range("aspect")) {
248  std::vector<aspect_ptr> aspects;
249  engine::parse_aspect_from_config(*this,cfg_element,cfg_element["id"],std::back_inserter(aspects));
250  add_aspects(aspects);
251  }
252 
253  // init the composite ai goals
254  for(const config &cfg_element : cfg_.child_range("goal")) {
255  engine::parse_goal_from_config(*this,cfg_element,std::back_inserter(get_goals()));
256  }
257 }
258 
260 {
261  return config();
262 }
263 
265 {
266  return config();
267 }
268 
270 {
271  config cfg;
272  for(const engine_ptr &e : engines_) {
273  cfg.add_child("engine",e->to_config());
274  }
275  for(const aspect_map::value_type &a : aspects_) {
276  cfg.add_child("aspect",a.second->to_config());
277  }
278  for(const goal_ptr &g : goals_) {
279  cfg.add_child("goal",g->to_config());
280  }
281  return cfg;
282 }
283 
285 {
287 }
288 
289 void readonly_context_impl::handle_generic_event(const std::string& /*event_name*/)
290 {
292 }
293 
296 }
297 
300 }
301 
302 void readonly_context_impl::diagnostic(const std::string& msg)
303 {
304  if(game_config::debug) {
306  }
307 }
308 
310 {
312 }
313 
314 void readonly_context_impl::log_message(const std::string& msg)
315 {
316  if(game_config::debug) {
318  std::time(nullptr), "ai", get_side(), msg, events::chat_handler::MESSAGE_PUBLIC, false);
319  }
320 }
321 
322 void readonly_context_impl::calculate_possible_moves(std::map<map_location,pathfind::paths>& res, move_map& srcdst,
323  move_map& dstsrc, bool enemy, bool assume_full_movement,
324  const terrain_filter* remove_destinations) const
325 {
326  calculate_moves(resources::gameboard->units(),res,srcdst,dstsrc,enemy,assume_full_movement,remove_destinations);
327 }
328 
329 void readonly_context_impl::calculate_moves(const unit_map& units, std::map<map_location,pathfind::paths>& res, move_map& srcdst,
330  move_map& dstsrc, bool enemy, bool assume_full_movement,
331  const terrain_filter* remove_destinations,
332  bool see_all
333  ) const
334 {
335 
336  for(unit_map::const_iterator un_it = units.begin(); un_it != units.end(); ++un_it) {
337  // If we are looking for the movement of enemies, then this unit must be an enemy unit.
338  // If we are looking for movement of our own units, it must be on our side.
339  // If we are assuming full movement, then it may be a unit on our side, or allied.
340  if ((enemy && current_team().is_enemy(un_it->side()) == false) ||
341  (!enemy && !assume_full_movement && un_it->side() != get_side()) ||
342  (!enemy && assume_full_movement && current_team().is_enemy(un_it->side()))) {
343  continue;
344  }
345  // Discount incapacitated units
346  if (un_it->incapacitated() ||
347  (!assume_full_movement && un_it->movement_left() == 0)) {
348  continue;
349  }
350 
351  // We can't see where invisible enemy units might move.
352  if (enemy && un_it->invisible(un_it->get_location()) && !see_all) {
353  continue;
354  }
355  // If it's an enemy unit, reset its moves while we do the calculations.
356  const unit_movement_resetter move_resetter(*un_it,enemy || assume_full_movement);
357 
358  // Insert the trivial moves of staying on the same map location.
359  if (un_it->movement_left() > 0) {
360  std::pair<map_location,map_location> trivial_mv(un_it->get_location(), un_it->get_location());
361  srcdst.insert(trivial_mv);
362  dstsrc.insert(trivial_mv);
363  }
364  /**
365  * TODO: This is where support for a speculative unit map is incomplete.
366  * There are several places (deep) within the paths constructor
367  * where resources::gameboard->units() is assumed to be the unit map. Rather
368  * than introduce a new parameter to numerous functions, a better
369  * solution may be for the creator of the speculative map (if one
370  * is used in the future) to cause resources::gameboard->units() to point to
371  * that map (and restore the "real" pointer when the speculating
372  * is completed). If that approach is adopted, calculate_moves()
373  * and calculate_possible_moves() become redundant, and one of
374  * them should probably be eliminated.
375  */
376  res.emplace(un_it->get_location(), pathfind::paths(*un_it, false, true, current_team(), 0, see_all));
377  }
378 
379  // deactivate terrain filtering if it's just the dummy 'matches nothing'
380  static const config only_not_tag("not");
381  if(remove_destinations && remove_destinations->to_config() == only_not_tag) {
382  remove_destinations = nullptr;
383  }
384 
385  for(std::map<map_location,pathfind::paths>::iterator m = res.begin(); m != res.end(); ++m) {
386  for(const pathfind::paths::step &dest : m->second.destinations)
387  {
388  const map_location& src = m->first;
389  const map_location& dst = dest.curr;
390 
391  if(remove_destinations != nullptr && remove_destinations->match(dst)) {
392  continue;
393  }
394 
395  bool friend_owns = false;
396 
397  // Don't take friendly villages
398  if(!enemy && resources::gameboard->map().is_village(dst)) {
399  for(std::size_t n = 0; n != resources::gameboard->teams().size(); ++n) {
400  if(resources::gameboard->teams()[n].owns_village(dst)) {
401  int side = n + 1;
402  if (get_side() != side && !current_team().is_enemy(side)) {
403  friend_owns = true;
404  }
405 
406  break;
407  }
408  }
409  }
410 
411  if(friend_owns) {
412  continue;
413  }
414 
415  if(src != dst && (resources::gameboard->find_visible_unit(dst, current_team()) == resources::gameboard->units().end()) ) {
416  srcdst.emplace(src, dst);
417  dstsrc.emplace(dst, src);
418  }
419  }
420  }
421 }
422 
423 void readonly_context_impl::add_aspects(std::vector< aspect_ptr > &aspects )
424 {
425  for(aspect_ptr a : aspects) {
426  const std::string id = a->get_id();
428  if (i != known_aspects_.end()) {
429  i->second->set(a);
430  } else {
431  ERR_AI << "when adding aspects, unknown aspect id["<<id<<"]"<<std::endl;
432  }
433  }
434 }
435 
436 void readonly_context_impl::add_facet(const std::string &id, const config &cfg) const
437 {
438  known_aspect_map::const_iterator i = known_aspects_.find(id);
439  if (i != known_aspects_.end()) {
440  i->second->add_facet(cfg);
441  } else {
442  ERR_AI << "when adding aspects, unknown aspect id["<<id<<"]"<<std::endl;
443  }
444 }
445 
447  const move_map& dstsrc, const move_map& srcdst, const move_map& enemy_dstsrc) const
448 {
450  if(itor == resources::gameboard->units().end()) {
451  static defensive_position pos;
452  pos.chance_to_hit = 0;
453  pos.vulnerability = pos.support = 0;
454  return pos;
455  }
456 
457  const std::map<map_location,defensive_position>::const_iterator position =
458  defensive_position_cache_.find(loc);
459 
460  if(position != defensive_position_cache_.end()) {
461  return position->second;
462  }
463 
464  defensive_position pos;
465  pos.chance_to_hit = 100;
466  pos.vulnerability = 10000.0;
467  pos.support = 0.0;
468 
469  typedef move_map::const_iterator Itor;
470  const std::pair<Itor,Itor> itors = srcdst.equal_range(loc);
471  for(Itor i = itors.first; i != itors.second; ++i) {
472  const int defense = itor->defense_modifier(resources::gameboard->map().get_terrain(i->second));
473  if(defense > pos.chance_to_hit) {
474  continue;
475  }
476 
477  const double vulnerability = power_projection(i->second,enemy_dstsrc);
478  const double support = power_projection(i->second,dstsrc);
479 
480  if(defense < pos.chance_to_hit || support - vulnerability > pos.support - pos.vulnerability) {
481  pos.loc = i->second;
482  pos.chance_to_hit = defense;
483  pos.vulnerability = vulnerability;
484  pos.support = support;
485  }
486  }
487 
488  defensive_position_cache_.emplace(loc, pos);
489  return defensive_position_cache_[loc];
490 }
491 
492 std::map<map_location,defensive_position>& readonly_context_impl::defensive_position_cache() const
493 {
495 }
496 
498 {
499  if (advancements_) {
500  return advancements_->get();
501  }
502 
504  return uaa;
505 }
506 
508 {
509  if (aggression_) {
510  return aggression_->get();
511  }
512  return 0;
513 }
514 
516 {
517  return aspects_;
518 }
519 
521 {
522  return aspects_;
523 }
524 
526 {
527  if (attacks_) {
528  return attacks_->get();
529  }
530  static attacks_vector av;
531  return av;
532 }
533 
535 {
536  if (attacks_) {
537  return attacks_->get_variant();
538  }
539  static wfl::variant v;
540  return v;
541 }
542 
543 const terrain_filter& readonly_context_impl::get_avoid() const
544 {
545  if (avoid_) {
546  return avoid_->get();
547  }
548  config cfg;
549  cfg.add_child("not");
550  static terrain_filter tf(vconfig(cfg, true), resources::filter_con, false);
551  return tf;
552 }
553 
555 {
556  if (caution_) {
557  return caution_->get();
558  }
559  return 0;
560 }
561 
563 {
564  if (!move_maps_valid_) {
566  }
567  return dstsrc_;
568 }
569 
571 {
572  if (!move_maps_enemy_valid_) {
574  }
575  return enemy_dstsrc_;
576 }
577 
579 {
580  if (!move_maps_enemy_valid_) {
582  }
583  return enemy_possible_moves_;
584 }
585 
587 {
588  if (!move_maps_enemy_valid_) {
590  }
591  return enemy_srcdst_;
592 }
593 
595 {
596  std::string engine_name = cfg["engine"];
597  if (engine_name.empty()) {
598  engine_name="cpp";//default engine
599  }
600 
602  while (en!=engines_.end() && ((*en)->get_name()!=engine_name) && ((*en)->get_id()!=engine_name)) {
603  ++en;
604  }
605 
606  if (en != engines_.end()){
607  return *en;
608  }
609 
611  if (eng == engine_factory::get_list().end()){
612  ERR_AI << "side "<<get_side()<<" : UNABLE TO FIND engine["<<
613  engine_name <<"]" << std::endl;
614  DBG_AI << "config snippet contains: " << std::endl << cfg << std::endl;
615  return engine_ptr();
616  }
617 
618  engine_ptr new_engine = eng->second->get_new_instance(*this,engine_name);
619  if (!new_engine) {
620  ERR_AI << "side "<<get_side()<<" : UNABLE TO CREATE engine["<<
621  engine_name <<"] " << std::endl;
622  DBG_AI << "config snippet contains: " << std::endl << cfg << std::endl;
623  return engine_ptr();
624  }
625  engines_.push_back(new_engine);
626  return engines_.back();
627 }
628 
629 const std::vector<engine_ptr>& readonly_context_impl::get_engines() const
630 {
631  return engines_;
632 }
633 
634 std::vector<engine_ptr>& readonly_context_impl::get_engines()
635 {
636  return engines_;
637 }
638 
640 {
641  if (grouping_) {
642  return grouping_->get();
643  }
644  return std::string();
645 }
646 
647 const std::vector<goal_ptr>& readonly_context_impl::get_goals() const
648 {
649  return goals_;
650 }
651 
652 std::vector<goal_ptr>& readonly_context_impl::get_goals()
653 {
654  return goals_;
655 }
656 
658 {
659  if (leader_aggression_) {
660  return leader_aggression_->get();
661  }
662  return 0;
663 }
664 
666 {
667  if (leader_goal_) {
668  return leader_goal_->get();
669  }
670  return config();
671 }
672 
673 utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_leader_ignores_keep() const
674 {
675  if (leader_ignores_keep_) {
676  return leader_ignores_keep_->get();
677  }
678  return {};
679 }
680 
682 {
683  if (leader_value_) {
684  return leader_value_->get();
685  }
686  return 0;
687 }
688 
689 utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader() const
690 {
691  if (passive_leader_) {
692  return passive_leader_->get();
693  }
694  return {};
695 }
696 
697 utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader_shares_keep() const
698 {
700  return passive_leader_shares_keep_->get();
701  }
702  return {};
703 }
704 
706 {
707  if (!move_maps_valid_) {
709  }
710  return possible_moves_;
711 }
712 
714 {
716  return recruitment_diversity_->get();
717  }
718  return 0.;
719 }
720 
722 {
724  return recruitment_instructions_->get();
725  }
726  return config();
727 }
728 
729 const std::vector<std::string> readonly_context_impl::get_recruitment_more() const
730 {
731  if (recruitment_more_) {
732  return recruitment_more_->get();
733  }
734  return std::vector<std::string>();
735 }
736 
737 const std::vector<std::string> readonly_context_impl::get_recruitment_pattern() const
738 {
739  if (recruitment_pattern_) {
740  return recruitment_pattern_->get();
741  }
742  return std::vector<std::string>();
743 }
744 
746 {
748  return recruitment_randomness_->get();
749  }
750  return 0;
751 }
752 
754 {
756  return recruitment_save_gold_->get();
757  }
758  return config();
759 }
760 
762 {
763  if (retreat_enemy_weight_) {
764  return retreat_enemy_weight_->get();
765  }
766  return 1;
767 }
768 
770 {
771  if (retreat_factor_) {
772  return retreat_factor_->get();
773  }
774  return 1;
775 }
776 
778 {
780  return scout_village_targeting_->get();
781  }
782  return 1;
783 }
784 
786 {
787  if (simple_targeting_) {
788  return simple_targeting_->get();
789  }
790  return false;
791 }
792 
794 {
795  if (!move_maps_valid_) {
797  }
798  return srcdst_;
799 }
800 
802 {
803  if (support_villages_) {
804  return support_villages_->get();
805  }
806  return false;
807 }
808 
810 {
811  if (village_value_) {
812  return village_value_->get();
813  }
814  return 0;
815 }
816 
818 {
819  if (villages_per_scout_) {
820  return villages_per_scout_->get();
821  }
822  return 0;
823 }
824 
826 {
827  return dst_src_valid_lua_;
828 }
829 
831 {
833 }
834 
836 {
837  return src_dst_valid_lua_;
838 }
839 
841 {
843 }
844 
846 {
848 }
849 
851 {
852  keeps_.clear();
853 }
854 
855 void keeps_cache::handle_generic_event(const std::string &/*event_name*/)
856 {
857  clear();
858 }
859 
861 {
862  move_maps_valid_ = false;
863  move_maps_enemy_valid_ = false;
864 
865  dst_src_valid_lua_ = false;
866  dst_src_enemy_valid_lua_ = false;
867 
868  src_dst_valid_lua_ = false;
869  src_dst_enemy_valid_lua_ = false;
870 }
871 
872 const std::set<map_location>& readonly_context_impl::keeps() const
873 {
874  return keeps_.get();
875 }
876 
878  : map_(nullptr)
879  , keeps_()
880 {
883 }
884 
886 {
889 }
890 
892 {
893  keeps_.clear();
894 }
895 
896 void keeps_cache::init(const gamemap &map)
897 {
898  map_ = &map;
899 }
900 
901 const std::set<map_location>& keeps_cache::get()
902 {
903  if(keeps_.empty()) {
904  // Generate the list of keeps:
905  // iterate over the entire map and find all keeps.
906  for(int x = 0; x != map_->w(); ++x) {
907  for(int y = 0; y != map_->h(); ++y) {
908  const map_location loc(x,y);
909  if(map_->is_keep(loc)) {
910  for(const map_location& adj : get_adjacent_tiles(loc)) {
911  if(map_->is_castle(adj)) {
912  keeps_.insert(loc);
913  break;
914  }
915  }
916  }
917  }
918  }
919  }
920 
921  return keeps_;
922 }
923 
925 {
926  const unit_map::iterator leader = resources::gameboard->units().find_leader(get_side());
927  if(leader == resources::gameboard->units().end() || leader->incapacitated()) {
928  return false;
929  }
930 
931  const map_location &start_pos = nearest_keep(leader->get_location());
932  if(start_pos.valid() == false) {
933  return false;
934  }
935 
936  if (leader->get_location() == start_pos) {
937  return true;
938  }
939 
940  // Find where the leader can move
941  const pathfind::paths leader_paths(*leader, false, true, current_team());
942 
943  return leader_paths.destinations.contains(start_pos);
944 }
945 
947 {
948  std::set<map_location> avoided_locations;
949  get_avoid().get_locations(avoided_locations);
950  const std::set<map_location>& keeps = this->keeps();
951  if(keeps.empty()) {
952  static const map_location dummy;
953  return dummy;
954  }
955 
956  const map_location* res = nullptr;
957  int closest = -1;
958  for(std::set<map_location>::const_iterator i = keeps.begin(); i != keeps.end(); ++i) {
959  if (avoided_locations.find(*i)!=avoided_locations.end()) {
960  continue;
961  }
962  const int distance = distance_between(*i,loc);
963  if(res == nullptr || distance < closest) {
964  closest = distance;
965  res = &*i;
966  }
967  }
968  if (res) {
969  return *res;
970  } else {
972  }
973 }
974 
975 double readonly_context_impl::power_projection(const map_location& loc, const move_map& dstsrc) const
976 {
977  map_location used_locs[6];
978  int ratings[6];
979  std::fill_n(ratings, 0, 6);
980  int num_used_locs = 0;
981 
982  const auto locs = get_adjacent_tiles(loc);
983 
984  const gamemap& map_ = resources::gameboard->map();
985  unit_map& units_ = resources::gameboard->units();
986 
987  int res = 0;
988 
989  bool changed = false;
990  for (int i = 0;; ++i) {
991  if (i == 6) {
992  if (!changed) break;
993  // Loop once again, in case a unit found a better spot
994  // and freed the place for another unit.
995  changed = false;
996  i = 0;
997  }
998 
999  if (map_.on_board(locs[i]) == false) {
1000  continue;
1001  }
1002 
1003  const t_translation::terrain_code terrain = map_[locs[i]];
1004 
1005  typedef move_map::const_iterator Itor;
1006  typedef std::pair<Itor,Itor> Range;
1007  Range its = dstsrc.equal_range(locs[i]);
1008 
1009  map_location* const beg_used = used_locs;
1010  map_location* end_used = used_locs + num_used_locs;
1011 
1012  int best_rating = 0;
1013  map_location best_unit;
1014 
1015  for(Itor it = its.first; it != its.second; ++it) {
1016  const unit_map::const_iterator u = units_.find(it->second);
1017 
1018  // Unit might have been killed, and no longer exist
1019  if(u == units_.end()) {
1020  continue;
1021  }
1022 
1023  const unit& un = *u;
1024 
1025  // The unit might play on the next turn
1026  int attack_turn = resources::tod_manager->turn();
1027  if(un.side() < get_side()) {
1028  ++attack_turn;
1029  }
1030  // Considering the unit location would be too slow, we only apply the bonus granted by the global ToD
1031  const int lawful_bonus = resources::tod_manager->get_time_of_day(attack_turn).lawful_bonus;
1032  int tod_modifier = 0;
1033  if(un.alignment() == unit_type::ALIGNMENT::LAWFUL) {
1034  tod_modifier = lawful_bonus;
1035  } else if(un.alignment() == unit_type::ALIGNMENT::CHAOTIC) {
1036  tod_modifier = -lawful_bonus;
1037  } else if(un.alignment() == unit_type::ALIGNMENT::LIMINAL) {
1038  tod_modifier = -(std::abs(lawful_bonus));
1039  }
1040 
1041  // The 0.5 power avoids underestimating too much the damage of a wounded unit.
1042  int64_t hp = static_cast<int>(std::sqrt(static_cast<double>(un.hitpoints()) / un.max_hitpoints()) * 1000);
1043  int64_t most_damage = 0;
1044  for(const attack_type &att : un.attacks())
1045  {
1046  int damage = att.damage() * att.num_attacks() * (100 + tod_modifier);
1047  if (damage > most_damage) {
1048  most_damage = damage;
1049  }
1050  }
1051 
1052  int64_t village_bonus = map_.is_village(terrain) ? 3 : 2;
1053  int64_t defense = 100 - un.defense_modifier(terrain);
1054  int64_t rating_64 = hp * defense * most_damage * village_bonus / 200;
1055  int rating = rating_64;
1056  if(static_cast<int64_t>(rating) != rating_64) {
1057  WRN_AI << "overflow in ai attack calculation\n";
1058  }
1059  if(rating > best_rating) {
1060  map_location *pos = std::find(beg_used, end_used, it->second);
1061  // Check if the spot is the same or better than an older one.
1062  if (pos == end_used || rating >= ratings[pos - beg_used]) {
1063  best_rating = rating;
1064  best_unit = it->second;
1065  }
1066  }
1067  }
1068 
1069  if (!best_unit.valid()) continue;
1070  map_location *pos = std::find(beg_used, end_used, best_unit);
1071  int index = pos - beg_used;
1072  if (index == num_used_locs)
1073  ++num_used_locs;
1074  else if (best_rating == ratings[index])
1075  continue;
1076  else {
1077  // The unit was in another spot already, so remove its older rating
1078  // from the final result, and require a new run to fill its old spot.
1079  res -= ratings[index];
1080  changed = true;
1081  }
1082  used_locs[index] = best_unit;
1083  ratings[index] = best_rating;
1084  res += best_rating;
1085  }
1086 
1087  return res / 100000.;
1088 }
1089 
1091 {
1092  dstsrc_ = move_map();
1093  possible_moves_ = moves_map();
1094  srcdst_ = move_map();
1095  calculate_possible_moves(possible_moves_,srcdst_,dstsrc_,false,false,&get_avoid());
1096  if (is_passive_leader("") && !is_passive_keep_sharing_leader("")) {
1098  if (i.valid()) {
1099  map_location loc = i->get_location();
1100  srcdst_.erase(loc);
1101  for(move_map::iterator it = dstsrc_.begin(); it != dstsrc_.end(); ) {
1102  if(it->second == loc) {
1103  it = dstsrc_.erase(it);
1104  } else {
1105  ++it;
1106  }
1107  }
1108  }
1109  }
1110  move_maps_valid_ = true;
1111 
1112  // invalidate lua cache
1113  dst_src_valid_lua_ = false;
1114  src_dst_valid_lua_ = false;
1115 }
1116 
1118 {
1119  enemy_dstsrc_ = move_map();
1120  enemy_srcdst_ = move_map();
1121  enemy_possible_moves_ = moves_map();
1122  calculate_possible_moves(enemy_possible_moves_,enemy_srcdst_,enemy_dstsrc_,true);
1123  move_maps_enemy_valid_ = true;
1124 
1125  // invalidate lua cache
1126  dst_src_enemy_valid_lua_ = false;
1127  src_dst_enemy_valid_lua_ = false;
1128 }
1129 
1131 {
1132  dst_src_valid_lua_ = true;
1133 }
1134 
1136 {
1137  dst_src_enemy_valid_lua_ = true;
1138 }
1139 
1141 {
1142  src_dst_valid_lua_ = true;
1143 }
1144 
1146 {
1147  src_dst_enemy_valid_lua_ = true;
1148 }
1149 
1150 const map_location& readonly_context_impl::suitable_keep(const map_location& leader_location, const pathfind::paths& leader_paths) const {
1151  if (resources::gameboard->map().is_keep(leader_location)) {
1152  return leader_location; //if leader already on keep, then return leader_location
1153  }
1154 
1155  map_location const* best_free_keep = &map_location::null_location();
1156  double move_left_at_best_free_keep = 0.0;
1157 
1158  map_location const* best_occupied_keep = &map_location::null_location();
1159  double move_left_at_best_occupied_keep = 0.0;
1160 
1161  for(const pathfind::paths::step &dest : leader_paths.destinations)
1162  {
1163  const map_location &loc = dest.curr;
1164  if (keeps().find(loc)!=keeps().end()){
1165 
1166  const int move_left_at_loc = dest.move_left;
1167  if (resources::gameboard->units().count(loc) == 0) {
1168  if ((*best_free_keep==map_location::null_location())||(move_left_at_loc>move_left_at_best_free_keep)){
1169  best_free_keep = &loc;
1170  move_left_at_best_free_keep = move_left_at_loc;
1171  }
1172  } else {
1173  if ((*best_occupied_keep==map_location::null_location())||(move_left_at_loc>move_left_at_best_occupied_keep)){
1174  best_occupied_keep = &loc;
1175  move_left_at_best_occupied_keep = move_left_at_loc;
1176  }
1177  }
1178  }
1179  }
1180 
1181  if (*best_free_keep != map_location::null_location()){
1182  return *best_free_keep; // if there is a free keep reachable during current turn, return it
1183  }
1184 
1185  if (*best_occupied_keep != map_location::null_location()){
1186  return *best_occupied_keep; // if there is an occupied keep reachable during current turn, return it
1187  }
1188 
1189  return nearest_keep(leader_location); // return nearest keep
1190 }
1191 
1192  /** Weapon choice cache, to speed simulations. */
1194 {
1195  return unit_stats_cache_;
1196 }
1197 
1198 bool readonly_context_impl::is_active(const std::string &time_of_day, const std::string &turns) const
1199 {
1200  if(time_of_day.empty() == false) {
1201  const std::vector<std::string>& times = utils::split(time_of_day);
1202  if(std::count(times.begin(),times.end(),resources::tod_manager->get_time_of_day().id) == 0) {
1203  return false;
1204  }
1205  }
1206 
1207  if(turns.empty() == false) {
1208  int turn = resources::tod_manager->turn();
1209  const std::vector<std::string>& turns_list = utils::split(turns);
1210  for(std::vector<std::string>::const_iterator j = turns_list.begin(); j != turns_list.end() ; ++j ) {
1211  const std::pair<int,int> range = utils::parse_range(*j);
1212  if(turn >= range.first && turn <= range.second) {
1213  return true;
1214  }
1215  }
1216  return false;
1217  }
1218  return true;
1219 }
1220 
1222  const utils::variant<bool, std::vector<std::string>>& aspect_value, const std::string& id) const
1223 {
1224  return utils::visit(
1225  [&id](const auto& v) {
1226  if constexpr(utils::decayed_is_same<bool, decltype(v)>) {
1227  return v;
1228  } else {
1229  return utils::contains(v, id);
1230  }
1231  },
1232  aspect_value);
1233 }
1234 
1235 bool readonly_context_impl::is_keep_ignoring_leader(const std::string &id) const
1236 {
1237  return applies_to_leader(leader_ignores_keep_->get(), id);
1238 }
1239 
1240 bool readonly_context_impl::is_passive_leader(const std::string &id) const
1241 {
1242  return applies_to_leader(passive_leader_->get(), id);
1243 }
1244 
1246 {
1247  return applies_to_leader(passive_leader_shares_keep_->get(), id);
1248 }
1249 
1250 } //of namespace ai
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:51
typesafe_aspect_ptr< terrain_filter > avoid_
Definition: contexts.hpp:1286
virtual bool get_support_villages() const override
Definition: contexts.cpp:801
virtual side_number get_side() const override
Get the side number.
Definition: contexts.hpp:961
bool is_keep(const map_location &loc) const
Definition: map.cpp:71
virtual const std::vector< std::string > get_recruitment_pattern() const override
Definition: contexts.cpp:737
virtual int get_villages_per_scout() const override
Definition: contexts.cpp:817
virtual const attacks_vector & get_attacks() const override
Definition: contexts.cpp:525
::tod_manager * tod_manager
Definition: resources.cpp:29
virtual int get_recursion_count() const override
Get the value of the recursion counter.
Definition: contexts.cpp:79
unit_iterator end()
Definition: map.hpp:428
std::pair< int, int > parse_range(const std::string &str)
typesafe_aspect_ptr< bool > simple_targeting_
Definition: contexts.hpp:1319
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:90
virtual const std::vector< team > & teams() const override
Definition: game_board.hpp:84
std::shared_ptr< stopunit_result > stopunit_result_ptr
Definition: game_info.hpp:86
virtual const std::vector< std::string > get_recruitment_more() const override
Definition: contexts.cpp:729
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.cpp:474
virtual const unit_map & units() const override
Definition: game_board.hpp:111
recruit_result_ptr check_recruit_action(const std::string &unit_name, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location()) override
Check if it is possible to recruit a unit for us on specified location.
Definition: contexts.cpp:136
This class represents a single unit of a specific type.
Definition: unit.hpp:120
void init(const gamemap &map)
Definition: contexts.cpp:896
int dummy
Definition: lstrlib.cpp:1347
virtual const move_map & get_enemy_dstsrc() const override
Definition: contexts.cpp:570
bool is_castle(const map_location &loc) const
Definition: map.cpp:69
virtual void handle_generic_event(const std::string &event_name) override
Handle generic event.
Definition: contexts.cpp:289
virtual const config get_recruitment_instructions() const override
Definition: contexts.cpp:721
typesafe_aspect_ptr< config > leader_goal_
Definition: contexts.hpp:1297
static manager & get_singleton()
Definition: manager.hpp:143
void raise_gamestate_changed()
Notifies all observers of &#39;ai_gamestate_changed&#39; event.
Definition: manager.cpp:410
virtual team & current_team_w() override
Return a reference to the &#39;team&#39; object for the AI.
Definition: contexts.cpp:99
void calculate_possible_moves(std::map< map_location, pathfind::paths > &possible_moves, move_map &srcdst, move_map &dstsrc, bool enemy, bool assume_full_movement=false, const terrain_filter *remove_destinations=nullptr) const override
Calculate the moves units may possibly make.
Definition: contexts.cpp:322
Various functions that implement attacks and attack calculations.
unit_iterator find_leader(int side)
Definition: map.cpp:327
virtual stopunit_result_ptr execute_stopunit_action(const map_location &unit_location, bool remove_movement=true, bool remove_attacks=false) override
Ask the game to remove unit movements and/or attack.
Definition: contexts.cpp:140
virtual bool is_active(const std::string &time_of_day, const std::string &turns) const override
Definition: contexts.cpp:1198
typesafe_aspect_ptr< double > caution_
Definition: contexts.hpp:1287
void add_known_aspect(const std::string &name, typesafe_aspect_ptr< T > &where)
Definition: contexts.cpp:157
#define a
Managing the AI-Game interaction - AI actions and their results.
game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
Definition: manager.cpp:674
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:492
virtual const moves_map & get_enemy_possible_moves() const override
Definition: contexts.cpp:578
virtual void set_src_dst_enemy_valid_lua() override
Definition: contexts.cpp:1145
void log_message(const std::string &msg) override
Display a debug message as a chat message.
Definition: contexts.cpp:314
child_itors child_range(config_key_type key)
Definition: config.cpp:356
std::string id
Definition: time_of_day.hpp:89
virtual bool is_passive_keep_sharing_leader(const std::string &id) const override
Definition: contexts.cpp:1245
virtual recruit_result_ptr execute_recruit_action(const std::string &unit_name, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location()) override
Ask the game to recruit a unit for us on specified location.
Definition: contexts.cpp:128
virtual void invalidate_keeps_cache() const override
Definition: contexts.cpp:850
readonly_context_impl(side_context &context, const config &cfg)
Constructor.
Definition: contexts.cpp:162
void add_turn_started_observer(events::observer *event_observer)
Adds an observer of &#39;ai_turn_started&#39; event.
Definition: manager.cpp:368
std::shared_ptr< move_result > move_result_ptr
Definition: game_info.hpp:84
void clear(const std::string &key)
Definition: general.cpp:203
virtual const gamemap & map() const override
Definition: game_board.hpp:101
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:82
dest_vect destinations
Definition: pathfind.hpp:100
unit_iterator begin()
Definition: map.hpp:418
move_result_ptr check_move_action(const map_location &from, const map_location &to, bool remove_movement=true, bool unreach_is_ok=false) override
Check if it is possible to move our unit from location &#39;from&#39; to location &#39;to&#39;.
Definition: contexts.cpp:120
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
static void parse_engine_from_config(readonly_context &context, const config &cfg, std::back_insert_iterator< std::vector< engine_ptr >> b)
Definition: engine.cpp:69
stopunit_result_ptr check_stopunit_action(const map_location &unit_location, bool remove_movement=true, bool remove_attacks=false) override
Check if it is possible to remove unit movements and/or attack.
Definition: contexts.cpp:144
Composite AI stages.
typesafe_aspect_ptr< double > retreat_factor_
Definition: contexts.hpp:1317
AI Support engine - creating specific ai components from config.
std::vector< goal_ptr > goals_
Definition: contexts.hpp:1294
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
const defensive_position & best_defensive_position(const map_location &unit, const move_map &dstsrc, const move_map &srcdst, const move_map &enemy_dstsrc) const override
Definition: contexts.cpp:446
std::shared_ptr< recruit_result > recruit_result_ptr
Definition: game_info.hpp:83
virtual config get_leader_goal() const override
Definition: contexts.cpp:665
virtual const std::set< map_location > & keeps() const override
Definition: contexts.cpp:872
void init_side_context_proxy(side_context &target)
Definition: contexts.hpp:395
static config unit_name(const unit *u)
Definition: reports.cpp:159
static void parse_goal_from_config(readonly_context &context, const config &cfg, std::back_insert_iterator< std::vector< goal_ptr >> b)
Definition: engine.cpp:78
virtual double get_scout_village_targeting() const override
Definition: contexts.cpp:777
virtual bool is_keep_ignoring_leader(const std::string &id) const override
Definition: contexts.cpp:1235
std::shared_ptr< attack_result > attack_result_ptr
Definition: game_info.hpp:81
virtual utils::variant< bool, std::vector< std::string > > get_passive_leader_shares_keep() const override
Definition: contexts.cpp:697
virtual const aspect_map & get_aspects() const override
Definition: contexts.cpp:515
typesafe_aspect_ptr< double > leader_value_
Definition: contexts.hpp:1299
bool applies_to_leader(const utils::variant< bool, std::vector< std::string >> &aspect_value, const std::string &id) const
Definition: contexts.cpp:1221
Definitions for the interface to Wesnoth Markup Language (WML).
virtual double get_retreat_factor() const override
Definition: contexts.cpp:769
std::map< map_location, defensive_position > defensive_position_cache_
Definition: contexts.hpp:1288
void add_chat_message(const std::time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
typesafe_aspect_ptr< int > villages_per_scout_
Definition: contexts.hpp:1324
virtual bool leader_can_reach_keep() const override
Definition: contexts.cpp:924
std::shared_ptr< aspect > aspect_ptr
Definition: game_info.hpp:94
virtual double get_retreat_enemy_weight() const override
Definition: contexts.cpp:761
std::multimap< map_location, map_location > move_map
The standard way in which a map of possible moves is recorded.
Definition: game_info.hpp:42
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:75
virtual double power_projection(const map_location &loc, const move_map &dstsrc) const override
Function which finds how much &#39;power&#39; a side can attack a certain location with.
Definition: contexts.cpp:975
typesafe_aspect_ptr< double > retreat_enemy_weight_
Definition: contexts.hpp:1316
std::vector< attack_analysis > attacks_vector
Definition: game_info.hpp:50
std::map< map_location, pathfind::paths > moves_map
The standard way in which a map of possible movement routes to location is recorded.
Definition: game_info.hpp:45
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:55
virtual void on_readonly_context_create() override
Definition: contexts.cpp:240
int defense_modifier(const t_translation::terrain_code &terrain) const
The unit&#39;s defense on a given terrain.
Definition: unit.cpp:1573
#define ERR_AI
Definition: contexts.cpp:67
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:59
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:344
std::shared_ptr< typesafe_aspect< T > > typesafe_aspect_ptr
Definition: game_info.hpp:57
team & get_team(int i)
Definition: game_board.hpp:96
static recall_result_ptr execute_recall_action(side_number side, bool execute, const std::string &unit_id, const map_location &where, const map_location &from)
Ask the game to recall a unit for us on specified location.
Definition: actions.cpp:1023
std::shared_ptr< recall_result > recall_result_ptr
Definition: game_info.hpp:82
void raise_gamestate_changed() const override
Notifies all interested observers of the event respectively.
Definition: contexts.cpp:94
virtual const move_map & get_enemy_srcdst() const override
Definition: contexts.cpp:586
const std::set< map_location > & get()
Definition: contexts.cpp:901
std::shared_ptr< goal > goal_ptr
Definition: game_info.hpp:99
virtual void add_aspects(std::vector< aspect_ptr > &aspects) override
Definition: contexts.cpp:423
virtual const config get_recruitment_save_gold() const override
Definition: contexts.cpp:753
int w() const
Effective map width.
Definition: map.hpp:49
virtual int get_recruitment_randomness() const override
Definition: contexts.cpp:745
map_location curr
Definition: pathfind.hpp:88
void remove_turn_started_observer(events::observer *event_observer)
Deletes an observer of &#39;ai_turn_started&#39; event.
Definition: manager.cpp:383
filter_context * filter_con
Definition: resources.cpp:23
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
Definition: tod_manager.hpp:54
virtual const std::vector< engine_ptr > & get_engines() const override
Definition: contexts.cpp:629
bool valid() const
Definition: location.hpp:88
virtual const std::vector< goal_ptr > & get_goals() const override
Definition: contexts.cpp:647
game_board * gameboard
Definition: resources.cpp:20
virtual const unit_advancements_aspect & get_advancements() const override
Definition: contexts.cpp:497
virtual ~readonly_context_impl()
Destructor.
Definition: contexts.cpp:284
void calculate_moves(const unit_map &units, std::map< map_location, pathfind::paths > &possible_moves, move_map &srcdst, move_map &dstsrc, bool enemy, bool assume_full_movement=false, const terrain_filter *remove_destinations=nullptr, bool see_all=false) const override
A more fundamental version of calculate_possible_moves which allows the use of a speculative unit map...
Definition: contexts.cpp:329
static factory_map & get_list()
Definition: engine.hpp:114
typesafe_aspect_ptr< std::vector< std::string > > recruitment_pattern_
Definition: contexts.hpp:1312
static lg::log_domain log_ai("ai/general")
virtual config to_readwrite_context_config() const override
serialize this context to config
Definition: contexts.cpp:264
virtual synced_command_result_ptr execute_synced_command_action(const std::string &lua_code, const map_location &location=map_location::null_location()) override
Ask the game to run Lua code.
Definition: contexts.cpp:148
virtual bool is_src_dst_enemy_valid_lua() const override
Definition: contexts.cpp:840
Encapsulates the map of the game.
Definition: map.hpp:170
virtual std::map< map_location, defensive_position > & defensive_position_cache() const override
Definition: contexts.cpp:492
virtual const wfl::variant & get_attacks_as_variant() const override
Definition: contexts.cpp:534
virtual const map_location & suitable_keep(const map_location &leader_location, const pathfind::paths &leader_paths) const override
get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return near...
Definition: contexts.cpp:1150
#define DBG_AI
Definition: contexts.cpp:64
bool is_enemy(int n) const
Definition: team.hpp:251
Object which temporarily resets a unit&#39;s movement.
Definition: unit.hpp:1994
const team & current_team() const override
Return a reference to the &#39;team&#39; object for the AI.
Definition: contexts.cpp:309
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands...
recall_result_ptr check_recall_action(const std::string &id, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location()) override
Check if it is possible to recall a unit for us on specified location.
Definition: contexts.cpp:132
virtual const move_map & get_srcdst() const override
Definition: contexts.cpp:793
typesafe_aspect_ptr< double > scout_village_targeting_
Definition: contexts.hpp:1318
virtual move_result_ptr execute_move_action(const map_location &from, const map_location &to, bool remove_movement=true, bool unreach_is_ok=false) override
Ask the game to move our unit from location &#39;from&#39; to location &#39;to&#39;, optionally - doing a partial mov...
Definition: contexts.cpp:116
typesafe_aspect_ptr< config > recruitment_instructions_
Definition: contexts.hpp:1310
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.cpp:594
constexpr bool decayed_is_same
Equivalent to as std::is_same_v except it uses the decayed form of V.
Definition: general.hpp:32
virtual game_info & get_info_w() override
Functions to retrieve the &#39;info&#39; object.
Definition: contexts.cpp:298
std::set< map_location > keeps_
Definition: contexts.hpp:117
virtual std::string get_grouping() const override
Definition: contexts.cpp:639
recursion_counter recursion_counter_
Definition: contexts.hpp:982
std::shared_ptr< synced_command_result > synced_command_result_ptr
Definition: game_info.hpp:87
virtual const moves_map & get_possible_moves() const override
Definition: contexts.cpp:705
Encapsulates the map of the game.
Definition: location.hpp:37
unit_iterator find(std::size_t id)
Definition: map.cpp:309
virtual void recalculate_move_maps() const override
Definition: contexts.cpp:1090
virtual int get_recursion_count() const override
Get the value of the recursion counter.
Definition: contexts.cpp:74
virtual recall_result_ptr execute_recall_action(const std::string &id, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location()) override
Ask the game to recall a unit for us on specified location.
Definition: contexts.cpp:124
virtual utils::variant< bool, std::vector< std::string > > get_passive_leader() const override
Definition: contexts.cpp:689
virtual void set_dst_src_valid_lua() override
Definition: contexts.cpp:1130
virtual bool is_dst_src_enemy_valid_lua() const override
Definition: contexts.cpp:830
virtual void set_dst_src_enemy_valid_lua() override
Definition: contexts.cpp:1135
virtual void set_src_dst_valid_lua() override
Definition: contexts.cpp:1140
void raise_user_interact()
Notifies all observers of &#39;ai_user_interact&#39; event.
Definition: manager.cpp:388
virtual bool get_simple_targeting() const override
Definition: contexts.cpp:785
virtual unit_stats_cache_t & unit_stats_cache() const override
Weapon choice cache, to speed simulations.
Definition: contexts.cpp:1193
virtual double get_recruitment_diversity() const override
Definition: contexts.cpp:713
std::vector< engine_ptr > engines_
AI Support Engines.
Definition: contexts.hpp:1278
std::size_t i
Definition: function.cpp:940
void raise_user_interact() const override
Function which should be called frequently to allow the user to interact with the interface...
Definition: contexts.cpp:89
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:498
typesafe_aspect_ptr< bool > support_villages_
Definition: contexts.hpp:1321
Game information for the AI.
void set_diagnostic(const std::string &msg)
Definition: display.cpp:1620
synced_command_result_ptr check_synced_command_action(const std::string &lua_code, const map_location &location=map_location::null_location()) override
Check if it is possible to run Lua code.
Definition: contexts.cpp:152
virtual double get_leader_value() const override
Definition: contexts.cpp:681
double g
Definition: astarsearch.cpp:64
typesafe_aspect_ptr< double > leader_aggression_
Definition: contexts.hpp:1296
static attack_result_ptr execute_attack_action(side_number side, bool execute, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression)
Ask the game to attack an enemy defender using our unit attacker from attackers current location...
Definition: actions.cpp:999
attack_itors attacks()
Gets an iterator over this unit&#39;s attacks.
Definition: unit.hpp:918
typesafe_aspect_ptr< utils::variant< bool, std::vector< std::string > > > passive_leader_
Definition: contexts.hpp:1306
static recruit_result_ptr execute_recruit_action(side_number side, bool execute, const std::string &unit_name, const map_location &where, const map_location &from)
Ask the game to recruit a unit for us on specified location.
Definition: actions.cpp:1034
virtual config to_readonly_context_config() const override
serialize to config
Definition: contexts.cpp:269
virtual side_number get_side() const override
Get the side number.
Definition: contexts.hpp:400
static synced_command_result_ptr execute_synced_command_action(side_number side, bool execute, const std::string &lua_code, const map_location &location)
Ask the game to run Lua code.
Definition: actions.cpp:1056
typesafe_aspect_ptr< attacks_vector > attacks_
Definition: contexts.hpp:1285
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:380
const bool & debug
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
typesafe_aspect_ptr< unit_advancements_aspect > advancements_
Definition: contexts.hpp:1282
typesafe_aspect_ptr< std::vector< std::string > > recruitment_more_
Definition: contexts.hpp:1311
std::map< std::pair< map_location, const unit_type * >, std::pair< battle_context_unit_stats, battle_context_unit_stats > > unit_stats_cache_t
Definition: contexts.hpp:345
virtual void invalidate_defensive_position_cache() const override
Definition: contexts.cpp:845
Helper functions for the object which operates in the context of AI for specific side this is part of...
typesafe_aspect_ptr< std::string > grouping_
Definition: contexts.hpp:1293
config & add_child(config_key_type key)
Definition: config.cpp:500
virtual double get_aggression() const override
Definition: contexts.cpp:507
static stopunit_result_ptr execute_stopunit_action(side_number side, bool execute, const map_location &unit_location, bool remove_movement, bool remove_attacks)
Ask the game to remove unit movements and/or attack.
Definition: actions.cpp:1045
virtual const terrain_filter & get_avoid() const override
Definition: contexts.cpp:543
virtual bool is_src_dst_valid_lua() const override
Definition: contexts.cpp:835
display_chat_manager & get_chat_manager()
bool is_village(const map_location &loc) const
Definition: map.cpp:65
int turns()
Definition: game.cpp:553
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
Definition: location.cpp:545
std::map< std::string, aspect_ptr > aspect_map
Definition: game_info.hpp:103
virtual void invalidate_move_maps() const override
Definition: contexts.cpp:860
virtual double get_caution() const override
Definition: contexts.cpp:554
#define WRN_AI
Definition: contexts.cpp:66
UNIT_ALIGNMENT alignment() const
The alignment of this unit.
Definition: unit.hpp:468
std::vector< std::string > split(const config_attribute_value &val)
virtual attack_result_ptr execute_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon) override
Ask the game to attack an enemy defender using our unit attacker from attackers current location...
Definition: contexts.cpp:104
typesafe_aspect_ptr< utils::variant< bool, std::vector< std::string > > > leader_ignores_keep_
Definition: contexts.hpp:1298
virtual utils::variant< bool, std::vector< std::string > > get_leader_ignores_keep() const override
Definition: contexts.cpp:673
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:338
known_aspect_map known_aspects_
Definition: contexts.hpp:1280
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
bool contains(const map_location &) const
Definition: pathfind.cpp:514
Standard logging facilities (interface).
const gamemap * map_
Definition: contexts.hpp:116
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Definition: pathfind.hpp:71
static const map_location & null_location()
Definition: location.hpp:80
Container associating units to locations.
Definition: map.hpp:97
int get_count() const
Get the current value of the recursion counter.
Definition: contexts.hpp:69
typesafe_aspect_ptr< int > recruitment_randomness_
Definition: contexts.hpp:1313
void handle_generic_event(const std::string &event_name)
Definition: contexts.cpp:855
virtual config to_side_context_config() const override
serialize this context to config
Definition: contexts.cpp:259
typesafe_aspect_ptr< double > recruitment_diversity_
Definition: contexts.hpp:1309
virtual int get_recursion_count() const override
Get the value of the recursion counter.
Definition: contexts.cpp:84
int turn() const
#define e
int side() const
The side this unit belongs to.
Definition: unit.hpp:333
virtual const map_location & nearest_keep(const map_location &loc) const override
Definition: contexts.cpp:946
typesafe_aspect_ptr< double > aggression_
Definition: contexts.hpp:1283
std::shared_ptr< engine > engine_ptr
Definition: game_info.hpp:98
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
virtual const game_info & get_info() const override
Definition: contexts.cpp:294
bool valid() const
Definition: map.hpp:273
virtual double get_village_value() const override
Definition: contexts.cpp:809
typesafe_aspect_ptr< utils::variant< bool, std::vector< std::string > > > passive_leader_shares_keep_
Definition: contexts.hpp:1307
attack_result_ptr check_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon) override
Check if it is possible to attack enemy defender using our unit attacker from attackers current locat...
Definition: contexts.cpp:110
virtual void recalculate_move_maps_enemy() const override
Definition: contexts.cpp:1117
static map_location::DIRECTION n
typesafe_aspect_ptr< config > recruitment_save_gold_
Definition: contexts.hpp:1314
int h() const
Effective map height.
Definition: map.hpp:52
This module contains various pathfinding functions and utilities.
virtual const move_map & get_dstsrc() const override
Definition: contexts.cpp:562
typesafe_aspect_ptr< double > village_value_
Definition: contexts.hpp:1323
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
virtual bool is_passive_leader(const std::string &id) const override
Definition: contexts.cpp:1240
void diagnostic(const std::string &msg) override
Show a diagnostic message on the screen.
Definition: contexts.cpp:302
static move_result_ptr execute_move_action(side_number side, bool execute, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok=false)
Ask the game to move our unit from location &#39;from&#39; to location &#39;to&#39;, optionally - doing a partial mov...
Definition: actions.cpp:1011
virtual bool is_dst_src_valid_lua() const override
Definition: contexts.cpp:825
virtual double get_leader_aggression() const override
Definition: contexts.cpp:657
void add_map_changed_observer(events::observer *event_observer)
Adds an observer of &#39;ai_map_changed&#39; event.
Definition: manager.cpp:358
static game_display * get_singleton()
virtual void add_facet(const std::string &id, const config &cfg) const override
Definition: contexts.cpp:436
void remove_map_changed_observer(events::observer *event_observer)
Deletes an observer of &#39;ai_map_changed&#39; event.
Definition: manager.cpp:378