1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-14 02:33:51 +02:00

AI now attacks randomly.

This commit is contained in:
Trevor Standley 2009-08-04 08:56:38 +00:00
parent f7ce452e5e
commit 45d311a9f5
2 changed files with 186 additions and 128 deletions

View File

@ -1,6 +1,6 @@
#include "CGeniusAI.h" #include "CGeniusAI.h"
#include <iostream> #include <iostream>
#include "../../hch/CBuildingHandler.h"
using namespace std; using namespace std;
using namespace GeniusAI; using namespace GeniusAI;
@ -74,10 +74,11 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
int movement = h.remainingMovement; int movement = h.remainingMovement;
for(std::set<AIObjectContainer>::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++) for(std::set<AIObjectContainer>::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++)
{ {
if(i->o->ID==54||i->o->ID==34) //creatures, another hero // if(i->o->ID==54||i->o->ID==34) //creatures, another hero
continue; // continue;
if(i->o->getOwner()==m_cb->getMyColor()) if(i->o->ID==53) //mine
if(i->o->getOwner()==m_cb->getMyColor())//don't visit if you own, there's almost no point(maybe to leave guards or because the hero's trapped).
continue; continue;
destination = i->o->getSightCenter(); destination = i->o->getSightCenter();
@ -105,8 +106,7 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
//recruitCreatures //recruitCreatures
//upgradeCreatures //upgradeCreatures
//buildBuilding //buildBuilding
if(hgs.heroModels.size()<3&&hgs.resourceAmounts[6]>=2500) //recruitHero
if(hgs.heroModels.size()<3) //recruitHero
{ {
if(!t.visitingHero) if(!t.visitingHero)
{ {
@ -120,43 +120,43 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
} }
} }
/* for(int i = 0; i < t.t->creatures.size() ;i++)
{
if(t.t->creatures[i].second.empty()) continue;
// for(int i = 0; i < t.t->creatures.size() ;i++) int ID = t.t->creatures[i].second.back();
// {
// int ID = t.t->creatures[i].second.back();
// CCreature
// cout << "town has " << t.t->creatures[i].first << " level " << i+1 << " " << creature->namePl << endl;
// }
const CCreature *creature = m_cb->getCCreatureByID(ID);
cout << "town has " << t.t->creatures[i].first << " "<< creature->namePl << " (AI Strength " << creature->AIValue << ")." << endl;
}
//buildBuilding
std::map<int, CBuilding *> thisTownsBuildings = m_cb->getCBuildingsByID(t.t);
for(std::map<int, CBuilding *>::iterator i = thisTownsBuildings.begin(); i != thisTownsBuildings.end();i++)
cout << "structure "<< i->first << ", " << i->second->Name() << ", build?= " << m_cb->canBuildStructure(t.t,i->first) << endl;
*/
} }
void CGeniusAI::TownObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & hgs) void CGeniusAI::TownObjective::fulfill(CGeniusAI & cg,HypotheticalGameState &hgs)
{ {
cg.m_cb->waitTillRealize = true;
switch(type) switch(type)
{ {
case recruitHero: case recruitHero:
cg.m_cb->recruitHero(whichTown->t,hgs.AvailableHeroesToBuy[which]); cg.m_cb->recruitHero(whichTown->t,hgs.AvailableHeroesToBuy[which]);
hgs.heroModels.push_back(hgs.AvailableHeroesToBuy[which]); hgs.heroModels.push_back(hgs.AvailableHeroesToBuy[which]);
whichTown->visitingHero = true; whichTown->visitingHero = true;
//TODO: sub 2500 gold from hgs here //TODO: sub 2500 gold from hgs here
} }
}
void CGeniusAI::getObjectives(CGeniusAI::HypotheticalGameState & hgs)
{
currentHeroObjectives.clear();
currentTownObjectives.clear();
for(std::vector <CGeniusAI::HypotheticalGameState::HeroModel>::iterator i = hgs.heroModels.begin(); i != hgs.heroModels.end(); i++) cg.m_cb->waitTillRealize = false;
addHeroObjectives(*i,hgs);
for(std::vector <CGeniusAI::HypotheticalGameState::TownModel>::iterator i = hgs.townModels.begin(); i != hgs.townModels.end(); i++)
addTownObjectives(*i,hgs);
} }
void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & hgs)
void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hgs)
{ {
cg.m_cb->waitTillRealize = true;
switch(type) switch(type)
{ {
case visit: case visit:
@ -170,8 +170,16 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & h
if(cg.m_cb->getPath(hpos,destination,h->h,path)) if(cg.m_cb->getPath(hpos,destination,h->h,path))
{ {
path.convert(0); path.convert(0);
for(int i = path.nodes.size()-2;i>=0;i--) //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); 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
}
h->remainingMovement-=path.nodes[0].dist; h->remainingMovement-=path.nodes[0].dist;
if(object->blockVisit) if(object->blockVisit)
h->pos = path.nodes[1].coord; h->pos = path.nodes[1].coord;
@ -184,49 +192,64 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & h
} }
cg.m_cb->waitTillRealize = false;
} }
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;
}
void CGeniusAI::yourTurn() void CGeniusAI::yourTurn()
{ {
static int seed = rand(); static int seed = rand();
srand(seed); srand(seed);
if(firstTurn) if(firstTurn)
{ {
//m_cb->sendMessage("vcmieagles"); //m_cb->sendMessage("vcmieagles");
//m_cb->sendMessage("vcmiformenos");
//m_cb->sendMessage("vcmiformenos");
firstTurn = false; firstTurn = false;
} }
//////////////TODO: replace with updates. Also add suspected objects list./////////
knownVisitableObjects.clear(); knownVisitableObjects.clear();
int3 pos = m_cb->getMapSize(); int3 pos = m_cb->getMapSize();
for(int x = 0;x<pos.x;x++) for(int x = 0;x<pos.x;x++)
for(int y = 0;y<pos.y;y++) for(int y = 0;y<pos.y;y++)
for(int z = 0;z<pos.z;z++) for(int z = 0;z<pos.z;z++)
tileRevealed(int3(x,y,z)); tileRevealed(int3(x,y,z));
///////////////////////////////////////////////////////////////////////////////////
reportResources(); // reportResources();
turn++; turn++;
HypotheticalGameState hgs(*this);
getObjectives(hgs);
vector<AIObjectivePtrCont> AIObjectiveQueue;
do{
//std::cout << "I have " << currentHeroObjectives.size() << " things I could do with my heroes!" << std::endl;
//std::cout << "I have " << currentTownObjectives.size() << " things I could do with my towns!" << std::endl;
AIObjectiveQueue.clear();
for(std::set<CGeniusAI::HeroObjective>::iterator i = currentHeroObjectives.begin(); i != currentHeroObjectives.end(); i++)
AIObjectiveQueue.push_back(AIObjectivePtrCont(&(*i)));
for(std::set<CGeniusAI::TownObjective>::iterator i = currentTownObjectives.begin(); i != currentTownObjectives.end(); i++)
AIObjectiveQueue.push_back(AIObjectivePtrCont(&(*i)));
if(!AIObjectiveQueue.empty())
max_element(AIObjectiveQueue.begin(),AIObjectiveQueue.end())->obj->fulfill(*this, hgs);
getObjectives(hgs);
}while(!currentHeroObjectives.empty());
AIObjective * objective;
while((objective = getBestObjective())!=NULL)
objective->fulfill(*this,trueGameState);
seed = rand(); seed = rand();
m_cb->endTurn(); m_cb->endTurn();
@ -252,6 +275,18 @@ void CGeniusAI::tileRevealed(int3 pos)
knownVisitableObjects.insert(*o); knownVisitableObjects.insert(*o);
} }
void CGeniusAI::newObject(const CGObjectInstance * obj) //eg. ship built in shipyard
{
knownVisitableObjects.insert(obj);
}
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) void CGeniusAI::tileHidden(int3 pos)
{ {
@ -259,7 +294,9 @@ void CGeniusAI::tileHidden(int3 pos)
void CGeniusAI::heroMoved(const TryMoveHero &TMH) void CGeniusAI::heroMoved(const TryMoveHero &TMH)
{ {
DbgBox("** CGeniusAI::heroMoved **"); //DbgBox("** CGeniusAI::heroMoved **");
} }
void CGeniusAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) void CGeniusAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)

