1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Dramatically reduced exploration complexity. AI will check only nearby objects.

This commit is contained in:
DjWarmonger
2013-12-21 19:17:27 +00:00
parent 473250e223
commit a6ce282f8a
3 changed files with 39 additions and 26 deletions

View File

@@ -213,6 +213,7 @@ bool canBeEmbarkmentPoint(const TerrainTile *t)
int3 whereToExplore(HeroPtr h)
{
TimeCheck tc ("where to explore");
//TODO it's stupid and ineffective, write sth better
cb->setSelection(*h);
int radius = h->getSightRadious();
@@ -221,14 +222,21 @@ int3 whereToExplore(HeroPtr h)
//look for nearby objs -> visit them if they're close enouh
const int DIST_LIMIT = 3;
std::vector<const CGObjectInstance *> nearbyVisitableObjs;
for(const CGObjectInstance *obj : ai->getPossibleDestinations(h))
for (int x = hpos.x - DIST_LIMIT; x <= hpos.y + DIST_LIMIT; ++x) //get only local objects instead of all possible objects on the map
{
for (int y = hpos.y - DIST_LIMIT; y <= hpos.y + DIST_LIMIT; ++y)
{
for (auto obj : cb->getVisitableObjs (int3(x,y,hpos.z), false))
{
int3 op = obj->visitablePos();
CGPath p;
cb->getPath2(op, p);
if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
if (ai->isGoodForVisit(obj, h))
nearbyVisitableObjs.push_back(obj);
}
}
}
boost::sort(nearbyVisitableObjs, isCloser);
if(nearbyVisitableObjs.size())
return nearbyVisitableObjs.back()->visitablePos();

View File

@@ -1090,11 +1090,7 @@ void VCAI::buildStructure(const CGTownInstance * t)
return;
}
std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
{
validateVisitableObjs();
std::vector<const CGObjectInstance *> possibleDestinations;
for(const CGObjectInstance *obj : visitableObjs)
bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h)
{
const int3 pos = obj->visitablePos();
if (isAccessibleForHero(obj->visitablePos(), h) &&
@@ -1104,21 +1100,31 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
shouldVisit(h, obj) &&
!vstd::contains(alreadyVisited, obj) &&
!vstd::contains(reservedObjs, obj))
{
possibleDestinations.push_back(obj);
}
}
possibleDestinations.erase(boost::remove_if(possibleDestinations, [&](const CGObjectInstance *obj) -> bool
{
const CGObjectInstance *topObj = cb->getVisitableObjs(obj->visitablePos()).back(); //it may be hero visiting this obj
//we don't try visiting object on which allied or owned hero stands
// -> it will just trigger exchange windows and AI will be confused that obj behind doesn't get visited
if (topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES)
return true;
return false;
else
return true; //all of the following is met
}
return false;
}), possibleDestinations.end());
}
std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
{
validateVisitableObjs();
std::vector<const CGObjectInstance *> possibleDestinations;
for(const CGObjectInstance *obj : visitableObjs)
{
const int3 pos = obj->visitablePos();
if (isGoodForVisit(obj, h))
{
possibleDestinations.push_back(obj);
}
}
boost::sort(possibleDestinations, isCloser);
@@ -1995,7 +2001,6 @@ void VCAI::buildArmyIn(const CGTownInstance * t)
int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
{
TimeCheck tc("looking for best exploration neighbour");
std::map<int3, int> dstToRevealedTiles;
for(crint3 dir : dirs)
if(cb->isInTheMap(hpos+dir))
@@ -2019,7 +2024,6 @@ int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
int3 VCAI::explorationNewPoint(int radius, HeroPtr h, std::vector<std::vector<int3> > &tiles)
{
TimeCheck tc("looking for new exploration point");
logAi->debugStream() << "Looking for an another place for exploration...";
tiles.resize(radius);

View File

@@ -241,6 +241,7 @@ public:
void striveToQuest (const QuestInfo &q);
void recruitHero(const CGTownInstance * t, bool throwing = false);
bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h);
std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);
void buildStructure(const CGTownInstance * t);
//void recruitCreatures(const CGTownInstance * t);