mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-17 11:56:46 +02:00
Cache SectorMap where possible and update when necessary.
This commit is contained in:
parent
c9e03405f2
commit
1e36f3cecd
@ -359,7 +359,7 @@ int3 whereToExplore(HeroPtr h)
|
||||
int radius = h->getSightRadious();
|
||||
int3 hpos = h->visitablePos();
|
||||
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = ai->getCachedSectorMap(h);
|
||||
|
||||
//look for nearby objs -> visit them if they're close enouh
|
||||
const int DIST_LIMIT = 3;
|
||||
|
@ -302,7 +302,7 @@ Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
||||
if (vec.empty()) //no possibilities found
|
||||
return sptr(Goals::Invalid());
|
||||
|
||||
cachedSectorMaps.clear();
|
||||
ai->cachedSectorMaps.clear();
|
||||
|
||||
//a trick to switch between heroes less often - calculatePaths is costly
|
||||
auto sortByHeroes = [](const Goals::TSubgoal & lhs, const Goals::TSubgoal & rhs) -> bool
|
||||
@ -482,7 +482,7 @@ float FuzzyHelper::evaluate (Goals::ClearWayTo & g)
|
||||
if (!g.hero.h)
|
||||
throw cannotFulfillGoalException("ClearWayTo called without hero!");
|
||||
|
||||
int3 t = getCachedSectorMap(g.hero).firstTileToGet(g.hero, g.tile);
|
||||
int3 t = ai->getCachedSectorMap(g.hero).firstTileToGet(g.hero, g.tile);
|
||||
|
||||
if (t.valid())
|
||||
{
|
||||
@ -530,16 +530,4 @@ float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
|
||||
void FuzzyHelper::setPriority (Goals::TSubgoal & g)
|
||||
{
|
||||
g->setpriority(g->accept(this)); //this enforces returned value is set
|
||||
}
|
||||
|
||||
SectorMap& FuzzyHelper::getCachedSectorMap(HeroPtr h)
|
||||
{
|
||||
auto it = cachedSectorMaps.find(h);
|
||||
if (it != cachedSectorMaps.end())
|
||||
return it->second;
|
||||
else
|
||||
{
|
||||
cachedSectorMaps.insert (std::make_pair(h, SectorMap(h)));
|
||||
return cachedSectorMaps[h];
|
||||
}
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@ class FuzzyHelper
|
||||
~EvalVisitTile();
|
||||
} vt;
|
||||
|
||||
std::map <HeroPtr, SectorMap> cachedSectorMaps;
|
||||
|
||||
|
||||
public:
|
||||
enum RuleBlocks {BANK_DANGER, TACTICAL_ADVANTAGE, VISIT_TILE};
|
||||
@ -84,7 +84,4 @@ public:
|
||||
|
||||
Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
|
||||
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec);
|
||||
|
||||
//optimization - use one SM for every hero call
|
||||
SectorMap& getCachedSectorMap (HeroPtr h);
|
||||
};
|
||||
|
@ -483,7 +483,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
|
||||
//if our hero is trapped, make sure we request clearing the way from OUR perspective
|
||||
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = ai->getCachedSectorMap(h);
|
||||
|
||||
int3 tileToHit = sm.firstTileToGet(h, tile);
|
||||
if (!tileToHit.valid())
|
||||
@ -633,7 +633,7 @@ TGoalVec Explore::getAllPossibleSubgoals()
|
||||
|
||||
for (auto h : heroes)
|
||||
{
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = ai->getCachedSectorMap(h);
|
||||
|
||||
for (auto obj : objs) //double loop, performance risk?
|
||||
{
|
||||
@ -963,7 +963,7 @@ TGoalVec Conquer::getAllPossibleSubgoals()
|
||||
|
||||
for (auto h : cb->getHeroesInfo())
|
||||
{
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = ai->getCachedSectorMap(h);
|
||||
std::vector<const CGObjectInstance *> ourObjs(objs); //copy common objects
|
||||
|
||||
for (auto obj : ai->reservedHeroesMap[h]) //add objects reserved by this hero
|
||||
@ -1093,7 +1093,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
|
||||
}
|
||||
for(auto h : cb->getHeroesInfo())
|
||||
{
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = ai->getCachedSectorMap(h);
|
||||
for (auto obj : objs)
|
||||
{ //find safe dwelling
|
||||
auto pos = obj->visitablePos();
|
||||
|
@ -115,6 +115,7 @@ void VCAI::heroMoved(const TryMoveHero & details)
|
||||
NET_EVENT_HANDLER;
|
||||
|
||||
validateObject(details.id); //enemy hero may have left visible area
|
||||
cachedSectorMaps.clear();
|
||||
|
||||
if(details.result == TryMoveHero::TELEPORTATION)
|
||||
{
|
||||
@ -296,7 +297,7 @@ void VCAI::tileRevealed(const std::unordered_set<int3, ShashInt3> &pos)
|
||||
for(const CGObjectInstance *obj : myCb->getVisitableObjs(tile))
|
||||
addVisitableObj(obj);
|
||||
|
||||
clearHeroesUnableToExplore();
|
||||
clearPathsInfo();
|
||||
}
|
||||
|
||||
void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
|
||||
@ -382,7 +383,7 @@ void VCAI::newObject(const CGObjectInstance * obj)
|
||||
if(obj->isVisitable())
|
||||
addVisitableObj(obj);
|
||||
|
||||
clearHeroesUnableToExplore();
|
||||
cachedSectorMaps.clear();
|
||||
}
|
||||
|
||||
void VCAI::objectRemoved(const CGObjectInstance *obj)
|
||||
@ -396,6 +397,8 @@ void VCAI::objectRemoved(const CGObjectInstance *obj)
|
||||
for (auto h : cb->getHeroesInfo())
|
||||
unreserveObject(h, obj);
|
||||
|
||||
cachedSectorMaps.clear(); //invalidate all paths
|
||||
|
||||
//TODO
|
||||
//there are other places where CGObjectinstance ptrs are stored...
|
||||
//
|
||||
@ -840,7 +843,7 @@ void VCAI::makeTurnInternal()
|
||||
bool VCAI::goVisitObj(const CGObjectInstance * obj, HeroPtr h)
|
||||
{
|
||||
int3 dst = obj->visitablePos();
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = getCachedSectorMap(h);
|
||||
logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getObjectName() % strFromInt3(dst);
|
||||
int3 pos = sm.firstTileToGet(h, dst);
|
||||
if (!pos.valid()) //rare case when we are already standing on one of potential objects
|
||||
@ -1378,7 +1381,7 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
|
||||
{
|
||||
validateVisitableObjs();
|
||||
std::vector<const CGObjectInstance *> possibleDestinations;
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = getCachedSectorMap(h);
|
||||
for(const CGObjectInstance *obj : visitableObjs)
|
||||
{
|
||||
if (isGoodForVisit(obj, h, sm))
|
||||
@ -1436,7 +1439,7 @@ void VCAI::wander(HeroPtr h)
|
||||
validateVisitableObjs();
|
||||
std::vector <ObjectIdRef> dests, tmp;
|
||||
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = getCachedSectorMap(h);
|
||||
|
||||
range::copy(reservedHeroesMap[h], std::back_inserter(tmp)); //also visit our reserved objects - but they are not prioritized to avoid running back and forth
|
||||
for (auto obj : tmp)
|
||||
@ -1649,9 +1652,10 @@ bool VCAI::isAbleToExplore (HeroPtr h)
|
||||
{
|
||||
return !vstd::contains (heroesUnableToExplore, h);
|
||||
}
|
||||
void VCAI::clearHeroesUnableToExplore()
|
||||
void VCAI::clearPathsInfo()
|
||||
{
|
||||
heroesUnableToExplore.clear();
|
||||
cachedSectorMaps.clear();
|
||||
}
|
||||
|
||||
void VCAI::validateVisitableObjs()
|
||||
@ -2533,8 +2537,7 @@ int3 VCAI::explorationNewPoint(HeroPtr h)
|
||||
|
||||
int3 VCAI::explorationDesperate(HeroPtr h)
|
||||
{
|
||||
//logAi->debugStream() << "Looking for an another place for exploration...";
|
||||
SectorMap sm(h);
|
||||
SectorMap &sm = getCachedSectorMap(h);
|
||||
int radius = h->getSightRadious();
|
||||
|
||||
std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow]
|
||||
@ -2691,6 +2694,7 @@ void VCAI::lostHero(HeroPtr h)
|
||||
erase_if_present(reservedObjs, obj); //unreserve all objects for that hero
|
||||
}
|
||||
erase_if_present(reservedHeroesMap, h);
|
||||
erase_if_present(cachedSectorMaps, h);
|
||||
}
|
||||
|
||||
void VCAI::answerQuery(QueryID queryID, int selection)
|
||||
@ -2751,6 +2755,18 @@ TResources VCAI::freeResources() const
|
||||
return myRes;
|
||||
}
|
||||
|
||||
SectorMap& VCAI::getCachedSectorMap(HeroPtr h)
|
||||
{
|
||||
auto it = cachedSectorMaps.find(h);
|
||||
if (it != cachedSectorMaps.end())
|
||||
return it->second;
|
||||
else
|
||||
{
|
||||
cachedSectorMaps.insert(std::make_pair(h, SectorMap(h)));
|
||||
return cachedSectorMaps[h];
|
||||
}
|
||||
}
|
||||
|
||||
AIStatus::AIStatus()
|
||||
{
|
||||
battle = NO_BATTLE;
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
std::set<const CGObjectInstance *> alreadyVisited;
|
||||
std::set<const CGObjectInstance *> reservedObjs; //to be visited by specific hero
|
||||
|
||||
std::map <HeroPtr, SectorMap> cachedSectorMaps; //TODO: serialize? not necessary
|
||||
|
||||
TResources saving;
|
||||
|
||||
AIStatus status;
|
||||
@ -296,7 +298,7 @@ public:
|
||||
void markHeroUnableToExplore (HeroPtr h);
|
||||
void markHeroAbleToExplore (HeroPtr h);
|
||||
bool isAbleToExplore (HeroPtr h);
|
||||
void clearHeroesUnableToExplore();
|
||||
void clearPathsInfo();
|
||||
|
||||
void validateObject(const CGObjectInstance *obj); //checks if object is still visible and if not, removes references to it
|
||||
void validateObject(ObjectIdRef obj); //checks if object is still visible and if not, removes references to it
|
||||
@ -311,6 +313,8 @@ public:
|
||||
|
||||
const CGObjectInstance *getUnvisitedObj(const std::function<bool(const CGObjectInstance *)> &predicate);
|
||||
bool isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies = false) const;
|
||||
//optimization - use one SM for every hero call
|
||||
SectorMap& getCachedSectorMap(HeroPtr h);
|
||||
|
||||
const CGTownInstance *findTownWithTavern() const;
|
||||
bool canRecruitAnyHero(const CGTownInstance * t = NULL) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user