View File

@ -5,10 +5,15 @@
#include "BattleLogic.h" #include "BattleLogic.h"
#include "GeneralAI.h" #include "GeneralAI.h"
#include "..\..\lib\CondSh.h" #include "..\..\lib\CondSh.h"
#include "../../lib/VCMI_Lib.h" //#include "../../lib/VCMI_Lib.h"
//#include "../../global.h"
//#include "../../client/CGameInfo.h"
#include <set> #include <set>
#include <list> #include <list>
#include <queue> #include <queue>
class CBuilding;
namespace GeniusAI { namespace GeniusAI {
enum BattleState enum BattleState
@ -25,6 +30,9 @@ private:
ICallback* m_cb; ICallback* m_cb;
GeniusAI::BattleAI::CBattleLogic* m_battleLogic; GeniusAI::BattleAI::CBattleLogic* m_battleLogic;
GeniusAI::GeneralAI::CGeneralAI m_generalAI; GeniusAI::GeneralAI::CGeneralAI m_generalAI;
CondSh<BattleState> m_state; //are we engaged into battle?
class AIObjectContainer class AIObjectContainer
{ {
public: public:
@ -37,11 +45,11 @@ private:
return o->id<b.o->id; return o->id<b.o->id;
} }
}; };
std::set< AIObjectContainer > knownVisitableObjects;
class HypotheticalGameState class HypotheticalGameState
{ {
public: public:
HypotheticalGameState(){}
HypotheticalGameState(CGeniusAI & AI) HypotheticalGameState(CGeniusAI & AI)
:knownVisitableObjects(AI.knownVisitableObjects) :knownVisitableObjects(AI.knownVisitableObjects)
{ {
@ -55,6 +63,8 @@ private:
if(AI.m_cb->howManyTowns()!=0) if(AI.m_cb->howManyTowns()!=0)
AvailableHeroesToBuy = AI.m_cb->getAvailableHeroes(AI.m_cb->getTownInfo(0,0)); AvailableHeroesToBuy = AI.m_cb->getAvailableHeroes(AI.m_cb->getTownInfo(0,0));
for(int i = 0; i < 7;i++)resourceAmounts.push_back(AI.m_cb->getResourceAmount(i));
} }
class TownModel class TownModel
@ -75,18 +85,11 @@ private:
const CGHeroInstance * h; const CGHeroInstance * h;
}; };
std::vector<const CGHeroInstance *> AvailableHeroesToBuy; std::vector<const CGHeroInstance *> AvailableHeroesToBuy;
std::vector<int> resourceAmounts;
std::vector<HeroModel> heroModels; std::vector<HeroModel> heroModels;
std::vector<TownModel> townModels; std::vector<TownModel> townModels;
std::set< AIObjectContainer > knownVisitableObjects; std::set< AIObjectContainer > knownVisitableObjects;
}; };
void addHeroObjectives(HypotheticalGameState::HeroModel &h, HypotheticalGameState & hgs);
void addTownObjectives(HypotheticalGameState::TownModel &h, HypotheticalGameState & hgs);
void getObjectives(HypotheticalGameState & hgs);
void reportResources();
int turn;
CondSh<BattleState> m_state; //are we engaged into battle?
bool firstTurn;
class AIObjective class AIObjective
{ {
@ -112,6 +115,7 @@ private:
//virtual bool operator < (const AIObjective &)const=0; //virtual bool operator < (const AIObjective &)const=0;
//virtual bool stillPossible(const HypotheticalGameState &)const = 0; //virtual bool stillPossible(const HypotheticalGameState &)const = 0;
virtual void fulfill(CGeniusAI &,HypotheticalGameState & hgs)=0; virtual void fulfill(CGeniusAI &,HypotheticalGameState & hgs)=0;
virtual HypotheticalGameState pretend(const HypotheticalGameState &) =0;
virtual float getValue() const=0; //how much is it worth to the AI to achieve virtual float getValue() const=0; //how much is it worth to the AI to achieve
}; };
@ -141,8 +145,8 @@ private:
return object->id < other.object->id; return object->id < other.object->id;
return false; return false;
} }
//bool stillPossible(const HypotheticalGameState &) const;
void fulfill(CGeniusAI &,HypotheticalGameState & hgs); void fulfill(CGeniusAI &,HypotheticalGameState & hgs);
HypotheticalGameState pretend(const HypotheticalGameState &hgs){return hgs;};
float getValue() const{return _value;} float getValue() const{return _value;}
private: private:
float _value; float _value;
@ -171,6 +175,7 @@ private:
return false; return false;
} }
void fulfill(CGeniusAI &,HypotheticalGameState & hgs); void fulfill(CGeniusAI &,HypotheticalGameState & hgs);
HypotheticalGameState pretend(const HypotheticalGameState &hgs){return hgs;};
float getValue() const {return _value;} float getValue() const {return _value;}
private: private:
float _value; float _value;
@ -186,8 +191,19 @@ private:
{return obj->getValue()<other.obj->getValue();} {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();
int turn;
bool firstTurn;
std::set< AIObjectContainer > knownVisitableObjects;
std::set<HeroObjective> currentHeroObjectives; //can be fulfilled right now std::set<HeroObjective> currentHeroObjectives; //can be fulfilled right now
std::set<TownObjective> currentTownObjectives; std::set<TownObjective> currentTownObjectives;
std::vector<AIObjectivePtrCont> objectiveQueue;
public: public:
CGeniusAI(); CGeniusAI();
@ -206,6 +222,11 @@ public:
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback); 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 showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
virtual void playerBlocked(int reason); 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 // battle
virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero 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 actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero