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?
		}
	}
}
Exemple #2
0
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);
	}
}