1 /* 2 Copyright (C) 2009 - 2018 by Yurii Chernyi <terraninfo@terraninfo.net> 3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY. 11 12 See the COPYING file for more details. 13 */ 14 15 /** 16 * @file 17 * candidate action framework 18 */ 19 20 #pragma once 21 22 #include "ai/composite/component.hpp" 23 #include "ai/composite/contexts.hpp" 24 25 //============================================================================ 26 namespace ai { 27 28 class candidate_action : public virtual rca_context_proxy, public component { 29 public: 30 //this is a score guaranteed to be <=0, thus candidate action with this score will not be selected for execution 31 static const double BAD_SCORE; 32 33 //this is a score guaranteed to be very high, higher than any 'normal' candidate action score 34 static const double HIGH_SCORE; 35 36 candidate_action( rca_context &context, const config &cfg ); 37 38 /** 39 * Destructor 40 */ 41 virtual ~candidate_action(); 42 43 44 /** 45 * Evaluate the candidate action, resetting the internal state of the action 46 * @return the score 47 * @retval >0 if the action is good 48 * @retval <=0 if the action is not good 49 */ 50 virtual double evaluate() = 0; 51 52 /** 53 * Execute the candidate action 54 */ 55 virtual void execute() = 0; 56 57 /** 58 * Is this candidate action enabled ? 59 */ 60 bool is_enabled() const; 61 62 /** 63 * Enable the candidate action 64 */ 65 void enable(); 66 67 /** 68 * Disable the candidate action 69 */ 70 void disable(); 71 72 /** 73 * Get the usual score of the candidate action without re-evaluation 74 */ 75 double get_score() const; 76 77 78 /** 79 * Get the upper bound of the score of the candidate action without re-evaluation 80 */ 81 double get_max_score() const; 82 83 /** 84 * Get the name of the candidate action (useful for debug purposes) 85 */ get_name() const86 virtual std::string get_name() const 87 { return name_; } 88 89 /** 90 * Get the type of the candidate action (useful for debug purposes) 91 */ 92 const std::string& get_type() const; 93 get_id() const94 virtual std::string get_id() const 95 { return id_; } 96 get_engine() const97 virtual std::string get_engine() const 98 { return engine_; } 99 100 int get_recursion_count() const; 101 102 103 /** 104 * serialize 105 */ 106 virtual config to_config() const; 107 108 virtual void set_to_be_removed(); 109 110 virtual bool to_be_removed(); 111 112 private: 113 114 recursion_counter recursion_counter_; 115 116 bool enabled_; 117 118 119 std::string engine_; 120 121 122 double score_; 123 124 125 double max_score_; 126 127 128 std::string id_; 129 130 131 std::string name_; 132 133 134 std::string type_; 135 136 137 bool to_be_removed_; 138 139 }; 140 141 typedef std::shared_ptr<candidate_action> candidate_action_ptr; 142 143 class candidate_action_factory; 144 145 class candidate_action_factory{ 146 bool is_duplicate(const std::string &name); 147 public: 148 typedef std::shared_ptr< candidate_action_factory > factory_ptr; 149 typedef std::map<std::string, factory_ptr> factory_map; 150 typedef std::pair<const std::string, factory_ptr> factory_map_pair; 151 get_list()152 static factory_map& get_list() { 153 static factory_map *candidate_action_factories; 154 if (candidate_action_factories==nullptr) { 155 candidate_action_factories = new factory_map; 156 } 157 return *candidate_action_factories; 158 } 159 160 virtual candidate_action_ptr get_new_instance( rca_context &context, const config &cfg ) = 0; 161 candidate_action_factory(const std::string & name)162 candidate_action_factory( const std::string &name ) 163 { 164 if (is_duplicate(name)) { 165 return; 166 } 167 factory_ptr ptr_to_this(this); 168 get_list().emplace(name,ptr_to_this); 169 } 170 ~candidate_action_factory()171 virtual ~candidate_action_factory() {} 172 }; 173 174 175 template<class CANDIDATE_ACTION> 176 class register_candidate_action_factory : public candidate_action_factory { 177 public: register_candidate_action_factory(const std::string & name)178 register_candidate_action_factory( const std::string &name ) 179 : candidate_action_factory( name ) 180 { 181 } 182 get_new_instance(rca_context & ai,const config & cfg)183 virtual candidate_action_ptr get_new_instance( rca_context &ai, const config &cfg ){ 184 return std::make_shared<CANDIDATE_ACTION>(ai, cfg); 185 } 186 }; 187 188 //============================================================================ 189 190 std::ostream &operator<<(std::ostream &s, const ai::candidate_action& ca); 191 192 } //end of namespace ai 193