ExpertSystem.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "../vcmi/global.h"
  2. #include "../vcmi/CCallback.h"
  3. #include "../vcmi/lib/HeroBonus.h"
  4. #include <boost/bind.hpp>
  5. #include <set>
  6. /*
  7. * ExpertSystem.h, part of VCMI engine
  8. *
  9. * Authors: listed in file AUTHORS in main folder
  10. *
  11. * License: GNU General Public License v2.0 or later
  12. * Full text of license available in license.txt file, in main folder
  13. *
  14. */
  15. struct Bonus;
  16. template <typename fact> class AIholder;
  17. template <typename input, typename output> class Rule;
  18. typedef Rule<Bonus, Bonus> BRule;
  19. bool greaterThan (int prop, si32 val);
  20. enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT};
  21. template <typename ruleType, typename fact> class ExpertSystemShell
  22. {
  23. enum runType {ANY_GOAL, TRESHOLD, FULL};
  24. private:
  25. ICallback* m_cb;
  26. protected:
  27. std::set<ruleType> knowledge;
  28. std::set<ruleType*> rulesToErase;
  29. std::set<ruleType*> rulesToAdd;
  30. std::set<fact*> factsToErase;
  31. std::set<fact*> factsToAdd;
  32. ui16 goalCounter; //count / evaluate achieved goals for runType
  33. public:
  34. ExpertSystemShell(){goalCounter = 0;};
  35. std::list<fact> facts; //facts are AIholders with actual game objects, for eg. "my bonus is worthless"
  36. template <typename t1> void getKnowledge(const t1 &a1){};
  37. void getNextRule(){};
  38. void addRule(ruleType &rule){rulesToAdd.insert(rule);};
  39. void removeRule(ruleType &rule){rulesToErase.insert(rule);};
  40. template <typename t2> void returnGoals(const t2 &a2){};
  41. template <typename cond> void DataDrivenReasoning(runType type);
  42. };
  43. template <typename ruleType, typename fact> class Blackboard : public ExpertSystemShell <ruleType, fact>
  44. //handle Bonus info coming from different sections of the game
  45. {
  46. public:
  47. Blackboard(){this->goalCounter = 0;}; //template magic, do not touch!
  48. std::vector<ExpertSystemShell*> experts; //modules responsible for different tasks
  49. };
  50. template <typename input> class condition
  51. {//compares selected object parameter with value using functor. universal logic handler
  52. public:
  53. input object; //what the fact is, or what it's like (CSelector)
  54. si32 value;
  55. ui8 parameter;
  56. boost::function<bool(int,si32)> functor; //value of selected parameter, condition value
  57. condition(){object = NULL; value = 0; parameter = 0; functor = greaterThan;};
  58. bool matchesFact(input &fact){return false;};
  59. };
  60. template <typename input, typename conType> class Rule
  61. {
  62. friend class ExpertSystemShell <input, conType>;
  63. public:
  64. bool fired; //if conditions of rule were met and it produces some output
  65. ui8 conditionCounter;
  66. protected:
  67. std::set<std::pair<conType, input*>> cons; //conditions and matching facts
  68. input decision;
  69. virtual void canBeFired(); //if this data makes any sense for rule - type check
  70. virtual bool checkCondition(); //if condition is true or false
  71. virtual bool checkCondition(std::set<input*> &feed);
  72. virtual void fireRule(); //use paired conditions and facts by default
  73. virtual void fireRule(ExpertSystemShell<input, conType> &system);
  74. virtual void fireRule(std::set<input*> &feed);
  75. virtual void refreshRule();
  76. virtual void refreshRule(std::set<conType> &conditionSet); //in case conditions were erased
  77. public:
  78. Rule(){fired = false; conditionCounter = 0; decision = NULL;};
  79. template <typename givenInput> bool matchesInput() //if condition and data match type
  80. {return dynamic_cast<input*>(&givenInput);};
  81. };
  82. template <typename input, typename output> class Goal : public Rule <input, output>
  83. {
  84. protected:
  85. boost::function<void(output)> decision(); //do something with AI eventually
  86. public:
  87. void fireRule(){};
  88. };
  89. template <typename input, typename output> class Weight : public Rule <input, output>
  90. {
  91. public:
  92. float multiplier; //multiply input by value and return to output
  93. void fireTule(){};
  94. };
  95. template <typename input> class AIholder
  96. { //stores certain condition and its temporal value
  97. public:
  98. si32 aiValue;
  99. input *object;
  100. AIholder(){object = NULL; aiValue = 0;}
  101. AIholder(input &o){object = o; aiValue = 0;}
  102. AIholder(input &o, si32 val){object = 0; aiValue = val;}
  103. };
  104. class BonusSystemExpert : public ExpertSystemShell <BRule, Bonus>
  105. { //TODO: less templates?
  106. enum effectType {POSITIVE=1, NEGATIVE=2, EXCLUDING=4, ENEMY=8, ALLY=16}; //what is the influence of bonus and for who
  107. };
  108. class BonusCondition : public condition<CSelector> //used to test rule
  109. {
  110. public:
  111. enum Parameter
  112. {
  113. type, subtype, val, duration, source, id, valType, additionalInfo, effectRange, limiter //?
  114. };
  115. bool matchesFact(Bonus &fact);
  116. };
  117. class BonusHolder : public AIholder<Bonus>
  118. {
  119. public:
  120. BonusHolder(Bonus &bonus){object = &bonus; aiValue = bonus.val;}
  121. BonusHolder(Bonus &bonus, si32 val){object = &bonus; aiValue = val;}
  122. };
  123. class BonusRule : public Rule <BonusHolder, BonusCondition>
  124. {
  125. protected:
  126. void fireRule();
  127. };
  128. inline bool greaterThan (int prop, si32 val)
  129. {
  130. if ((si32)prop > val)
  131. return true;
  132. return false;
  133. }
  134. inline bool lessThan (int prop, si32 val)
  135. {
  136. if ((si32)prop < val)
  137. return true;
  138. return false;
  139. }
  140. inline bool eqal (int prop, si32 val)
  141. {
  142. if ((si32)prop == val)
  143. return true;
  144. return false;
  145. }
  146. inline bool unequal (int prop, si32 val)
  147. {
  148. if ((si32)prop != val)
  149. return true;
  150. return false;
  151. }
  152. inline bool present (int prop, si32 val=0)
  153. //inline bool present (int prop) //TODO: can we use function with less arguments?
  154. {
  155. return(prop); //unfixable warning :(
  156. }
  157. class KnowledgeHandler///I'd opt for one omniscent knowledge manager, so no templates here
  158. {
  159. public:
  160. std::list<BonusRule> knowledge; //permanent storage of rules
  161. void parseKnowledge(std::string &filename){};
  162. void addKnowledge(ExpertSystemShell<BRule,Bonus> &expert);
  163. void addFacts(ExpertSystemShell<BRule,Bonus> &expert);
  164. };