#ifndef __CGENIUSAI_H__ #define __CGENIUSAI_H__ #include "Common.h" #include "BattleLogic.h" #include "GeneralAI.h" #include "../../lib/CondSh.h" #include #include #include class CBuilding; namespace GeniusAI { enum BattleState { NO_BATTLE, UPCOMING_BATTLE, ONGOING_BATTLE, ENDING_BATTLE }; class Priorities; class CGeniusAI : public CGlobalAI { private: ICallback* m_cb; GeniusAI::BattleAI::CBattleLogic* m_battleLogic; GeniusAI::GeneralAI::CGeneralAI m_generalAI; GeniusAI::Priorities * m_priorities; CondSh m_state; //are we engaged into battle? struct AIObjectContainer { AIObjectContainer(const CGObjectInstance * o):o(o){} const CGObjectInstance * o; bool operator<(const AIObjectContainer& b)const; }; class HypotheticalGameState { public: struct HeroModel { HeroModel(){} HeroModel(const CGHeroInstance * h); int3 pos; int3 interestingPos; bool finished; int remainingMovement; const CGHeroInstance * h; }; struct TownModel { TownModel(const CGTownInstance *t); const CGTownInstance *t; std::vector > > creaturesToRecruit; CCreatureSet creaturesInGarrison; //type, num bool hasBuilt; }; HypotheticalGameState(){} HypotheticalGameState(CGeniusAI & ai); void update(CGeniusAI & ai); CGeniusAI * AI; std::vector AvailableHeroesToBuy; std::vector resourceAmounts; std::vector heroModels; std::vector townModels; std::set< AIObjectContainer > knownVisitableObjects; }; class AIObjective { public: enum Type { //hero objectives visit, //done TODO: upon visit friendly hero, trade attack, //done //flee, dismissUnits, dismissYourself, finishTurn, //done //uses up remaining motion to get somewhere interesting. //town objectives recruitHero, //done buildBuilding, //done recruitCreatures, //done upgradeCreatures //done }; CGeniusAI * AI; Type type; virtual void fulfill(CGeniusAI &,HypotheticalGameState & hgs)=0; virtual HypotheticalGameState pretend(const HypotheticalGameState &) =0; virtual void print() const=0; virtual float getValue() const=0; //how much is it worth to the AI to achieve }; class HeroObjective: public AIObjective { public: HypotheticalGameState hgs; int3 pos; const CGObjectInstance * object; std::vector whoCanAchieve; HeroObjective(){} HeroObjective(Type t):object(NULL){type = t;} HeroObjective(const HypotheticalGameState &hgs,Type t,const CGObjectInstance * object,HypotheticalGameState::HeroModel *h,CGeniusAI * AI); bool operator < (const HeroObjective &other)const; void fulfill(CGeniusAI &,HypotheticalGameState & hgs); HypotheticalGameState pretend(const HypotheticalGameState &hgs){return hgs;}; float getValue() const; void print() const; private: mutable float _value; mutable float _cost; }; //town objectives //recruitHero //buildBuilding //recruitCreatures //upgradeCreatures class TownObjective: public AIObjective { public: HypotheticalGameState hgs; HypotheticalGameState::TownModel * whichTown; int which; //which hero, which building, which creature, TownObjective(const HypotheticalGameState &hgs,Type t,HypotheticalGameState::TownModel * tn,int Which,CGeniusAI * AI); bool operator < (const TownObjective &other)const; void fulfill(CGeniusAI &,HypotheticalGameState & hgs); HypotheticalGameState pretend(const HypotheticalGameState &hgs){return hgs;}; float getValue() const; void print() const; private: mutable float _value; mutable float _cost; }; class AIObjectivePtrCont { public: AIObjectivePtrCont():obj(NULL){} AIObjectivePtrCont(AIObjective * obj):obj(obj){}; AIObjective * obj; bool operator < (const AIObjectivePtrCont & other) const{return obj->getValue()getValue();} }; HypotheticalGameState trueGameState; AIObjective * getBestObjective(); void addHeroObjectives(HypotheticalGameState::HeroModel &h, HypotheticalGameState & hgs); void addTownObjectives(HypotheticalGameState::TownModel &h, HypotheticalGameState & hgs); void fillObjectiveQueue(HypotheticalGameState & hgs); void reportResources(); void startFirstTurn(); std::map isHeroStrong;//hero std::set< AIObjectContainer > knownVisitableObjects; std::set currentHeroObjectives; //can be fulfilled right now std::set currentTownObjectives; std::vector objectiveQueue; public: CGeniusAI(); virtual ~CGeniusAI(); virtual void init(ICallback * CB); virtual void yourTurn(); virtual void heroKilled(const CGHeroInstance *); virtual void heroCreated(const CGHeroInstance *); virtual void heroMoved(const TryMoveHero &); virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) {}; virtual void showSelDialog(std::string text, std::vector & components, int askID){}; virtual void showBlockingDialog(const std::string &text, const std::vector &components, ui32 askID, const int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. virtual void tileRevealed(int3 pos); virtual void tileHidden(int3 pos); virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function &onEnd); virtual void playerBlocked(int reason); virtual void objectRemoved(const CGObjectInstance *obj); //eg. collected resource, picked artifact, beaten hero virtual void newObject(const CGObjectInstance * obj); //eg. ship built in shipyard // battle virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero virtual void battleAttack(BattleAttack *ba); //called when stack is performing attack virtual void battleStacksAttacked(std::set & bsa); //called when stack receives damage (after battleAttack()) virtual void battleEnd(BattleResult *br); virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn virtual void battleStackMoved(int ID, int dest, int distance, bool end); virtual void battleSpellCast(SpellCast *sc); virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right virtual void battlefieldPrepared(int battlefieldType, std::vector obstacles); //called when battlefield is prepared, prior the battle beginning // virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); virtual void battleStackAttacking(int ID, int dest); virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); virtual BattleAction activeStack(int stackID); void battleResultsApplied(); friend class Priorities; }; } #endif // __CGENIUSAI_H__