2009-08-04 11:56:38 +03:00
# ifndef __CGENIUSAI_H__
# define __CGENIUSAI_H__
# include "Common.h"
# include "BattleLogic.h"
# include "GeneralAI.h"
2009-08-06 08:08:17 +03:00
# include "../../lib/CondSh.h"
2009-08-04 01:15:13 +03:00
# include <set>
# include <list>
# include <queue>
2009-08-04 11:56:38 +03:00
class CBuilding ;
namespace GeniusAI {
enum BattleState
{
NO_BATTLE ,
UPCOMING_BATTLE ,
ONGOING_BATTLE ,
ENDING_BATTLE
} ;
2009-08-18 10:37:45 +03:00
class Priorities ;
2009-08-04 11:56:38 +03:00
class CGeniusAI : public CGlobalAI
{
private :
ICallback * m_cb ;
GeniusAI : : BattleAI : : CBattleLogic * m_battleLogic ;
GeniusAI : : GeneralAI : : CGeneralAI m_generalAI ;
2009-08-18 10:37:45 +03:00
GeniusAI : : Priorities * m_priorities ;
2009-08-04 11:56:38 +03:00
CondSh < BattleState > m_state ; //are we engaged into battle?
2009-08-06 12:52:07 +03:00
struct AIObjectContainer
2009-08-04 01:15:13 +03:00
{
AIObjectContainer ( const CGObjectInstance * o ) : o ( o ) { }
const CGObjectInstance * o ;
2009-08-06 12:52:07 +03:00
bool operator < ( const AIObjectContainer & b ) const ;
2009-08-04 01:15:13 +03:00
} ;
2009-08-07 11:41:40 +03:00
2009-08-04 01:15:13 +03:00
class HypotheticalGameState
{
public :
2009-08-06 12:52:07 +03:00
struct HeroModel
2009-08-04 01:15:13 +03:00
{
2009-08-05 12:46:55 +03:00
HeroModel ( ) { }
2009-08-06 12:52:07 +03:00
HeroModel ( const CGHeroInstance * h ) ;
2009-08-04 01:15:13 +03:00
int3 pos ;
2009-08-19 13:18:14 +03:00
int3 previouslyVisited_pos ;
2009-08-05 12:46:55 +03:00
int3 interestingPos ;
2009-08-06 12:52:07 +03:00
bool finished ;
2009-08-04 01:15:13 +03:00
int remainingMovement ;
const CGHeroInstance * h ;
} ;
2009-08-06 12:52:07 +03:00
struct TownModel
2009-08-05 12:46:55 +03:00
{
2009-08-06 12:52:07 +03:00
TownModel ( const CGTownInstance * t ) ;
2009-08-05 12:46:55 +03:00
const CGTownInstance * t ;
std : : vector < std : : pair < ui32 , std : : vector < ui32 > > > creaturesToRecruit ;
2009-08-06 12:52:07 +03:00
CCreatureSet creaturesInGarrison ; //type, num
2009-08-05 12:46:55 +03:00
bool hasBuilt ;
} ;
2009-08-06 12:52:07 +03:00
HypotheticalGameState ( ) { }
2009-08-18 10:37:45 +03:00
HypotheticalGameState ( CGeniusAI & ai ) ;
2009-08-06 12:52:07 +03:00
2009-08-18 10:37:45 +03:00
void update ( CGeniusAI & ai ) ;
CGeniusAI * AI ;
2009-08-04 01:15:13 +03:00
std : : vector < const CGHeroInstance * > AvailableHeroesToBuy ;
2009-08-04 11:56:38 +03:00
std : : vector < int > resourceAmounts ;
2009-08-04 01:15:13 +03:00
std : : vector < HeroModel > heroModels ;
std : : vector < TownModel > townModels ;
std : : set < AIObjectContainer > knownVisitableObjects ;
} ;
2009-08-07 11:41:40 +03:00
2009-08-04 01:15:13 +03:00
class AIObjective
{
public :
enum Type
{
//hero objectives
2009-08-18 10:37:45 +03:00
visit , //done TODO: upon visit friendly hero, trade
2009-08-06 12:52:07 +03:00
attack , //done
2009-08-18 10:37:45 +03:00
//flee,
2009-08-04 01:15:13 +03:00
dismissUnits ,
dismissYourself ,
2009-08-19 13:18:14 +03:00
rearangeTroops ,
2009-08-18 10:37:45 +03:00
finishTurn , //done //uses up remaining motion to get somewhere interesting.
2009-08-04 01:15:13 +03:00
//town objectives
2009-08-06 12:52:07 +03:00
recruitHero , //done
buildBuilding , //done
recruitCreatures , //done
upgradeCreatures //done
2009-08-04 01:15:13 +03:00
} ;
2009-08-07 11:41:40 +03:00
CGeniusAI * AI ;
2009-08-04 01:15:13 +03:00
Type type ;
virtual void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) = 0 ;
2009-08-04 11:56:38 +03:00
virtual HypotheticalGameState pretend ( const HypotheticalGameState & ) = 0 ;
2009-08-07 11:41:40 +03:00
virtual void print ( ) const = 0 ;
2009-08-04 01:15:13 +03:00
virtual float getValue ( ) const = 0 ; //how much is it worth to the AI to achieve
} ;
class HeroObjective : public AIObjective
{
public :
2009-08-18 10:37:45 +03:00
HypotheticalGameState hgs ;
2009-08-04 01:15:13 +03:00
int3 pos ;
const CGObjectInstance * object ;
2009-08-21 21:18:52 +03:00
mutable std : : vector < HypotheticalGameState : : HeroModel * > whoCanAchieve ;
2009-08-04 01:15:13 +03:00
2009-08-21 21:18:52 +03:00
//HeroObjective(){}
//HeroObjective(Type t):object(NULL){type = t;}
2009-08-18 10:37:45 +03:00
HeroObjective ( const HypotheticalGameState & hgs , Type t , const CGObjectInstance * object , HypotheticalGameState : : HeroModel * h , CGeniusAI * AI ) ;
2009-08-06 12:52:07 +03:00
bool operator < ( const HeroObjective & other ) const ;
2009-08-04 01:15:13 +03:00
void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) ;
2009-08-04 11:56:38 +03:00
HypotheticalGameState pretend ( const HypotheticalGameState & hgs ) { return hgs ; } ;
2009-08-07 11:41:40 +03:00
float getValue ( ) const ;
void print ( ) const ;
2009-08-04 01:15:13 +03:00
private :
2009-08-07 11:41:40 +03:00
mutable float _value ;
2009-08-18 10:37:45 +03:00
mutable float _cost ;
2009-08-04 01:15:13 +03:00
} ;
2009-08-04 11:56:38 +03:00
//town objectives
2009-08-05 12:46:55 +03:00
//recruitHero
2009-08-04 11:56:38 +03:00
//buildBuilding
2009-08-05 12:46:55 +03:00
//recruitCreatures
//upgradeCreatures
2009-08-04 01:15:13 +03:00
class TownObjective : public AIObjective
{
public :
2009-08-18 10:37:45 +03:00
HypotheticalGameState hgs ;
2009-08-04 01:15:13 +03:00
HypotheticalGameState : : TownModel * whichTown ;
int which ; //which hero, which building, which creature,
2009-08-18 10:37:45 +03:00
TownObjective ( const HypotheticalGameState & hgs , Type t , HypotheticalGameState : : TownModel * tn , int Which , CGeniusAI * AI ) ;
2009-08-04 01:15:13 +03:00
2009-08-06 12:52:07 +03:00
bool operator < ( const TownObjective & other ) const ;
2009-08-04 01:15:13 +03:00
void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) ;
2009-08-04 11:56:38 +03:00
HypotheticalGameState pretend ( const HypotheticalGameState & hgs ) { return hgs ; } ;
2009-08-07 11:41:40 +03:00
float getValue ( ) const ;
void print ( ) const ;
2009-08-04 01:15:13 +03:00
private :
2009-08-07 11:41:40 +03:00
mutable float _value ;
2009-08-18 10:37:45 +03:00
mutable float _cost ;
2009-08-04 01:15:13 +03:00
} ;
class AIObjectivePtrCont
{
public :
AIObjectivePtrCont ( ) : obj ( NULL ) { }
AIObjectivePtrCont ( AIObjective * obj ) : obj ( obj ) { } ;
AIObjective * obj ;
2009-08-06 12:52:07 +03:00
bool operator < ( const AIObjectivePtrCont & other ) const { return obj - > getValue ( ) < other . obj - > getValue ( ) ; }
2009-08-04 01:15:13 +03:00
} ;
2009-08-04 11:56:38 +03:00
HypotheticalGameState trueGameState ;
AIObjective * getBestObjective ( ) ;
void addHeroObjectives ( HypotheticalGameState : : HeroModel & h , HypotheticalGameState & hgs ) ;
void addTownObjectives ( HypotheticalGameState : : TownModel & h , HypotheticalGameState & hgs ) ;
void fillObjectiveQueue ( HypotheticalGameState & hgs ) ;
2009-08-05 12:46:55 +03:00
2009-08-04 11:56:38 +03:00
void reportResources ( ) ;
2009-08-06 12:52:07 +03:00
void startFirstTurn ( ) ;
std : : map < int , bool > isHeroStrong ; //hero
2009-08-04 11:56:38 +03:00
std : : set < AIObjectContainer > knownVisitableObjects ;
2009-08-04 01:15:13 +03:00
std : : set < HeroObjective > currentHeroObjectives ; //can be fulfilled right now
std : : set < TownObjective > currentTownObjectives ;
2009-08-04 11:56:38 +03:00
std : : vector < AIObjectivePtrCont > objectiveQueue ;
public :
CGeniusAI ( ) ;
virtual ~ CGeniusAI ( ) ;
2009-08-04 01:15:13 +03:00
2009-08-04 11:56:38 +03:00
virtual void init ( ICallback * CB ) ;
virtual void yourTurn ( ) ;
virtual void heroKilled ( const CGHeroInstance * ) ;
virtual void heroCreated ( const CGHeroInstance * ) ;
virtual void heroMoved ( const TryMoveHero & ) ;
2009-08-16 18:39:18 +03:00
virtual void heroPrimarySkillChanged ( const CGHeroInstance * hero , int which , si64 val ) { } ;
2009-08-04 11:56:38 +03:00
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.
2009-08-04 01:15:13 +03:00
virtual void tileRevealed ( int3 pos ) ;
virtual void tileHidden ( int3 pos ) ;
2009-08-04 11:56:38 +03:00
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 , 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 ( BattleAttack * ba ) ; //called when stack is performing attack
virtual void battleStacksAttacked ( std : : set < BattleStackAttacked > & 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 < 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 ( int stackID ) ;
void battleResultsApplied ( ) ;
2009-08-18 10:37:45 +03:00
friend class Priorities ;
2009-08-04 11:56:38 +03:00
} ;
}
# endif // __CGENIUSAI_H__