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