AIhelper should be owned by AI instance.

This commit is contained in:
AlexVinS
2018-09-02 18:04:38 +03:00
parent edcaaf036a
commit 99f167a44c
5 changed files with 29 additions and 31 deletions
-2
View File
@@ -13,8 +13,6 @@
#include "ResourceManager.h"
#include "BuildingManager.h"
boost::thread_specific_ptr<AIhelper> ah;
AIhelper::AIhelper()
{
resourceManager.reset(new ResourceManager());
-2
View File
@@ -27,11 +27,9 @@ class DLL_EXPORT AIhelper : public IResourceManager, public IBuildingManager
friend class VCAI;
friend struct SetGlobalState; //mess?
//members are thread_specific. AIhelper is global
std::shared_ptr<ResourceManager> resourceManager;
std::shared_ptr<BuildingManager> buildingManager;
//TODO: vector<IAbstractManager>
std::shared_ptr<VCAI> ai;
public:
AIhelper();
~AIhelper();
+15 -16
View File
@@ -21,7 +21,6 @@
extern boost::thread_specific_ptr<CCallback> cb;
extern boost::thread_specific_ptr<VCAI> ai;
extern boost::thread_specific_ptr<AIhelper> ah;
extern FuzzyHelper * fh;
using namespace Goals;
@@ -280,7 +279,7 @@ namespace Goals
//TODO: calculate the actual cost of units instead
TResources price;
price[Res::GOLD] = value * 0.4f; //some approximate value
return ah->whatToDo(price, iAmElementar()); //buy right now or gather resources
return ai->ah->whatToDo(price, iAmElementar()); //buy right now or gather resources
}
std::string BuyArmy::completeMessage() const
{
@@ -924,7 +923,7 @@ TSubgoal RecruitHero::whatToDoToAchieve()
TResources res;
res[Res::GOLD] = GameConstants::HERO_GOLD_COST;
return ah->whatToDo(res, iAmElementar()); //either buy immediately, or collect res
return ai->ah->whatToDo(res, iAmElementar()); //either buy immediately, or collect res
}
bool Goals::RecruitHero::operator==(AbstractGoal & g)
@@ -1058,7 +1057,7 @@ TSubgoal BuildThis::whatToDoToAchieve()
case EBuildingState::NO_RESOURCES:
{
auto res = town->town->buildings.at(BuildingID(bid))->resources;
return ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources
return ai->ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources
}
break;
default:
@@ -1142,7 +1141,7 @@ TGoalVec Goals::CollectRes::getAllPossibleSubgoals()
}
for (auto obj : ourObjs)
{
auto pos = obj->visitablePos();
auto pos = obj->visitablePos();
if (ai->isTileNotReserved(h, pos)) //further decomposition and evaluation will be handled by VisitObj
ret.push_back(sptr(Goals::VisitObj(obj->id.getNum()).sethero(h).setisAbstract(true)));
}
@@ -1215,7 +1214,7 @@ TSubgoal Goals::CollectRes::whatToDoToTrade()
int toGive = -1, toReceive = -1;
m->getOffer(i, resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
assert(toGive > 0 && toReceive > 0);
howManyCanWeBuy += toReceive * (ah->freeResources()[i] / toGive);
howManyCanWeBuy += toReceive * (ai->ah->freeResources()[i] / toGive);
}
if (howManyCanWeBuy >= value)
@@ -1296,7 +1295,7 @@ TSubgoal GatherTroops::whatToDoToAchieve()
{
for(auto type : creature.second)
{
if(type == objid && ah->freeResources().canAfford(VLC->creh->creatures[type]->cost))
if(type == objid && ai->ah->freeResources().canAfford(VLC->creh->creatures[type]->cost))
dwellings.push_back(d);
}
}
@@ -1438,19 +1437,19 @@ TGoalVec Goals::Build::getAllPossibleSubgoals()
for (const CGTownInstance * t : cb->getTownsInfo())
{
//start fresh with every town
ah->getBuildingOptions(t);
auto ib = ah->immediateBuilding();
ai->ah->getBuildingOptions(t);
auto ib = ai->ah->immediateBuilding();
if (ib.is_initialized())
{
ret.push_back(sptr(Goals::BuildThis(ib.get().bid, t).setpriority(2))); //prioritize buildings we can build quick
}
else //try build later
{
auto eb = ah->expensiveBuilding();
auto eb = ai->ah->expensiveBuilding();
if (eb.is_initialized())
{
auto pb = eb.get(); //gather resources for any we can't afford
auto goal = ah->whatToDo(pb.price, sptr(Goals::BuildThis(pb.bid, t).setpriority(0.5)));
auto goal = ai->ah->whatToDo(pb.price, sptr(Goals::BuildThis(pb.bid, t).setpriority(0.5)));
ret.push_back(goal);
}
}
@@ -1520,18 +1519,18 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
if (val)
{
auto goal = sptr(Goals::BuyArmy(t, val).sethero(hero));
if (!ah->containsObjective(goal)) //avoid loops caused by reserving same objective twice
if (!ai->ah->containsObjective(goal)) //avoid loops caused by reserving same objective twice
ret.push_back(goal);
}
}
//build dwelling
//TODO: plan building over multiple turns?
//auto bid = ah->canBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK));
auto bid = ah->canBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 1);
auto bid = ai->ah->canBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 1);
if (bid.is_initialized())
{
auto goal = sptr(BuildThis(bid.get(), t).setpriority(priority));
if (!ah->containsObjective(goal)) //avoid loops caused by reserving same objective twice
if (!ai->ah->containsObjective(goal)) //avoid loops caused by reserving same objective twice
ret.push_back(goal);
}
}
@@ -1580,7 +1579,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
for(auto & creatureID : creLevel.second)
{
auto creature = VLC->creh->creatures[creatureID];
if(ah->freeResources().canAfford(creature->cost))
if(ai->ah->freeResources().canAfford(creature->cost))
objs.push_back(obj); //TODO: reserve resources?
}
}
@@ -1600,7 +1599,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
}
}
if(ai->canRecruitAnyHero() && ah->freeGold() > GameConstants::HERO_GOLD_COST) //this is not stupid in early phase of game
if(ai->canRecruitAnyHero() && ai->ah->freeGold() > GameConstants::HERO_GOLD_COST) //this is not stupid in early phase of game
{
if(auto t = ai->findTownWithTavern())
{
+10 -11
View File
@@ -35,7 +35,6 @@ const double SAFE_ATTACK_CONSTANT = 1.5;
//one thread may be turn of AI and another will be handling a side effect for AI2
boost::thread_specific_ptr<CCallback> cb;
boost::thread_specific_ptr<VCAI> ai;
extern boost::thread_specific_ptr<AIhelper> ah;
//std::map<int, std::map<int, int> > HeroView::infosCount;
@@ -49,10 +48,6 @@ struct SetGlobalState
ai.reset(AI);
cb.reset(AI->myCb.get());
if (!ah.get())
ah.reset(new AIhelper());
ah->setAI(AI); //does this make any sense?
ah->setCB(cb.get());
}
~SetGlobalState()
{
@@ -100,10 +95,14 @@ VCAI::VCAI()
makingTurn = nullptr;
destinationTeleport = ObjectInstanceID();
destinationTeleportPos = int3(-1);
ah = new AIhelper();
ah->setAI(this);
}
VCAI::~VCAI()
{
delete ah;
LOG_TRACE(logAi);
finish();
}
@@ -447,7 +446,7 @@ void VCAI::objectRemoved(const CGObjectInstance * obj)
for(auto goal : ultimateGoalsFromBasic)
vstd::erase_if(goal.second, goalErasePredicate);
//TODO: Find better way to handle hero boat removal
if(auto hero = dynamic_cast<const CGHeroInstance *>(obj))
{
@@ -614,7 +613,7 @@ void VCAI::init(std::shared_ptr<CCallback> CB)
myCb = CB;
cbc = CB;
ah.reset(new AIhelper());
ah->setCB(CB.get());
NET_EVENT_HANDLER; //sets ah->rm->cb
playerID = *myCb->getMyColor();
@@ -1494,7 +1493,7 @@ void VCAI::wander(HeroPtr h)
//end of objs empty
if(dests.size()) //performance improvement
{
{
Goals::TGoalVec targetObjectGoals;
for(auto destination : dests)
{
@@ -3083,7 +3082,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
case Obj::SCHOOL_OF_MAGIC:
case Obj::SCHOOL_OF_WAR:
{
if (ah->freeGold() < 1000)
if (ai->ah->freeGold() < 1000)
return false;
break;
}
@@ -3093,7 +3092,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
break;
case Obj::TREE_OF_KNOWLEDGE:
{
TResources myRes = ah->freeResources();
TResources myRes = ai->ah->freeResources();
if(myRes[Res::GOLD] < 2000 || myRes[Res::GEMS] < 10)
return false;
break;
@@ -3108,7 +3107,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
//TODO: only on request
if(ai->myCb->getHeroesInfo().size() >= VLC->modh->settings.MAX_HEROES_ON_MAP_PER_PLAYER)
return false;
else if(ah->freeGold() < GameConstants::HERO_GOLD_COST)
else if(ai->ah->freeGold() < GameConstants::HERO_GOLD_COST)
return false;
break;
}
+4
View File
@@ -28,6 +28,8 @@
struct QuestInfo;
class AIhelper;
class AIStatus
{
boost::mutex mx;
@@ -114,6 +116,8 @@ public:
std::unique_ptr<boost::thread> makingTurn;
AIhelper * ah;
VCAI();
virtual ~VCAI();