Browse Source

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

DjWarmonger 12 years ago
parent
commit
a6ce282f8a
3 changed files with 39 additions and 26 deletions
  1. 14 6
      AI/VCAI/AIUtility.cpp
  2. 24 20
      AI/VCAI/VCAI.cpp
  3. 1 0
      AI/VCAI/VCAI.h

+ 14 - 6
AI/VCAI/AIUtility.cpp

@@ -213,6 +213,7 @@ bool canBeEmbarkmentPoint(const TerrainTile *t)
 
 
 int3 whereToExplore(HeroPtr h)
 int3 whereToExplore(HeroPtr h)
 {
 {
+	TimeCheck tc ("where to explore");
 	//TODO it's stupid and ineffective, write sth better
 	//TODO it's stupid and ineffective, write sth better
 	cb->setSelection(*h);
 	cb->setSelection(*h);
 	int radius = h->getSightRadious();
 	int radius = h->getSightRadious();
@@ -221,13 +222,20 @@ int3 whereToExplore(HeroPtr h)
 	//look for nearby objs -> visit them if they're close enouh
 	//look for nearby objs -> visit them if they're close enouh
 	const int DIST_LIMIT = 3;
 	const int DIST_LIMIT = 3;
 	std::vector<const CGObjectInstance *> nearbyVisitableObjs;
 	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
 	{
 	{
-		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);
+		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);
 	boost::sort(nearbyVisitableObjs, isCloser);
 	if(nearbyVisitableObjs.size())
 	if(nearbyVisitableObjs.size())

+ 24 - 20
AI/VCAI/VCAI.cpp

@@ -1090,36 +1090,42 @@ void VCAI::buildStructure(const CGTownInstance * t)
 		return;
 		return;
 }
 }
 
 
-std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
+bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h)
 {
 {
-	validateVisitableObjs();
-	std::vector<const CGObjectInstance *> possibleDestinations;
-	for(const CGObjectInstance *obj : visitableObjs)
-	{
-		const int3 pos = obj->visitablePos();
-		if (isAccessibleForHero(obj->visitablePos(), h) &&
+	const int3 pos = obj->visitablePos();
+	if (isAccessibleForHero(obj->visitablePos(), h) &&
 			!obj->wasVisited(playerID) &&
 			!obj->wasVisited(playerID) &&
 			(obj->tempOwner != playerID || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
 			(obj->tempOwner != playerID || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
 			isSafeToVisit(h, pos) &&
 			isSafeToVisit(h, pos) &&
 			shouldVisit(h, obj) &&
 			shouldVisit(h, obj) &&
 			!vstd::contains(alreadyVisited, obj) &&
 			!vstd::contains(alreadyVisited, obj) &&
 			!vstd::contains(reservedObjs, obj))
 			!vstd::contains(reservedObjs, obj))
+	{
+		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 false;
+		else
+			return true; //all of the following is met
+	}
+
+	return false;
+}
+
+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);
 			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;
-		}), possibleDestinations.end());
-
 	boost::sort(possibleDestinations, isCloser);
 	boost::sort(possibleDestinations, isCloser);
 
 
 	return possibleDestinations;
 	return possibleDestinations;
@@ -1995,7 +2001,6 @@ void VCAI::buildArmyIn(const CGTownInstance * t)
 
 
 int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
 int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
 {
 {
-	TimeCheck tc("looking for best exploration neighbour");
 	std::map<int3, int> dstToRevealedTiles;
 	std::map<int3, int> dstToRevealedTiles;
 	for(crint3 dir : dirs)
 	for(crint3 dir : dirs)
 		if(cb->isInTheMap(hpos+dir))
 		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)
 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...";
     logAi->debugStream() << "Looking for an another place for exploration...";
 	tiles.resize(radius);
 	tiles.resize(radius);
 
 

+ 1 - 0
AI/VCAI/VCAI.h

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