int3 whereToExplore(HeroPtr h) { //TODO it's stupid and ineffective, write sth better cb->setSelection(*h); int radius = h->getSightRadious(); int3 hpos = h->visitablePos(); //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)) { int3 op = obj->visitablePos(); CGPath p; cb->getPath2(op, p); if(p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT) nearbyVisitableObjs.push_back(obj); } boost::sort(nearbyVisitableObjs, isCloser); if(nearbyVisitableObjs.size()) return nearbyVisitableObjs.back()->visitablePos(); try { return ai->explorationBestNeighbour(hpos, radius, h); } catch(cannotFulfillGoalException &e) { std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow] try { return ai->explorationNewPoint(radius, h, tiles); } catch(cannotFulfillGoalException &e) { std::map<int, std::vector<int3> > profits; { TimeCheck tc("Evaluating exploration possibilities"); tiles[0].clear(); //we can't reach FoW anyway for(auto &vt : tiles) for(auto &tile : vt) profits[howManyTilesWillBeDiscovered(tile, radius)].push_back(tile); } if(profits.empty()) return int3 (-1,-1,-1); auto bestDest = profits.end(); bestDest--; return bestDest->second.front(); //TODO which is the real best tile? } } }
int3 whereToExplore(HeroPtr h) { TimeCheck tc ("where to explore"); int radius = h->getSightRadious(); int3 hpos = h->visitablePos(); SectorMap sm(h); //look for nearby objs -> visit them if they're close enouh const int DIST_LIMIT = 3; std::vector<const CGObjectInstance *> nearbyVisitableObjs; for (int x = hpos.x - DIST_LIMIT; x <= hpos.x + 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; ai->myCb->getPathsInfo(h.get())->getPath(op, p); if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT) if (ai->isGoodForVisit(obj, h, sm)) nearbyVisitableObjs.push_back(obj); } } } vstd::removeDuplicates (nearbyVisitableObjs); //one object may occupy multiple tiles boost::sort(nearbyVisitableObjs, CDistanceSorter(h.get())); if(nearbyVisitableObjs.size()) return nearbyVisitableObjs.back()->visitablePos(); try //check if nearby tiles allow us to reveal anything - this is quick { return ai->explorationBestNeighbour(hpos, radius, h); } catch(cannotFulfillGoalException &e) { //perform exhaustive search return ai->explorationNewPoint(h); } }