From ed9b75b447f45a8826a16af10ea87401bbafdc9d Mon Sep 17 00:00:00 2001 From: red1939 Date: Thu, 22 Oct 2009 22:04:42 +0000 Subject: [PATCH] First part of reformatting the code, renaming variables, rewriting tricky part. Basically making the code more readable, maintainable and ready for further additions. --- AI/GeniusAI/AIPriorities.cpp | 2 +- AI/GeniusAI/AIPriorities.h | 2 +- AI/GeniusAI/BattleHelper.cpp | 2 +- AI/GeniusAI/BattleHelper.h | 2 +- AI/GeniusAI/BattleLogic.cpp | 2 +- AI/GeniusAI/BattleLogic.h | 2 +- AI/GeniusAI/CGeniusAI.cpp | 605 ++++++++++++++++++++++------------- AI/GeniusAI/CGeniusAI.h | 8 +- AI/GeniusAI/DLLMain.cpp | 2 +- AI/GeniusAI/GeneralAI.cpp | 2 +- AI/GeniusAI/GeneralAI.h | 2 +- 11 files changed, 390 insertions(+), 241 deletions(-) diff --git a/AI/GeniusAI/AIPriorities.cpp b/AI/GeniusAI/AIPriorities.cpp index a46396ba3..1db3b5592 100644 --- a/AI/GeniusAI/AIPriorities.cpp +++ b/AI/GeniusAI/AIPriorities.cpp @@ -3,7 +3,7 @@ #define AI_PRIORITIES #include "AIPriorities.h" #include -using namespace GeniusAI; +using namespace geniusai; Network::Network() {} Network::Network(vector whichFeatures)// random network diff --git a/AI/GeniusAI/AIPriorities.h b/AI/GeniusAI/AIPriorities.h index ef0e9442e..b7b6c8189 100644 --- a/AI/GeniusAI/AIPriorities.h +++ b/AI/GeniusAI/AIPriorities.h @@ -5,7 +5,7 @@ #include "CGeniusAI.h" #include "neuralNetwork.h" -namespace GeniusAI { +namespace geniusai { class Network { diff --git a/AI/GeniusAI/BattleHelper.cpp b/AI/GeniusAI/BattleHelper.cpp index e0c263422..07c5d6169 100644 --- a/AI/GeniusAI/BattleHelper.cpp +++ b/AI/GeniusAI/BattleHelper.cpp @@ -7,7 +7,7 @@ #include #include -using namespace GeniusAI::BattleAI; +using namespace geniusai::BattleAI; using namespace std; diff --git a/AI/GeniusAI/BattleHelper.h b/AI/GeniusAI/BattleHelper.h index 63fa1651e..5f68b1c18 100644 --- a/AI/GeniusAI/BattleHelper.h +++ b/AI/GeniusAI/BattleHelper.h @@ -3,7 +3,7 @@ #include "Common.h" -namespace GeniusAI { namespace BattleAI { +namespace geniusai { namespace BattleAI { class CBattleHelper { diff --git a/AI/GeniusAI/BattleLogic.cpp b/AI/GeniusAI/BattleLogic.cpp index bd3bc6776..b661aca61 100644 --- a/AI/GeniusAI/BattleLogic.cpp +++ b/AI/GeniusAI/BattleLogic.cpp @@ -12,7 +12,7 @@ HANDLE handleIn; HANDLE handleOut; #endif -using namespace GeniusAI::BattleAI; +using namespace geniusai::BattleAI; using namespace boost::lambda; using namespace std; diff --git a/AI/GeniusAI/BattleLogic.h b/AI/GeniusAI/BattleLogic.h index 238bde8ac..e2462874a 100644 --- a/AI/GeniusAI/BattleLogic.h +++ b/AI/GeniusAI/BattleLogic.h @@ -15,7 +15,7 @@ using namespace std; -namespace GeniusAI { namespace BattleAI { +namespace geniusai { namespace BattleAI { /** * Class is responsible for making decision during the battle. diff --git a/AI/GeniusAI/CGeniusAI.cpp b/AI/GeniusAI/CGeniusAI.cpp index ae2f6b14b..e4e1595d5 100644 --- a/AI/GeniusAI/CGeniusAI.cpp +++ b/AI/GeniusAI/CGeniusAI.cpp @@ -1,14 +1,17 @@ #include "CGeniusAI.h" -#include "AIPriorities.h" + #include +#include + #include "../../hch/CBuildingHandler.h" #include "../../hch/CHeroHandler.h" #include "../../lib/VCMI_Lib.h" #include "../../lib/NetPacks.h" -#include +#include "AIPriorities.h" -using namespace std; -using namespace GeniusAI; +using std::cout; +using std::endl; +using geniusai::CGeniusAI; #if defined (_MSC_VER) && (_MSC_VER >= 1020) || (__MINGW32__) #define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing @@ -32,77 +35,114 @@ void DbgBox(const char *msg, bool messageBox) } -bool CGeniusAI::AIObjectContainer::operator<(const AIObjectContainer& b)const +bool CGeniusAI::AIObjectContainer::operator<( + const AIObjectContainer& b) const { - if (o->pos!=b.o->pos) - return o->pospos; - return o->idid; + if (o->pos != b.o->pos) + return o->pos < b.o->pos; + else + return o->id < b.o->id; } -CGeniusAI::HypotheticalGameState::HeroModel::HeroModel(const CGHeroInstance * h) -:h(h),finished(false) + +CGeniusAI::HypotheticalGameState::HeroModel::HeroModel( + const CGHeroInstance* h) + : h(h), finished(false) { - pos = h->getPosition(false);remainingMovement = h->movement; + pos = h->getPosition(false); + remainingMovement = h->movement; } -CGeniusAI::HypotheticalGameState::TownModel::TownModel(const CGTownInstance *t):t(t) + +CGeniusAI::HypotheticalGameState::TownModel::TownModel( + const CGTownInstance *t) + : t(t) { hasBuilt = t->builded; creaturesToRecruit = t->creatures; creaturesInGarrison = t->army; } -CGeniusAI::HypotheticalGameState::HypotheticalGameState(CGeniusAI & ai) - :knownVisitableObjects(ai.knownVisitableObjects) + +CGeniusAI::HypotheticalGameState::HypotheticalGameState( + CGeniusAI& ai) + : knownVisitableObjects(ai.knownVisitableObjects) { AI = &ai; - std::vector < const CGHeroInstance *> heroes = ai.m_cb->getHeroesInfo(); - for(std::vector < const CGHeroInstance *>::iterator i = heroes.begin(); i != heroes.end(); i++) + std::vector heroes = ai.m_cb->getHeroesInfo(); + for (std::vector::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++) - if((*i)->tempOwner==ai.m_cb->getMyColor()) - townModels.push_back(TownModel(*i)); + std::vector towns = ai.m_cb->getTownsInfo(); + for (std::vector < const CGTownInstance *>::iterator i = towns.begin(); + i != towns.end(); + i++) { + if ( (*i)->tempOwner == ai.m_cb->getMyColor() ) + townModels.push_back(TownModel(*i)); + } - if(ai.m_cb->howManyTowns()!=0) - AvailableHeroesToBuy = ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + if (ai.m_cb->howManyTowns() != 0) { + AvailableHeroesToBuy = + ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + } - for(int i = 0; i < 8;i++)resourceAmounts.push_back(ai.m_cb->getResourceAmount(i)); + for (int i = 0; i < 8; i++) + resourceAmounts.push_back(ai.m_cb->getResourceAmount(i)); } -void CGeniusAI::HypotheticalGameState::update(CGeniusAI & ai) + +void CGeniusAI::HypotheticalGameState::update(CGeniusAI& ai) { AI = &ai; knownVisitableObjects = ai.knownVisitableObjects; std::vector oldModels = heroModels; heroModels.clear(); - std::vector < const CGHeroInstance *> heroes = ai.m_cb->getHeroesInfo(); - for(std::vector < const CGHeroInstance *>::iterator i = heroes.begin(); i != heroes.end(); i++) + + std::vector heroes = ai.m_cb->getHeroesInfo(); + for (std::vector::iterator i = heroes.begin(); + i != heroes.end(); + i++) heroModels.push_back(HeroModel(*i)); - for(int i = 0; i < oldModels.size();i++) - for(int ii = 0; ii < heroModels.size();ii++) - if(oldModels[i].h->subID==heroModels[ii].h->subID) - { - heroModels[ii].finished = oldModels[i].finished; - heroModels[ii].previouslyVisited_pos=oldModels[i].previouslyVisited_pos; + + for (int i = 0; i < oldModels.size(); i++) { + for (int j = 0; j < heroModels.size(); j++) { + if (oldModels[i].h->subID == heroModels[j].h->subID) { + heroModels[j].finished = oldModels[i].finished; + heroModels[j].previouslyVisited_pos = oldModels[i].previouslyVisited_pos; } + } + } townModels.clear(); - std::vector < const CGTownInstance *> towns = ai.m_cb->getTownsInfo(); - for(std::vector < const CGTownInstance *>::iterator i = towns.begin(); i != towns.end(); i++) - if((*i)->tempOwner==ai.m_cb->getMyColor()) + std::vector towns = ai.m_cb->getTownsInfo(); + for (std::vector::iterator i = towns.begin(); + i != towns.end(); + i++) { + if ( (*i)->tempOwner == ai.m_cb->getMyColor() ) townModels.push_back(TownModel(*i)); + } - if(ai.m_cb->howManyTowns()!=0) - AvailableHeroesToBuy = ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + if (ai.m_cb->howManyTowns() != 0) { + AvailableHeroesToBuy = + ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + } resourceAmounts.clear(); - for(int i = 0; i < 8;i++)resourceAmounts.push_back(ai.m_cb->getResourceAmount(i)); + for (int i = 0; i < 8; i++) + resourceAmounts.push_back(ai.m_cb->getResourceAmount(i)); } -CGeniusAI::HeroObjective::HeroObjective(const HypotheticalGameState &hgs,Type t,const CGObjectInstance * object,HypotheticalGameState::HeroModel *h,CGeniusAI * ai):object(object),hgs(hgs) + +CGeniusAI::HeroObjective::HeroObjective( + const HypotheticalGameState &hgs, + Type t, + const CGObjectInstance* object, + HypotheticalGameState::HeroModel* h, + CGeniusAI* ai) + : object(object), hgs(hgs) { AI = ai; pos = object->pos; @@ -111,228 +151,301 @@ CGeniusAI::HeroObjective::HeroObjective(const HypotheticalGameState &hgs,Type t, _value = -1; } + float CGeniusAI::HeroObjective::getValue() const { - if(_value>=0) - return _value-_cost; + if (_value >= 0) + return _value - _cost; - vector resourceCosts; //TODO: each object should have an associated cost to visit IE (tree of knowledge 1000 gold/10 gems) - for(int i = 0; i < 8;i++) + // TODO: each object should have an associated cost to visit IE + // (tree of knowledge 1000 gold/10 gems) + vector resourceCosts; + for (int i = 0; i < 8; i++) resourceCosts.push_back(0); - if(object->ID==47) //school of magic - resourceCosts[6]+=1000; + + if (object->ID == 47) // School of magic + resourceCosts[6] += 1000; float bestCost = 9e9; - HypotheticalGameState::HeroModel * bestHero = NULL; - if(type !=AIObjective::finishTurn) + HypotheticalGameState::HeroModel* bestHero = NULL; + if (type != AIObjective::finishTurn) { - for(int i = 0; i < whoCanAchieve.size();i++) + for (int i = 0; i < whoCanAchieve.size(); i++) { int distOutOfTheWay = 0; CPath path3; //from hero to object - if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path3)) + if (AI->m_cb->getPath(whoCanAchieve[i]->pos, + pos, + whoCanAchieve[i]->h, + path3)) { distOutOfTheWay+=path3.nodes[0].dist; - //from object to goal - if(AI->m_cb->getPath(pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path3)) - { - distOutOfTheWay+=path3.nodes[0].dist; - //from hero directly to goal - if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path3)) + } + + // from object to goal + if (AI->m_cb->getPath(pos, + whoCanAchieve[i]->interestingPos, + whoCanAchieve[i]->h, + path3)) { + distOutOfTheWay += path3.nodes[0].dist; + // from hero directly to goal + if (AI->m_cb->getPath(whoCanAchieve[i]->pos, + whoCanAchieve[i]->interestingPos, + whoCanAchieve[i]->h, + path3)) distOutOfTheWay-=path3.nodes[0].dist; } - - - - float cost = AI->m_priorities->getCost(resourceCosts,whoCanAchieve[i]->h,distOutOfTheWay); - if(cost < bestCost) - { + float cost = AI->m_priorities->getCost(resourceCosts, + whoCanAchieve[i]->h, + distOutOfTheWay); + if (cost < bestCost) { bestCost = cost; bestHero = whoCanAchieve[i]; } + } // for (int i = 0; i < whoCanAchieve.size(); i++) + } else // if (type != AIObjective::finishTurn) + bestCost = 0; - } - } - else bestCost = 0; - if(bestHero) - { + if (bestHero) { whoCanAchieve.clear(); whoCanAchieve.push_back(bestHero); } _value = AI->m_priorities->getValue(*this); - _cost=bestCost; - return _value-_cost; + _cost = bestCost; + return _value - _cost; } -bool CGeniusAI::HeroObjective::operator < (const HeroObjective &other)const + + +bool CGeniusAI::HeroObjective::operator<( + const HeroObjective& other) const { - if(type != other.type) - return typeid!=other.object->id) + else if (object->id != other.object->id) return object->id < other.object->id; - if(dynamic_cast (object)) - if(whoCanAchieve.front()->h->id!=other.whoCanAchieve.front()->h->id) - return whoCanAchieve.front()->h->idh->id; - return false; + else if (dynamic_cast (object)) { + if (whoCanAchieve.front()->h->id != other.whoCanAchieve.front()->h->id) + return whoCanAchieve.front()->h->id < other.whoCanAchieve.front()->h->id; + } else + return false; } + void CGeniusAI::HeroObjective::print() const { - switch(type) - { + switch (type) { case visit: - cout << "visit " << object->hoverName << " at (" <pos.x << ","<pos.y << ")" ; + cout << "visit " << object->hoverName + << " at (" <pos.x << ","<< object->pos.y << ")" ; break; case attack: cout << "attack " << object->hoverName; break; case finishTurn: cout << "finish turn"; + // TODO: Add a default, just in case. } - if(whoCanAchieve.size()==1) + if (whoCanAchieve.size() == 1) cout << " with " << whoCanAchieve.front()->h->hoverName; } -CGeniusAI::TownObjective::TownObjective(const HypotheticalGameState &hgs,Type t,HypotheticalGameState::TownModel * tn,int Which,CGeniusAI * ai) -:whichTown(tn),which(Which),hgs(hgs) + +CGeniusAI::TownObjective::TownObjective( + const HypotheticalGameState& hgs, + Type t, + HypotheticalGameState::TownModel* tn, + int Which, + CGeniusAI * ai) + : whichTown(tn), which(Which), hgs(hgs) { - AI=ai; + AI = ai; type = t; _value = -1; } float CGeniusAI::TownObjective::getValue() const { - if(_value>=0) - return _value-_cost; - float cost; + if (_value >= 0) + return _value - _cost; + float cost; // TODO: Initialize it! + // TODO: Include a constant stating the meaning of 8 (number of resources). vector resourceCosts(8,0); - CBuilding * b; - CCreature * creature; - int ID,newID, howMany; - switch(type) - { + CBuilding* b; + CCreature* creature; + int ID; + int newID; + int howMany; + ui32 creatures_max = 0; + + switch (type) { case recruitHero: - resourceCosts[6]=2500; + resourceCosts[6] = 2500; // TODO: Define somehow the meaning of gold etc. break; + case buildBuilding: b = VLC->buildh->buildings[whichTown->t->subID][which]; - for(int i = 0; b && i < b->resources.size();i++) - resourceCosts[i]=b->resources[i]; + for (int i = 0; + b && ( i < b->resources.size() ); // TODO: b what?? + i++) + resourceCosts[i] = b->resources[i]; break; - case recruitCreatures: - ID = whichTown->creaturesToRecruit[which].second.back(); //buy upgraded if possible - creature = &VLC->creh->creatures[ID]; - howMany = whichTown->creaturesToRecruit[which].first; - for(int i = 0; i < creature->cost.size();i++) - amin(howMany,creature->cost[i]?hgs.resourceAmounts[i]/creature->cost[i]:INT_MAX); - for(int i = 0; creature && i < creature->cost.size();i++) - resourceCosts[i]=creature->cost[i]*howMany; - + case recruitCreatures: + // Buy upgraded if possible. + ID = whichTown->creaturesToRecruit[which].second.back(); + creature = &VLC->creh->creatures[ID]; + howMany = whichTown->creaturesToRecruit[which].first; + creatures_max = 0; // Max creatures you can recruit of this type. + + for (int i = 0; i < creature->cost.size(); i++) { + if (creature->cost[i] != 0) + creatures_max = hgs.resourceAmounts[i]/creature->cost[i]; + else + creatures_max = INT_MAX; // TODO: Will have to rewrite it. + // TODO: Buy the best units (the least I can buy)? + amin(howMany, creatures_max); + } + // The cost of recruiting the stack of creatures. + for (int i = 0; + creature && ( i < creature->cost.size() ); // TODO: Creature what?? + i++) + resourceCosts[i] = creature->cost[i]*howMany; + break; - break; - case upgradeCreatures: - UpgradeInfo ui = AI->m_cb->getUpgradeInfo(whichTown->t,which); - ID = whichTown->creaturesInGarrison.slots[which].first; - howMany = whichTown->creaturesInGarrison.slots[which].second; - newID = ui.newID.back(); - int upgrade_serial = ui.newID.size()-1; - for (std::set >::iterator j=ui.cost[upgrade_serial].begin(); j!=ui.cost[upgrade_serial].end(); j++) - resourceCosts[j->first] = j->second*howMany; - - break; + case upgradeCreatures: + UpgradeInfo ui = AI->m_cb->getUpgradeInfo(whichTown->t,which); + ID = whichTown->creaturesInGarrison.slots[which].first; + howMany = whichTown->creaturesInGarrison.slots[which].second; + newID = ui.newID.back(); + int upgrade_serial = ui.newID.size() - 1; + for (std::set< std::pair >::iterator + j = ui.cost[upgrade_serial].begin(); + j != ui.cost[upgrade_serial].end(); + j++) + resourceCosts[j->first] = j->second*howMany; + break; } - - - _cost = AI->m_priorities->getCost(resourceCosts,NULL,0); + _cost = AI->m_priorities->getCost(resourceCosts, NULL, 0); _value = AI->m_priorities->getValue(*this); - return _value-_cost; + return _value - _cost; } -bool CGeniusAI::TownObjective::operator < (const TownObjective &other)const +bool CGeniusAI::TownObjective::operator<(const TownObjective &other) const { - if(type != other.type) - return typet->id!=other.whichTown->t->id) + if (type != other.type) + return type < other.type; + else if (which != other.which) + return which < other.which; + else if (whichTown->t->id != other.whichTown->t->id) return whichTown->t->id < other.whichTown->t->id; return false; } + void CGeniusAI::TownObjective::print() const { - CBuilding * b; - const CCreature *creature; + CBuilding* b; + const CCreature* creature; HypotheticalGameState::HeroModel hm; - int ID, howMany, newID, hSlot; - switch(type) - { + int ID; + int howMany; + int newID; + int hSlot; + ui32 creatures_max; + + switch (type) { case recruitHero: - cout << "recruit hero.";break; + cout << "recruit hero."; + break; + case buildBuilding: b = VLC->buildh->buildings[whichTown->t->subID][which]; cout << "build " << b->Name() << " cost = "; - if(b->resources.size()!=0) + if (b->resources.size() != 0) { - if(b->resources[0]!=0)cout << b->resources[0] << " wood. "; - if(b->resources[1]!=0)cout << b->resources[1] << " mercury. "; - if(b->resources[2]!=0)cout << b->resources[2] << " ore. "; - if(b->resources[3]!=0)cout << b->resources[3] << " sulfur. "; - if(b->resources[4]!=0)cout << b->resources[4] << " cristal. "; - if(b->resources[5]!=0)cout << b->resources[5] << " gems. "; - if(b->resources[6]!=0)cout << b->resources[6] << " gold. "; + if (b->resources[0] != 0) + cout << b->resources[0] << " wood. "; + if (b->resources[1] != 0) + cout << b->resources[1] << " mercury. "; + if (b->resources[2] != 0) + cout << b->resources[2] << " ore. "; + if (b->resources[3] != 0) + cout << b->resources[3] << " sulfur. "; + if (b->resources[4] != 0) + cout << b->resources[4] << " cristal. "; + if (b->resources[5] != 0) + cout << b->resources[5] << " gems. "; + if (b->resources[6] != 0) + cout << b->resources[6] << " gold. "; } break; + case recruitCreatures: - ID = whichTown->creaturesToRecruit[which].second.back(); //buy upgraded if possible + // Buy upgraded if possible. + ID = whichTown->creaturesToRecruit[which].second.back(); creature = &VLC->creh->creatures[ID]; howMany = whichTown->creaturesToRecruit[which].first; - for(int i = 0; i < creature->cost.size();i++) - amin(howMany,creature->cost[i]?AI->m_cb->getResourceAmount(i)/creature->cost[i]:INT_MAX); - cout << "recruit " << howMany << " "<< creature->namePl << " (Total AI Strength " << creature->AIValue*howMany << "). cost = "; + creatures_max = 0; + + for (int i = 0; i < creature->cost.size(); i++) { + if (creature->cost[i] != 0) + creatures_max = hgs.resourceAmounts[i]/creature->cost[i]; + else + creatures_max = INT_MAX; + amin(howMany, creatures_max); + } + cout << "recruit " << howMany << " " << creature->namePl + << " (Total AI Strength " << creature->AIValue*howMany << "). cost = "; - if(creature->cost.size()!=0) + if (creature->cost.size() != 0) { - if(creature->cost[0]!=0)cout << creature->cost[0]*howMany << " wood. "; - if(creature->cost[1]!=0)cout << creature->cost[1]*howMany << " mercury. "; - if(creature->cost[2]!=0)cout << creature->cost[2]*howMany << " ore. "; - if(creature->cost[3]!=0)cout << creature->cost[3]*howMany << " sulfur. "; - if(creature->cost[4]!=0)cout << creature->cost[4]*howMany << " cristal. "; - if(creature->cost[5]!=0)cout << creature->cost[5]*howMany << " gems. "; - if(creature->cost[6]!=0)cout << creature->cost[6]*howMany << " gold. "; + if (creature->cost[0] != 0) + cout << creature->cost[0]*howMany << " wood. "; + if (creature->cost[1] != 0) + cout << creature->cost[1]*howMany << " mercury. "; + if (creature->cost[2] != 0) + cout << creature->cost[2]*howMany << " ore. "; + if (creature->cost[3] != 0) + cout << creature->cost[3]*howMany << " sulfur. "; + if (creature->cost[4] != 0) + cout << creature->cost[4]*howMany << " cristal. "; + if (creature->cost[5] != 0) + cout << creature->cost[5]*howMany << " gems. "; + if (creature->cost[6] != 0) + cout << creature->cost[6]*howMany << " gold. "; } break; + case upgradeCreatures: UpgradeInfo ui = AI->m_cb->getUpgradeInfo(whichTown->t,which); ID = whichTown->creaturesInGarrison.slots[which].first; cout << "upgrade " << VLC->creh->creatures[ID].namePl; - //ui.cost - + //ui.cost break; - - } + } // case buildBuilding } -CGeniusAI::CGeniusAI() - : m_generalAI(), m_state(NO_BATTLE) + +CGeniusAI::CGeniusAI() : m_generalAI(), m_state(NO_BATTLE) { m_priorities = new Priorities("AI/GeniusAI.brain"); } + CGeniusAI::~CGeniusAI() { delete m_priorities; } + void CGeniusAI::init(ICallback *CB) { m_cb = CB; @@ -341,7 +454,8 @@ void CGeniusAI::init(ICallback *CB) human = false; playerID = m_cb->getMyColor(); serialID = m_cb->getMySerial(); - std::string info = std::string("GeniusAI initialized for player ") + boost::lexical_cast(playerID); + std::string info = std::string("GeniusAI initialized for player ") + + boost::lexical_cast(playerID); m_battleLogic = NULL; DbgBox(info.c_str()); } @@ -350,8 +464,8 @@ void CGeniusAI::init(ICallback *CB) void CGeniusAI::reportResources() { cout << "Day " << m_cb->getDate() << ": "; - cout << "AI Player " <getMySerial()<< " with " << m_cb->howManyHeroes(true) << " heroes. " << endl; - + cout << "AI Player " <getMySerial()<< " with " + << m_cb->howManyHeroes(true) << " heroes. " << endl; cout << m_cb->getResourceAmount(0) << " wood. "; cout << m_cb->getResourceAmount(1) << " mercury. "; cout << m_cb->getResourceAmount(2) << " ore. "; @@ -362,112 +476,146 @@ void CGeniusAI::reportResources() cout << endl; } -void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h, CGeniusAI::HypotheticalGameState &hgs) + +void CGeniusAI::addHeroObjectives( + CGeniusAI::HypotheticalGameState::HeroModel& h, + CGeniusAI::HypotheticalGameState& hgs) { - int3 hpos, destination; - CPath path; - hpos = h.pos; + int3 hpos = h.pos; + int3 destination; + int3 interestingPos; + CPath path; int movement = h.remainingMovement; - int3 interestingPos; - int maxInteresting=0; + int maxInteresting = 0; AIObjective::Type tp = AIObjective::visit; - if(h.finished) return; - for(std::set::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++) - { + + if (h.finished) + return; + + for (std::set::const_iterator i = + hgs.knownVisitableObjects.begin(); + i != hgs.knownVisitableObjects.end(); + i++) { tp = AIObjective::visit; if( h.previouslyVisited_pos==i->o->getSightCenter()) continue; + //TODO: what would the hero actually visit if he went to that spot - // maybe the hero wants to visit a seemingly unguarded enemy town, but there is a hero on top of it. - //if(i->o->) - if(i->o->ID!=HEROI_TYPE) //unless you are trying to visit a hero - { + // maybe the hero wants to visit a seemingly unguarded enemy town, + // but there is a hero on top of it. + // if(i->o->) + if (i->o->ID != HEROI_TYPE) {// Unless you are trying to visit a hero. bool heroThere = false; - for(int ii = 0; ii < hgs.heroModels.size();ii++) - if(hgs.heroModels[ii].pos==i->o->getSightCenter()) - heroThere = true; - if(heroThere) //it won't work if there is already someone visiting that spot. + for(int j = 0; j < hgs.heroModels.size(); j++) { + if (hgs.heroModels[j].pos == i->o->getSightCenter()) + heroThere = true; + } + if (heroThere) // It won't work if there is already someone visiting that spot. continue; } - if(i->o->ID==HEROI_TYPE&&i->o->getOwner()==m_cb->getMyColor())//visiting friendly heroes not yet supported + if (i->o->ID == HEROI_TYPE && // Visiting friendly heroes not yet supported. + i->o->getOwner() == m_cb->getMyColor()) continue; - if(i->o->id==h.h->id) //don't visit yourself (should be caught by above) + if (i->o->id == h.h->id) // Don't visit yourself (should be caught by above). continue; - - 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). + // Don't visit a mine if you own, there's almost no + // point(maybe to leave guards or because the hero's trapped). + if (i->o->ID == 53 + && i->o->getOwner() == m_cb->getMyColor()) continue; - if(i->o->getOwner()!=m_cb->getMyColor()) - { - int enemyStrength = 0; //TODO: I feel like the AI shouldn't have access to this information. - // We must get an approximation based on few, many, ... zounds etc. - if(dynamic_cast (i->o)) - enemyStrength = (dynamic_cast (i->o))->getArmyStrength();//TODO: should be virtual maybe, Army strength should be comparable across objects - if(dynamic_cast (i->o)) - enemyStrength = (dynamic_cast (i->o))->getTotalStrength(); - if(dynamic_cast (i->o)) - enemyStrength = (dynamic_cast (i->o))->getArmyStrength()*1.2; + if (i->o->getOwner() != m_cb->getMyColor()) { + // TODO: I feel like the AI shouldn't have access to this information. + // We must get an approximation based on few, many, ... zounds etc. + int enemyStrength = 0; + + // TODO: should be virtual maybe, army strength should be + // comparable across objects. + // TODO: Rewrite all those damn i->o. For someone reading it the first + // time it's completely inconprehensible. + if (dynamic_cast (i->o)) + enemyStrength = + (dynamic_cast (i->o))->getArmyStrength(); + if (dynamic_cast (i->o)) + enemyStrength = + (dynamic_cast (i->o))->getTotalStrength(); + // TODO: Make constants of those 1.2 & 2.5. + if (dynamic_cast (i->o)) + enemyStrength = + (dynamic_cast (i->o))->getArmyStrength()*1.2; float heroStrength = h.h->getTotalStrength(); - if(enemyStrength*2.5 > heroStrength) //TODO: ballence these numbers using objective cost formula. - continue; // it would be nice to do a battle sim - if(enemyStrength>0)tp = AIObjective::attack; + // TODO: ballence these numbers using objective cost formula. + // TODO: it would be nice to do a battle simulation. + if (enemyStrength*2.5 > heroStrength) + continue; + + if (enemyStrength > 0) + tp = AIObjective::attack; } - - if(dynamic_cast (i->o)&&dynamic_cast (i->o)->visited)//don't visit things that have already been visited this week. - continue; - if(dynamic_cast (i->o)&&vstd::contains(dynamic_cast (i->o)->visitors,h.h->id))//don't visit things that you have already visited OPH + //don't visit things that have already been visited this week. + if (dynamic_cast (i->o) + && dynamic_cast (i->o)->visited) continue; + //don't visit things that you have already visited OPH + if (dynamic_cast (i->o) + && vstd::contains( + dynamic_cast (i->o)->visitors, + h.h->id)) + continue; - - if(i->o->ID==88||i->o->ID==89||i->o->ID==90) - { + // TODO: Some descriptions of those included so someone can undestand them. + if (i->o->ID == 88 || i->o->ID == 89 || i->o->ID == 90) { //TODO: if no spell book continue //TODO: if the shrine's spell is identified, and the hero already has it, continue - } destination = i->o->getSightCenter(); - if(hpos.z==destination.z) //don't try to take a path from the underworld to the top or vice versa - { //TODO: fix get path so that it doesn't return a path unless z's are the same, or path goes through sub gate - if(m_cb->getPath(hpos,destination,h.h,path)) - { + // Don't try to take a path from the underworld to the top or vice versa. + // TODO: Will have to make some calculations so that the AI can enter the + // underground. + if (hpos.z == destination.z) { + //TODO: fix get path so that it doesn't return a path unless z's are \ + // the same, or path goes through sub gate. + if (m_cb->getPath(hpos, destination, h.h, path)) { path.convert(0); - if(path.nodes[0].disto,&h,this); + if (path.nodes[0].dist < movement) { + // TODO: So easy to understand... + HeroObjective ho(hgs, tp, i->o, &h, this); std::set::iterator found = currentHeroObjectives.find(ho); - if(found==currentHeroObjectives.end()) + if (found == currentHeroObjectives.end()) currentHeroObjectives.insert(ho); else { - HeroObjective *objective = (HeroObjective *)&(*found); + HeroObjective *objective = (HeroObjective*)&(*found); objective->whoCanAchieve.push_back(&h); } } - // find the most interesting object that is eventually reachable, and set that position to the ultimate goal position - int hi = rand(); //TODO: replace random numbers with some sort of ranking system - - if(hi>maxInteresting) - { + // Find the most interesting object that is eventually reachable, + // and set that position to the ultimate goal position. + // TODO: replace random numbers with some sort of ranking system. + int hi = rand(); + if (hi > maxInteresting) { maxInteresting = hi; interestingPos = destination; } - } + } // if (m_cb->getPath(hpos, destination, h.h, path)) + } // if (hpos.z == destination.z) + } // for (std::set::const_iterator i = knownVisitableObjects.begin(); - } - } - h.interestingPos = interestingPos; -// if(h.remainingMovement>0&&m_cb->getPath(hpos,interestingPos,h.h,path)) // there ought to be a path - currentHeroObjectives.insert(HeroObjective(hgs,HeroObjective::finishTurn,h.h,&h,this)); - - + // there ought to be a path + // if(h.remainingMovement>0&&m_cb->getPath(hpos,interestingPos,h.h,path)) + currentHeroObjectives.insert(HeroObjective(hgs, + HeroObjective::finishTurn, + h.h, + &h, + this)); } + void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hgs) { @@ -623,6 +771,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg } + void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, HypotheticalGameState & hgs) { //recruitHero @@ -940,12 +1089,12 @@ void CGeniusAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector callback(rand() % skills.size()); } -void GeniusAI::CGeniusAI::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function &onEnd ) +void geniusai::CGeniusAI::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function &onEnd ) { onEnd(); } -void GeniusAI::CGeniusAI::playerBlocked( int reason ) +void geniusai::CGeniusAI::playerBlocked( int reason ) { if(reason == 0) //battle is coming... { @@ -953,7 +1102,7 @@ void GeniusAI::CGeniusAI::playerBlocked( int reason ) } } -void GeniusAI::CGeniusAI::battleResultsApplied() +void geniusai::CGeniusAI::battleResultsApplied() { assert(m_state.get() == ENDING_BATTLE); m_state.setn(NO_BATTLE); diff --git a/AI/GeniusAI/CGeniusAI.h b/AI/GeniusAI/CGeniusAI.h index 0d4a7f46a..20ed05e62 100644 --- a/AI/GeniusAI/CGeniusAI.h +++ b/AI/GeniusAI/CGeniusAI.h @@ -11,7 +11,7 @@ class CBuilding; -namespace GeniusAI { +namespace geniusai { enum BattleState { @@ -28,9 +28,9 @@ class CGeniusAI : public CGlobalAI { private: ICallback* m_cb; - GeniusAI::BattleAI::CBattleLogic* m_battleLogic; - GeniusAI::GeneralAI::CGeneralAI m_generalAI; - GeniusAI::Priorities * m_priorities; + geniusai::BattleAI::CBattleLogic* m_battleLogic; + geniusai::GeneralAI::CGeneralAI m_generalAI; + geniusai::Priorities * m_priorities; CondSh m_state; //are we engaged into battle? diff --git a/AI/GeniusAI/DLLMain.cpp b/AI/GeniusAI/DLLMain.cpp index 930282f43..f2bd001eb 100644 --- a/AI/GeniusAI/DLLMain.cpp +++ b/AI/GeniusAI/DLLMain.cpp @@ -4,7 +4,7 @@ #include "CGeniusAI.h" -using namespace GeniusAI; +using namespace geniusai; const char *g_cszAiName = "Genius 1.0"; diff --git a/AI/GeniusAI/GeneralAI.cpp b/AI/GeniusAI/GeneralAI.cpp index b36530ac2..47f0d1def 100644 --- a/AI/GeniusAI/GeneralAI.cpp +++ b/AI/GeniusAI/GeneralAI.cpp @@ -1,7 +1,7 @@ #include "GeneralAI.h" #include "../../CCallback.h" -using namespace GeniusAI::GeneralAI; +using namespace geniusai::GeneralAI; CGeneralAI::CGeneralAI() : m_cb(NULL) diff --git a/AI/GeniusAI/GeneralAI.h b/AI/GeniusAI/GeneralAI.h index 6da3d8e84..959b3e871 100644 --- a/AI/GeniusAI/GeneralAI.h +++ b/AI/GeniusAI/GeneralAI.h @@ -3,7 +3,7 @@ #include "Common.h" -namespace GeniusAI { namespace GeneralAI { +namespace geniusai { namespace GeneralAI { class CGeneralAI {