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