2008-11-25 20:51:44 +02:00
# include "CGeniusAI.h"
# include <iostream>
2009-08-04 11:56:38 +03:00
# include "../../hch/CBuildingHandler.h"
2009-08-05 12:46:55 +03:00
# include "../../lib/VCMI_Lib.h"
2009-02-07 20:52:55 +02:00
using namespace std ;
2008-11-25 20:51:44 +02:00
using namespace GeniusAI ;
2009-02-08 18:36:53 +02:00
# if defined (_MSC_VER) && (_MSC_VER >= 1020) || (__MINGW32__)
2008-11-25 20:51:44 +02:00
# include <windows.h>
# endif
2009-08-04 01:15:13 +03:00
void DbgBox ( const char * msg , bool messageBox )
2008-11-25 20:51:44 +02:00
{
2009-08-04 01:15:13 +03:00
# if defined PRINT_DEBUG
2008-11-25 20:51:44 +02:00
# if defined _DEBUG
2009-08-04 01:15:13 +03:00
//#if 0
2008-11-25 20:51:44 +02:00
# if defined (_MSC_VER) && (_MSC_VER >= 1020)
if ( messageBox )
{
MessageBoxA ( NULL , msg , " Debug message " , MB_OK | MB_ICONASTERISK ) ;
}
# endif
std : : cout < < msg < < std : : endl ;
# endif
2009-08-04 01:15:13 +03:00
# endif
2008-11-25 20:51:44 +02:00
}
2009-05-10 11:15:30 +03:00
CGeniusAI : : CGeniusAI ( )
2009-08-04 02:53:18 +03:00
: m_generalAI ( ) , turn ( 0 ) , m_state ( NO_BATTLE ) , firstTurn ( true )
2009-05-10 11:15:30 +03:00
{
}
CGeniusAI : : ~ CGeniusAI ( )
{
}
2008-11-25 20:51:44 +02:00
void CGeniusAI : : init ( ICallback * CB )
{
m_cb = CB ;
2009-05-10 11:15:30 +03:00
m_generalAI . init ( CB ) ;
2008-11-25 20:51:44 +02:00
human = false ;
playerID = m_cb - > getMyColor ( ) ;
serialID = m_cb - > getMySerial ( ) ;
std : : string info = std : : string ( " GeniusAI initialized for player " ) + boost : : lexical_cast < std : : string > ( playerID ) ;
m_battleLogic = NULL ;
2009-08-04 01:15:13 +03:00
DbgBox ( info . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
}
2009-08-01 05:57:50 +03:00
unsigned long randomFromInt ( unsigned long in )
{
return ( in * 214013 + 2531011 ) ;
}
2009-08-04 01:15:13 +03:00
void CGeniusAI : : reportResources ( )
{
std : : cout < < " AI Player " < < m_cb - > getMySerial ( ) < < " with " < < m_cb - > howManyHeroes ( true ) < < " heroes. " < < std : : endl ;
2009-08-01 05:57:50 +03:00
2009-08-04 01:15:13 +03:00
std : : cout < < m_cb - > getResourceAmount ( 0 ) < < " wood. " ;
std : : cout < < m_cb - > getResourceAmount ( 1 ) < < " mercury. " ;
std : : cout < < m_cb - > getResourceAmount ( 2 ) < < " ore. " ;
std : : cout < < m_cb - > getResourceAmount ( 3 ) < < " sulfer. " ;
std : : cout < < m_cb - > getResourceAmount ( 4 ) < < " cristal. " ;
std : : cout < < m_cb - > getResourceAmount ( 5 ) < < " gems. " ;
std : : cout < < m_cb - > getResourceAmount ( 6 ) < < " gold. " ;
std : : cout < < std : : endl ;
}
void CGeniusAI : : addHeroObjectives ( CGeniusAI : : HypotheticalGameState : : HeroModel & h , CGeniusAI : : HypotheticalGameState & hgs )
{
int3 hpos , destination ;
CPath path ;
hpos = h . pos ;
int movement = h . remainingMovement ;
2009-08-05 12:46:55 +03:00
int3 interestingPos ;
int maxInteresting = 0 ;
2009-08-04 01:15:13 +03:00
for ( std : : set < AIObjectContainer > : : const_iterator i = hgs . knownVisitableObjects . begin ( ) ; i ! = hgs . knownVisitableObjects . end ( ) ; i + + )
2009-08-01 05:57:50 +03:00
{
2009-08-04 11:56:38 +03:00
// if(i->o->ID==54||i->o->ID==34) //creatures, another hero
// continue;
2009-08-05 12:46:55 +03:00
if ( i - > o - > ID = = 53 & & i - > o - > getOwner ( ) = = m_cb - > getMyColor ( ) ) //don't visit a mine if you own, there's almost no point(maybe to leave guards or because the hero's trapped).
2009-08-04 01:15:13 +03:00
continue ;
destination = i - > o - > getSightCenter ( ) ;
2009-08-05 12:46:55 +03:00
if ( hpos . z = = destination . z ) //don't try to take a path from the underworld to the top or vice versa
2009-08-04 01:15:13 +03:00
{
2009-08-05 12:46:55 +03:00
if ( m_cb - > getPath ( hpos , destination , h . h , path ) )
2009-08-01 05:57:50 +03:00
{
2009-08-05 12:46:55 +03:00
path . convert ( 0 ) ;
if ( path . nodes [ 0 ] . dist < movement )
{
AIObjective : : Type tp = AIObjective : : visit ;
HeroObjective ho ( tp , i - > o , & h ) ;
std : : set < HeroObjective > : : iterator found = currentHeroObjectives . find ( ho ) ;
if ( found = = currentHeroObjectives . end ( ) )
currentHeroObjectives . insert ( ho ) ;
else
found - > whoCanAchieve . push_back ( & h ) ;
}
// find the most interesting object that is eventually reachable, and set a similar (out of the way) position to the ultimate goal position
int hi = rand ( ) ; //TODO: replace random numbers with some sort of ranking system
if ( hi > maxInteresting )
{
maxInteresting = hi ;
interestingPos = destination ;
}
}
}
}
//find close pos with the most neighboring empty squares
if ( h . remainingMovement > 0 & & m_cb - > getPath ( hpos , interestingPos , h . h , path ) )
{
int3 bestPos = interestingPos , currentPos , destPos ;
int howGood = 0 ;
for ( int x = - 2 ; x < = 2 ; x + + )
for ( int y = - 2 ; y < = 2 ; y + + )
{
currentPos = interestingPos + int3 ( x , y , 0 ) ;
if ( m_cb - > getVisitableObjs ( destPos ) . size ( ) ! = 0 ) //there better not be anything there
continue ;
if ( ! m_cb - > getPath ( hpos , destPos , h . h , path ) ) //it had better be reachable from the hero
continue ;
2009-08-04 01:15:13 +03:00
2009-08-05 12:46:55 +03:00
int count = 0 ;
for ( int xx = - 1 ; xx < = 1 ; xx + + )
for ( int yy = - 2 ; yy < = 1 ; yy + + )
{
destPos = currentPos + int3 ( xx , yy , 0 ) ;
if ( m_cb - > getPath ( currentPos , destPos , h . h , path ) )
count + + ;
}
if ( count > howGood )
{
howGood = count ;
bestPos = currentPos ;
}
2009-08-01 05:57:50 +03:00
}
2009-08-05 12:46:55 +03:00
h . interestingPos = bestPos ;
currentHeroObjectives . insert ( HeroObjective ( HeroObjective : : finishTurn , h . h , & h ) ) ;
}
}
void CGeniusAI : : HeroObjective : : fulfill ( CGeniusAI & cg , HypotheticalGameState & hgs )
{
HypotheticalGameState : : HeroModel * h ;
int3 hpos , destination ;
CPath path ;
CPath path2 ;
switch ( type )
{
case finishTurn :
h = whoCanAchieve . front ( ) ;
hpos = h - > pos ;
destination = h - > interestingPos ;
if ( ! cg . m_cb - > getPath ( hpos , destination , h - > h , path ) ) { cout < < " AI error: invalid destination " < < endl ; return ; }
// path.convert(0);
destination = h - > pos ;
for ( int i = path . nodes . size ( ) - 2 ; i > = 0 ; i - - ) //find closest coord that we can get to
if ( cg . m_cb - > getPath ( hpos , path . nodes [ i ] . coord , h - > h , path2 ) & & path2 . nodes [ 0 ] . dist < = h - > remainingMovement )
destination = path . nodes [ i ] . coord ;
break ;
case visit :
//std::cout << "trying to visit " << object->hoverName << std::endl;
h = whoCanAchieve [ rand ( ) % whoCanAchieve . size ( ) ] ; //TODO:replace with best hero for the job
hpos = h - > pos ;
destination = object - > getSightCenter ( ) ;
break ;
}
if ( type = = visit | | type = = finishTurn )
if ( cg . m_cb - > getPath ( hpos , destination , h - > h , path ) )
{
path . convert ( 0 ) ;
if ( cg . m_state . get ( ) ! = NO_BATTLE )
cg . m_state . waitUntil ( NO_BATTLE ) ; //wait for battle end
//wait over, battle over too. hero might be killed. check.
for ( int i = path . nodes . size ( ) - 2 ; i > = 0 & & ( cg . m_cb - > getHeroSerial ( h - > h ) > = 0 ) ; i - - )
{
cg . m_cb - > moveHero ( h - > h , path . nodes [ i ] . coord ) ;
if ( cg . m_state . get ( ) ! = NO_BATTLE )
cg . m_state . waitUntil ( NO_BATTLE ) ; //wait for battle end
2009-08-04 01:15:13 +03:00
}
2009-08-05 12:46:55 +03:00
h - > remainingMovement - = path . nodes [ 0 ] . dist ;
if ( object - > blockVisit )
h - > pos = path . nodes [ 1 ] . coord ;
else
h - > pos = destination ;
std : : set < AIObjectContainer > : : iterator i = hgs . knownVisitableObjects . find ( AIObjectContainer ( object ) ) ;
if ( i ! = hgs . knownVisitableObjects . end ( ) )
hgs . knownVisitableObjects . erase ( i ) ;
2009-08-04 01:15:13 +03:00
}
2009-08-05 12:46:55 +03:00
2009-08-04 01:15:13 +03:00
}
2009-08-05 12:46:55 +03:00
2009-08-04 01:15:13 +03:00
void CGeniusAI : : addTownObjectives ( HypotheticalGameState : : TownModel & t , HypotheticalGameState & hgs )
{
//recruitHero
2009-08-05 12:46:55 +03:00
//buildBuilding
2009-08-04 01:15:13 +03:00
//recruitCreatures
//upgradeCreatures
2009-08-04 11:56:38 +03:00
if ( hgs . heroModels . size ( ) < 3 & & hgs . resourceAmounts [ 6 ] > = 2500 ) //recruitHero
2009-08-04 01:15:13 +03:00
{
2009-08-05 12:46:55 +03:00
bool heroAtTown = false ;
for ( int i = 0 ; i < hgs . heroModels . size ( ) ; i + + )
if ( hgs . heroModels [ i ] . pos = = t . t - > getSightCenter ( ) )
heroAtTown = true ;
if ( ! heroAtTown & & vstd : : contains ( t . t - > builtBuildings , 5 ) ) //no visiting hero and built tavern
2009-08-01 05:57:50 +03:00
{
2009-08-04 01:15:13 +03:00
for ( int i = 0 ; i < hgs . AvailableHeroesToBuy . size ( ) ; i + + )
2009-08-05 12:46:55 +03:00
if ( hgs . AvailableHeroesToBuy [ i ] ! = NULL & & hgs . AvailableHeroesToBuy [ i ] - > getArmyStrength ( ) > 4000 ) //only buy heros with units
{ //TODO: recruit heros of own race.
2009-08-04 01:15:13 +03:00
TownObjective to ( AIObjective : : recruitHero , & t , 0 ) ;
currentTownObjectives . insert ( to ) ;
}
2009-08-05 12:46:55 +03:00
}
}
//buildBuilding
if ( ! t . hasBuilt )
{
std : : map < int , CBuilding * > thisTownsBuildings = VLC - > buildh - > buildings [ t . t - > subID ] ; // m_cb->getCBuildingsByID(t.t);
for ( std : : map < int , CBuilding * > : : iterator i = thisTownsBuildings . begin ( ) ; i ! = thisTownsBuildings . end ( ) ; i + + )
{
if ( m_cb - > canBuildStructure ( t . t , i - > first ) = = 7 )
{
TownObjective to ( AIObjective : : buildBuilding , & t , i - > first ) ;
currentTownObjectives . insert ( to ) ;
//cout <<"can build " << i->first << " "<< i->second->Name() << endl;
}
2009-08-01 05:57:50 +03:00
}
2009-08-04 01:15:13 +03:00
}
2009-08-05 12:46:55 +03:00
//recruitCreatures
for ( int i = 0 ; i < t . creaturesToRecruit . size ( ) ; i + + )
2009-08-04 11:56:38 +03:00
{
2009-08-05 12:46:55 +03:00
if ( t . creaturesToRecruit [ i ] . first = = 0 ) continue ;
int ID = t . creaturesToRecruit [ i ] . second . back ( ) ;
const CCreature * creature = & VLC - > creh - > creatures [ ID ] ; //m_cb->getCCreatureByID(ID);
bool canAfford = true ;
for ( int ii = 0 ; ii < creature - > cost . size ( ) ; ii + + )
if ( creature - > cost [ ii ] > hgs . resourceAmounts [ ii ] )
canAfford = false ;
if ( ! canAfford ) continue ;
//cout << "town has " << t.t->creatures[i].first << " "<< creature->namePl << " (AI Strength " << creature->AIValue << ")." << endl;
TownObjective to ( AIObjective : : recruitCreatures , & t , i ) ;
currentTownObjectives . insert ( to ) ;
2009-08-01 05:57:50 +03:00
2009-08-05 12:46:55 +03:00
}
//upgradeCreatures
/* for(int i = 0; i < t.creaturesToRecruit.size() ;i++)
{
if ( t . creaturesToRecruit [ i ] . first = = 0 ) continue ;
int ID = t . creaturesToRecruit [ i ] . second . back ( ) ;
2009-08-04 11:56:38 +03:00
const CCreature * creature = m_cb - > getCCreatureByID ( ID ) ;
2009-08-05 12:46:55 +03:00
bool canAfford = true ;
for ( int ii = 0 ; ii < creature - > cost . size ( ) ; ii + + )
if ( creature - > cost [ ii ] > hgs . resourceAmounts [ ii ] )
canAfford = false ;
if ( ! canAfford ) continue ;
//cout << "town has " << t.t->creatures[i].first << " "<< creature->namePl << " (AI Strength " << creature->AIValue << ")." << endl;
TownObjective to ( AIObjective : : recruitCreatures , & t , i ) ;
currentTownObjectives . insert ( to ) ;
} */
2009-08-04 01:15:13 +03:00
}
2009-08-04 11:56:38 +03:00
void CGeniusAI : : TownObjective : : fulfill ( CGeniusAI & cg , HypotheticalGameState & hgs )
2009-08-04 01:15:13 +03:00
{
2009-08-05 12:46:55 +03:00
CBuilding * b ;
const CCreature * creature ;
HypotheticalGameState : : HeroModel hm ;
2009-08-04 01:15:13 +03:00
switch ( type )
{
case recruitHero :
cg . m_cb - > recruitHero ( whichTown - > t , hgs . AvailableHeroesToBuy [ which ] ) ;
2009-08-05 12:46:55 +03:00
hm = HypotheticalGameState : : HeroModel ( hgs . AvailableHeroesToBuy [ which ] ) ;
hm . pos = whichTown - > t - > getSightCenter ( ) ;
hm . remainingMovement = hm . h - > maxMovePoints ( true ) ;
hgs . heroModels . push_back ( hm ) ;
hgs . resourceAmounts [ 6 ] - = 2500 ;
break ;
case buildBuilding :
b = VLC - > buildh - > buildings [ whichTown - > t - > subID ] [ which ] ; //cg.m_cb->getCBuildingsByID(whichTown->t)[which];
if ( cg . m_cb - > canBuildStructure ( whichTown - > t , which ) = = 7 )
2009-08-01 05:57:50 +03:00
{
2009-08-05 12:46:55 +03:00
cout < < " built " < < b - > Name ( ) < < " . " < < endl ;
cg . m_cb - > buildBuilding ( whichTown - > t , which ) ;
for ( int i = 0 ; b & & i < b - > resources . size ( ) ; i + + )
hgs . resourceAmounts [ i ] - = b - > resources [ i ] ;
whichTown - > hasBuilt = true ;
2009-08-01 05:57:50 +03:00
}
2009-08-05 12:46:55 +03:00
break ;
case recruitCreatures :
int ID = whichTown - > creaturesToRecruit [ which ] . second . back ( ) ; //buy upgraded if possible
creature = & VLC - > creh - > creatures [ ID ] ; //cg.m_cb->getCCreatureByID(ID);
int howMany = whichTown - > creaturesToRecruit [ which ] . first ;
for ( int i = 0 ; i < creature - > cost . size ( ) ; i + + )
howMany = min ( howMany , creature - > cost [ i ] ? hgs . resourceAmounts [ i ] / creature - > cost [ i ] : INT_MAX ) ;
if ( howMany = = 0 ) cout < < " tried to recruit without enough money. " ;
cout < < " recruiting " < < howMany < < " " < < creature - > namePl < < " (Total AI Strength " < < creature - > AIValue * howMany < < " ). " < < endl ;
cg . m_cb - > recruitCreatures ( whichTown - > t , ID , howMany ) ;
break ;
2009-08-01 05:57:50 +03:00
2009-08-04 01:15:13 +03:00
}
2009-08-05 12:46:55 +03:00
2009-08-01 05:57:50 +03:00
}
2009-08-04 11:56:38 +03:00
void CGeniusAI : : fillObjectiveQueue ( HypotheticalGameState & hgs )
{
objectiveQueue . clear ( ) ;
currentHeroObjectives . clear ( ) ;
currentTownObjectives . clear ( ) ;
for ( std : : vector < CGeniusAI : : HypotheticalGameState : : HeroModel > : : iterator i = hgs . heroModels . begin ( ) ; i ! = hgs . heroModels . end ( ) ; i + + )
addHeroObjectives ( * i , hgs ) ;
for ( std : : vector < CGeniusAI : : HypotheticalGameState : : TownModel > : : iterator i = hgs . townModels . begin ( ) ; i ! = hgs . townModels . end ( ) ; i + + )
addTownObjectives ( * i , hgs ) ;
for ( std : : set < CGeniusAI : : HeroObjective > : : iterator i = currentHeroObjectives . begin ( ) ; i ! = currentHeroObjectives . end ( ) ; i + + )
objectiveQueue . push_back ( AIObjectivePtrCont ( & ( * i ) ) ) ;
for ( std : : set < CGeniusAI : : TownObjective > : : iterator i = currentTownObjectives . begin ( ) ; i ! = currentTownObjectives . end ( ) ; i + + )
objectiveQueue . push_back ( AIObjectivePtrCont ( & ( * i ) ) ) ;
}
CGeniusAI : : AIObjective * CGeniusAI : : getBestObjective ( )
{
trueGameState = HypotheticalGameState ( * this ) ;
fillObjectiveQueue ( trueGameState ) ;
if ( ! objectiveQueue . empty ( ) )
return max_element ( objectiveQueue . begin ( ) , objectiveQueue . end ( ) ) - > obj ;
return NULL ;
}
2008-11-25 20:51:44 +02:00
void CGeniusAI : : yourTurn ( )
{
2009-08-05 12:46:55 +03:00
m_cb - > waitTillRealize = true ;
2009-08-04 01:15:13 +03:00
static int seed = rand ( ) ;
srand ( seed ) ;
if ( firstTurn )
{
//m_cb->sendMessage("vcmieagles");
2009-08-04 11:56:38 +03:00
//m_cb->sendMessage("vcmiformenos");
//m_cb->sendMessage("vcmiformenos");
2009-08-04 01:15:13 +03:00
firstTurn = false ;
}
2009-08-04 11:56:38 +03:00
//////////////TODO: replace with updates. Also add suspected objects list./////////
2009-08-04 01:15:13 +03:00
knownVisitableObjects . clear ( ) ;
int3 pos = m_cb - > getMapSize ( ) ;
for ( int x = 0 ; x < pos . x ; x + + )
for ( int y = 0 ; y < pos . y ; y + + )
for ( int z = 0 ; z < pos . z ; z + + )
tileRevealed ( int3 ( x , y , z ) ) ;
2009-08-04 11:56:38 +03:00
///////////////////////////////////////////////////////////////////////////////////
2009-08-04 01:15:13 +03:00
2009-08-04 12:40:57 +03:00
reportResources ( ) ;
2009-08-04 01:15:13 +03:00
turn + + ;
2009-08-01 05:57:50 +03:00
2009-08-04 11:56:38 +03:00
AIObjective * objective ;
while ( ( objective = getBestObjective ( ) ) ! = NULL )
objective - > fulfill ( * this , trueGameState ) ;
2009-08-01 05:57:50 +03:00
2009-08-04 01:15:13 +03:00
seed = rand ( ) ;
2008-11-25 20:51:44 +02:00
m_cb - > endTurn ( ) ;
2009-08-05 12:46:55 +03:00
m_cb - > waitTillRealize = false ;
2008-11-25 20:51:44 +02:00
}
2009-08-01 05:57:50 +03:00
void CGeniusAI : : heroKilled ( const CGHeroInstance * hero )
2008-11-25 20:51:44 +02:00
{
2009-08-01 05:57:50 +03:00
2008-11-25 20:51:44 +02:00
}
2009-08-01 05:57:50 +03:00
void CGeniusAI : : heroCreated ( const CGHeroInstance * hero )
2008-11-25 20:51:44 +02:00
{
2009-08-01 05:57:50 +03:00
2008-11-25 20:51:44 +02:00
}
2009-08-04 01:15:13 +03:00
void CGeniusAI : : tileRevealed ( int3 pos )
2008-11-25 20:51:44 +02:00
{
2009-08-04 01:15:13 +03:00
std : : vector < const CGObjectInstance * > objects = m_cb - > getVisitableObjs ( pos ) ;
for ( std : : vector < const CGObjectInstance * > : : iterator o = objects . begin ( ) ; o ! = objects . end ( ) ; o + + )
knownVisitableObjects . insert ( * o ) ;
objects = m_cb - > getFlaggableObjects ( pos ) ;
for ( std : : vector < const CGObjectInstance * > : : iterator o = objects . begin ( ) ; o ! = objects . end ( ) ; o + + )
knownVisitableObjects . insert ( * o ) ;
}
2009-08-01 05:57:50 +03:00
2009-08-04 11:56:38 +03:00
void CGeniusAI : : newObject ( const CGObjectInstance * obj ) //eg. ship built in shipyard
2009-08-04 01:15:13 +03:00
{
2009-08-04 11:56:38 +03:00
knownVisitableObjects . insert ( obj ) ;
}
2009-08-01 05:57:50 +03:00
2009-08-04 11:56:38 +03:00
void CGeniusAI : : objectRemoved ( const CGObjectInstance * obj ) //eg. collected resource, picked artifact, beaten hero
{
std : : set < AIObjectContainer > : : iterator o = knownVisitableObjects . find ( obj ) ;
if ( o ! = knownVisitableObjects . end ( ) )
knownVisitableObjects . erase ( o ) ;
}
void CGeniusAI : : tileHidden ( int3 pos )
{
2008-11-25 20:51:44 +02:00
}
2009-08-04 01:15:13 +03:00
void CGeniusAI : : heroMoved ( const TryMoveHero & TMH )
{
2009-08-04 11:56:38 +03:00
//DbgBox("** CGeniusAI::heroMoved **");
2009-08-04 01:15:13 +03:00
}
2008-11-25 20:51:44 +02:00
void CGeniusAI : : heroGotLevel ( const CGHeroInstance * hero , int pskill , std : : vector < ui16 > & skills , boost : : function < void ( ui32 ) > & callback )
{
callback ( rand ( ) % skills . size ( ) ) ;
}
2009-04-11 04:32:50 +03:00
2009-04-12 03:58:41 +03:00
void GeniusAI : : CGeniusAI : : showGarrisonDialog ( const CArmedInstance * up , const CGHeroInstance * down , boost : : function < void ( ) > & onEnd )
{
onEnd ( ) ;
}
2009-08-04 02:53:18 +03:00
void GeniusAI : : CGeniusAI : : playerBlocked ( int reason )
{
if ( reason = = 0 ) //battle is coming...
{
m_state . setn ( UPCOMING_BATTLE ) ;
}
}
void GeniusAI : : CGeniusAI : : battleResultsApplied ( )
{
assert ( m_state . get ( ) = = ENDING_BATTLE ) ;
m_state . setn ( NO_BATTLE ) ;
}
2009-05-10 11:15:30 +03:00
void CGeniusAI : : showBlockingDialog ( const std : : string & text , const std : : vector < Component > & components , ui32 askID , const int soundID , bool selection , bool cancel )
2009-04-11 04:32:50 +03:00
{
m_cb - > selectionMade ( cancel ? 0 : 1 , askID ) ;
}
2008-11-25 20:51:44 +02:00
/**
* occurs AFTER every action taken by any stack or by the hero
*/
void CGeniusAI : : actionFinished ( const BattleAction * action )
{
std : : string message ( " \t \t CGeniusAI::actionFinished - type( " ) ;
message + = boost : : lexical_cast < std : : string > ( ( unsigned ) action - > actionType ) ;
message + = " ), side( " ;
message + = boost : : lexical_cast < std : : string > ( ( unsigned ) action - > side ) ;
message + = " ) " ;
2009-08-04 01:15:13 +03:00
DbgBox ( message . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
}
/**
* occurs BEFORE every action taken by any stack or by the hero
*/
void CGeniusAI : : actionStarted ( const BattleAction * action )
{
std : : string message ( " \t \t CGeniusAI::actionStarted - type( " ) ;
message + = boost : : lexical_cast < std : : string > ( ( unsigned ) action - > actionType ) ;
message + = " ), side( " ;
message + = boost : : lexical_cast < std : : string > ( ( unsigned ) action - > side ) ;
message + = " ) " ;
2009-08-04 01:15:13 +03:00
DbgBox ( message . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called when stack is performing attack
*/
void CGeniusAI : : battleAttack ( BattleAttack * ba )
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleAttack " ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called when stack receives damage ( after battleAttack ( ) )
*/
2009-03-21 14:49:58 +02:00
void CGeniusAI : : battleStacksAttacked ( std : : set < BattleStackAttacked > & bsa )
2008-11-25 20:51:44 +02:00
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleStacksAttacked " ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called by engine when battle starts ; side = 0 - left , side = 1 - right
*/
2009-08-01 05:57:50 +03:00
2008-11-25 20:51:44 +02:00
void CGeniusAI : : battleStart ( CCreatureSet * army1 , CCreatureSet * army2 , int3 tile , CGHeroInstance * hero1 , CGHeroInstance * hero2 , bool side )
{
2009-08-04 02:53:18 +03:00
assert ( ! m_battleLogic ) ;
assert ( playerID > PLAYER_LIMIT | | m_state . get ( ) = = UPCOMING_BATTLE ) ; //we have been informed that battle will start (or we are neutral AI)
m_state . setn ( ONGOING_BATTLE ) ;
2009-05-10 11:15:30 +03:00
m_battleLogic = new BattleAI : : CBattleLogic ( m_cb , army1 , army2 , tile , hero1 , hero2 , side ) ;
2008-11-25 20:51:44 +02:00
2009-08-04 01:15:13 +03:00
DbgBox ( " ** CGeniusAI::battleStart ** " ) ;
2008-11-25 20:51:44 +02:00
}
/**
*
*/
void CGeniusAI : : battleEnd ( BattleResult * br )
{
2009-08-01 05:57:50 +03:00
/*switch(br->winner)
{
case 0 : std : : cout < < " The winner is the attacker. " < < std : : endl ; break ;
case 1 : std : : cout < < " The winner is the defender. " < < std : : endl ; break ;
case 2 : std : : cout < < " It's a draw. " < < std : : endl ; break ;
} ; */
2008-11-25 20:51:44 +02:00
delete m_battleLogic ;
m_battleLogic = NULL ;
2009-08-04 02:53:18 +03:00
assert ( m_state . get ( ) = = ONGOING_BATTLE ) ;
m_state . setn ( ENDING_BATTLE ) ;
2009-08-04 01:15:13 +03:00
DbgBox ( " ** CGeniusAI::battleEnd ** " ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called at the beggining of each turn , round = - 1 is the tactic phase , round = 0 is the first " normal " turn
*/
void CGeniusAI : : battleNewRound ( int round )
{
std : : string message ( " \t CGeniusAI::battleNewRound - " ) ;
message + = boost : : lexical_cast < std : : string > ( round ) ;
2009-08-04 01:15:13 +03:00
DbgBox ( message . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
m_battleLogic - > SetCurrentTurn ( round ) ;
}
/**
*
*/
2009-03-31 23:47:53 +03:00
void CGeniusAI : : battleStackMoved ( int ID , int dest , int distance , bool end )
2008-11-25 20:51:44 +02:00
{
std : : string message ( " \t \t \t CGeniusAI::battleStackMoved ID( " ) ;
message + = boost : : lexical_cast < std : : string > ( ID ) ;
message + = " ), dest( " ;
message + = boost : : lexical_cast < std : : string > ( dest ) ;
message + = " ) " ;
2009-08-04 01:15:13 +03:00
DbgBox ( message . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
}
/**
*
*/
2009-05-12 06:35:51 +03:00
void CGeniusAI : : battleSpellCast ( SpellCast * sc )
2008-11-25 20:51:44 +02:00
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleSpellCast " ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called when battlefield is prepared , prior the battle beginning
*/
void CGeniusAI : : battlefieldPrepared ( int battlefieldType , std : : vector < CObstacle * > obstacles )
{
2009-08-04 01:15:13 +03:00
DbgBox ( " CGeniusAI::battlefieldPrepared " ) ;
2008-11-25 20:51:44 +02:00
}
/**
*
*/
void CGeniusAI : : battleStackMoved ( int ID , int dest , bool startMoving , bool endMoving )
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleStackMoved " ) ;
2008-11-25 20:51:44 +02:00
}
/**
*
*/
void CGeniusAI : : battleStackAttacking ( int ID , int dest )
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleStackAttacking " ) ;
2008-11-25 20:51:44 +02:00
}
/**
*
*/
void CGeniusAI : : battleStackIsAttacked ( int ID , int dmg , int killed , int IDby , bool byShooting )
{
2009-08-04 01:15:13 +03:00
DbgBox ( " \t \t \t CGeniusAI::battleStackIsAttacked " ) ;
2008-11-25 20:51:44 +02:00
}
/**
* called when it ' s turn of that stack
*/
2009-02-08 17:39:26 +02:00
BattleAction CGeniusAI : : activeStack ( int stackID )
2008-11-25 20:51:44 +02:00
{
std : : string message ( " \t \t \t CGeniusAI::activeStack stackID( " ) ;
2009-02-08 17:39:26 +02:00
2008-11-25 20:51:44 +02:00
message + = boost : : lexical_cast < std : : string > ( stackID ) ;
message + = " ) " ;
2009-08-04 01:15:13 +03:00
DbgBox ( message . c_str ( ) ) ;
2008-11-25 20:51:44 +02:00
return m_battleLogic - > MakeDecision ( stackID ) ;
} ;