1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00
vcmi/AI/GeniusAI/CGeniusAI.h
Michał W. Urbańczyk b4144dc616 Callback jugglery, part 1.
Fixed #252.
2011-05-03 03:14:18 +00:00

223 lines
7.9 KiB
C++

#ifndef __CGENIUSAI_H__
#define __CGENIUSAI_H__
#include "Common.h"
#include "BattleLogic.h"
#include "GeneralAI.h"
#include "../../lib/CondSh.h"
#include <set>
#include <list>
#include <queue>
class CBuilding;
namespace geniusai {
enum BattleState
{
NO_BATTLE,
UPCOMING_BATTLE,
ONGOING_BATTLE,
ENDING_BATTLE
};
class Priorities;
class CGeniusAI : public CGlobalAI
{
private:
// TODO: cb... come back, croach busters!?
CCallback* m_cb;
geniusai::BattleAI::CBattleLogic* m_battleLogic;
geniusai::GeneralAI::CGeneralAI m_generalAI;
geniusai::Priorities* m_priorities;
CondSh<BattleState> 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 previouslyVisited_pos;
int3 interestingPos;
bool finished;
int remainingMovement;
const CGHeroInstance * h;
};
struct TownModel
{
TownModel(const CGTownInstance *t);
const CGTownInstance *t;
std::vector<std::pair<ui32, std::vector<ui32> > > creaturesToRecruit;
//CCreatureSet creaturesInGarrison; //type, num
bool hasBuilt;
};
HypotheticalGameState(){}
HypotheticalGameState(CGeniusAI & ai);
void update(CGeniusAI & ai);
CGeniusAI * AI;
std::vector<const CGHeroInstance *> AvailableHeroesToBuy;
std::vector<ui32> resourceAmounts;
std::vector<HeroModel> heroModels;
std::vector<TownModel> 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,
rearangeTroops,
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; //interactive object
mutable std::vector<HypotheticalGameState::HeroModel*> 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()<other.obj->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<int,bool> isHeroStrong;//hero
std::set< AIObjectContainer > knownVisitableObjects;
std::set<HeroObjective> currentHeroObjectives; //can be fulfilled right now
std::set<TownObjective> currentTownObjectives;
std::vector<AIObjectivePtrCont> objectiveQueue;
public:
CGeniusAI();
virtual ~CGeniusAI();
virtual void init(CCallback * 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<CSelectableComponent*> & components, int askID){};
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &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<ui16> &skills, boost::function<void(ui32)> &callback);
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &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(const BattleAttack *ba); //called when stack is performing attack
virtual void battleStacksAttacked(const std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack())
virtual void battleEnd(const 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, THex dest, int distance, bool end);
virtual void battleSpellCast(const BattleSpellCast *sc);
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
//virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> 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(const CStack * stack);
void battleResultsApplied();
friend class Priorities;
};
}
#endif // __CGENIUSAI_H__