#include "../vcmi/global.h" #include "../vcmi/CCallback.h" #include "../vcmi/lib/HeroBonus.h" #include #include /* * ExpertSystem.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ struct Bonus; template class AIholder; template class Rule; typedef Rule BRule; bool greaterThan (int prop, si32 val); enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT}; template class ExpertSystemShell { enum runType {ANY_GOAL, TRESHOLD, FULL}; private: ICallback* m_cb; protected: std::set knowledge; std::set rulesToErase; std::set rulesToAdd; std::set factsToErase; std::set factsToAdd; ui16 goalCounter; //count / evaluate achieved goals for runType public: ExpertSystemShell(){goalCounter = 0;}; std::list facts; //facts are AIholders with actual game objects, for eg. "my bonus is worthless" template void getKnowledge(const t1 &a1){}; void getNextRule(){}; void addRule(ruleType &rule){rulesToAdd.insert(rule);}; void removeRule(ruleType &rule){rulesToErase.insert(rule);}; template void returnGoals(const t2 &a2){}; template void DataDrivenReasoning(runType type); }; template class Blackboard : public ExpertSystemShell //handle Bonus info coming from different sections of the game { public: Blackboard(){this->goalCounter = 0;}; //template magic, do not touch! std::vector experts; //modules responsible for different tasks }; template class condition {//compares selected object parameter with value using functor. universal logic handler public: input object; //what the fact is, or what it's like (CSelector) si32 value; ui8 parameter; boost::function functor; //value of selected parameter, condition value condition(){object = NULL; value = 0; parameter = 0; functor = greaterThan;}; bool matchesFact(input &fact){return false;}; }; template class Rule { friend class ExpertSystemShell ; public: bool fired; //if conditions of rule were met and it produces some output ui8 conditionCounter; protected: std::set> cons; //conditions and matching facts input decision; virtual void canBeFired(); //if this data makes any sense for rule - type check virtual bool checkCondition(); //if condition is true or false virtual bool checkCondition(std::set &feed); virtual void fireRule(); //use paired conditions and facts by default virtual void fireRule(ExpertSystemShell &system); virtual void fireRule(std::set &feed); virtual void refreshRule(); virtual void refreshRule(std::set &conditionSet); //in case conditions were erased public: Rule(){fired = false; conditionCounter = 0; decision = NULL;}; template bool matchesInput() //if condition and data match type {return dynamic_cast(&givenInput);}; }; template class Goal : public Rule { protected: boost::function decision(); //do something with AI eventually public: void fireRule(){}; }; template class Weight : public Rule { public: float multiplier; //multiply input by value and return to output void fireTule(){}; }; template class AIholder { //stores certain condition and its temporal value public: si32 aiValue; input *object; AIholder(){object = NULL; aiValue = 0;} AIholder(input &o){object = o; aiValue = 0;} AIholder(input &o, si32 val){object = 0; aiValue = val;} }; class BonusSystemExpert : public ExpertSystemShell { //TODO: less templates? enum effectType {POSITIVE=1, NEGATIVE=2, EXCLUDING=4, ENEMY=8, ALLY=16}; //what is the influence of bonus and for who }; class BonusCondition : public condition //used to test rule { public: enum Parameter { type, subtype, val, duration, source, id, valType, additionalInfo, effectRange, limiter //? }; bool matchesFact(Bonus &fact); }; class BonusHolder : public AIholder { public: BonusHolder(Bonus &bonus){object = &bonus; aiValue = bonus.val;} BonusHolder(Bonus &bonus, si32 val){object = &bonus; aiValue = val;} }; class BonusRule : public Rule { protected: void fireRule(); }; inline bool greaterThan (int prop, si32 val) { if ((si32)prop > val) return true; return false; } inline bool lessThan (int prop, si32 val) { if ((si32)prop < val) return true; return false; } inline bool eqal (int prop, si32 val) { if ((si32)prop == val) return true; return false; } inline bool unequal (int prop, si32 val) { if ((si32)prop != val) return true; return false; } inline bool present (int prop, si32 val=0) //inline bool present (int prop) //TODO: can we use function with less arguments? { return(prop); //unfixable warning :( } class KnowledgeHandler///I'd opt for one omniscent knowledge manager, so no templates here { public: std::list knowledge; //permanent storage of rules void parseKnowledge(std::string &filename){}; void addKnowledge(ExpertSystemShell &expert); void addFacts(ExpertSystemShell &expert); };