2009-08-04 11:56:38 +03:00
# ifndef __CGENIUSAI_H__
# define __CGENIUSAI_H__
# include "Common.h"
# include "BattleLogic.h"
# include "GeneralAI.h"
# 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
} ;
class CGeniusAI : public CGlobalAI
{
private :
ICallback * m_cb ;
GeniusAI : : BattleAI : : CBattleLogic * m_battleLogic ;
GeniusAI : : GeneralAI : : CGeneralAI m_generalAI ;
CondSh < BattleState > m_state ; //are we engaged into battle?
2009-08-04 01:15:13 +03:00
class AIObjectContainer
{
public :
AIObjectContainer ( const CGObjectInstance * o ) : o ( o ) { }
const CGObjectInstance * o ;
bool operator < ( const AIObjectContainer & b ) const
{
if ( o - > pos ! = b . o - > pos )
return o - > pos < b . o - > pos ;
return o - > id < b . o - > id ;
}
} ;
2009-08-04 11:56:38 +03:00
2009-08-04 01:15:13 +03:00
class HypotheticalGameState
{
public :
2009-08-04 11:56:38 +03:00
HypotheticalGameState ( ) { }
2009-08-04 01:15:13 +03:00
HypotheticalGameState ( CGeniusAI & AI )
: knownVisitableObjects ( AI . knownVisitableObjects )
{
std : : vector < const CGHeroInstance * > heroes = AI . m_cb - > getHeroesInfo ( ) ;
for ( std : : vector < const CGHeroInstance * > : : iterator i = heroes . begin ( ) ; i ! = heroes . end ( ) ; i + + )
heroModels . push_back ( HeroModel ( * i ) ) ;
std : : vector < const CGTownInstance * > towns = AI . m_cb - > getTownsInfo ( ) ;
for ( std : : vector < const CGTownInstance * > : : iterator i = towns . begin ( ) ; i ! = towns . end ( ) ; i + + )
townModels . push_back ( TownModel ( * i ) ) ;
if ( AI . m_cb - > howManyTowns ( ) ! = 0 )
AvailableHeroesToBuy = AI . m_cb - > getAvailableHeroes ( AI . m_cb - > getTownInfo ( 0 , 0 ) ) ;
2009-08-04 11:56:38 +03:00
2009-08-05 12:46:55 +03:00
for ( int i = 0 ; i < 8 ; i + + ) resourceAmounts . push_back ( AI . m_cb - > getResourceAmount ( i ) ) ;
2009-08-04 01:15:13 +03:00
}
class HeroModel
{
public :
2009-08-05 12:46:55 +03:00
HeroModel ( ) { }
2009-08-04 01:15:13 +03:00
HeroModel ( const CGHeroInstance * h ) : h ( h ) {
pos = h - > getPosition ( false ) ; remainingMovement = h - > movement ;
}
int3 pos ;
2009-08-05 12:46:55 +03:00
int3 interestingPos ;
2009-08-04 01:15:13 +03:00
int remainingMovement ;
const CGHeroInstance * h ;
} ;
2009-08-05 12:46:55 +03:00
class TownModel
{
public :
TownModel ( const CGTownInstance * t ) : t ( t ) { hasBuilt = t - > builded ; creaturesToRecruit = t - > creatures ; }
const CGTownInstance * t ;
std : : vector < std : : pair < ui32 , std : : vector < ui32 > > > creaturesToRecruit ;
bool hasBuilt ;
} ;
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-04 11:56:38 +03:00
2009-08-04 01:15:13 +03:00
class AIObjective
{
public :
enum Type
{
//hero objectives
visit ,
attack ,
flee ,
dismissUnits ,
dismissYourself ,
finishTurn , //uses up remaining motion to get somewhere nice.
//town objectives
recruitHero ,
2009-08-05 12:46:55 +03:00
buildBuilding ,
2009-08-04 01:15:13 +03:00
recruitCreatures ,
2009-08-05 12:46:55 +03:00
upgradeCreatures
2009-08-04 01:15:13 +03:00
} ;
Type type ;
//virtual bool operator < (const AIObjective &)const=0;
//virtual bool stillPossible(const HypotheticalGameState &)const = 0;
virtual void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) = 0 ;
2009-08-04 11:56:38 +03:00
virtual HypotheticalGameState pretend ( const HypotheticalGameState & ) = 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 :
int3 pos ;
const CGObjectInstance * object ;
std : : vector < HypotheticalGameState : : HeroModel * > whoCanAchieve ;
HeroObjective ( ) { }
HeroObjective ( Type t ) : object ( NULL ) { type = t ; }
HeroObjective ( Type t , const CGObjectInstance * object , HypotheticalGameState : : HeroModel * h ) : object ( object )
{
pos = object - > pos ;
type = t ;
whoCanAchieve . push_back ( h ) ;
2009-08-05 12:46:55 +03:00
_value = 100 + rand ( ) % 30 ;
2009-08-04 01:15:13 +03:00
}
bool operator < ( const HeroObjective & other ) const
{
if ( type ! = other . type )
return type < other . type ;
if ( pos ! = other . pos )
return pos < other . pos ;
if ( object - > id ! = other . object - > id )
return object - > id < other . object - > id ;
return false ;
}
void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) ;
2009-08-04 11:56:38 +03:00
HypotheticalGameState pretend ( const HypotheticalGameState & hgs ) { return hgs ; } ;
2009-08-04 01:15:13 +03:00
float getValue ( ) const { return _value ; }
private :
float _value ;
} ;
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 :
HypotheticalGameState : : TownModel * whichTown ;
int which ; //which hero, which building, which creature,
2009-08-05 12:46:55 +03:00
TownObjective ( Type t , HypotheticalGameState : : TownModel * tn , int Which ) : whichTown ( tn ) , which ( Which ) { type = t ; _value = 100 + rand ( ) % 30 ; }
2009-08-04 01:15:13 +03:00
bool operator < ( const TownObjective & other ) const
{
if ( type ! = other . type )
return type < other . type ;
2009-08-05 12:46:55 +03:00
if ( which ! = other . which )
return which < other . which ;
2009-08-04 01:15:13 +03:00
if ( whichTown - > t - > id ! = other . whichTown - > t - > id )
return whichTown - > t - > id < other . whichTown - > t - > id ;
return false ;
}
void fulfill ( CGeniusAI & , HypotheticalGameState & hgs ) ;
2009-08-04 11:56:38 +03:00
HypotheticalGameState pretend ( const HypotheticalGameState & hgs ) { return hgs ; } ;
2009-08-04 01:15:13 +03:00
float getValue ( ) const { return _value ; }
private :
float _value ;
} ;
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 ( ) ; }
} ;
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 ( ) ;
int turn ;
bool firstTurn ;
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 & ) ;
virtual void heroPrimarySkillChanged ( const CGHeroInstance * hero , int which , int 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.
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 ( ) ;
} ;
}
# endif // __CGENIUSAI_H__