Explorar o código

Replaced AI vectors by sets for both performance and safety.

DjWarmonger %!s(int64=12) %!d(string=hai) anos
pai
achega
7af9b0ea74
Modificáronse 3 ficheiros con 32 adicións e 21 borrados
  1. 2 2
      AI/VCAI/Goals.cpp
  2. 23 14
      AI/VCAI/VCAI.cpp
  3. 7 5
      AI/VCAI/VCAI.h

+ 2 - 2
AI/VCAI/Goals.cpp

@@ -284,8 +284,8 @@ bool GetObj::fulfillsMe (TSubgoal goal)
 		if (obj && obj->visitablePos() == goal->tile) //object could be removed
 			return true;
 	}
-	else
-		return false;
+
+	return false;
 }
 
 std::string VisitHero::completeMessage() const

+ 23 - 14
AI/VCAI/VCAI.cpp

@@ -410,7 +410,7 @@ void VCAI::heroCreated(const CGHeroInstance* h)
 {
 	LOG_TRACE(logAi);
 	if (h->visitedTown)
-		townVisitsThisWeek[HeroPtr(h)].push_back(h->visitedTown);
+		townVisitsThisWeek[HeroPtr(h)].insert(h->visitedTown);
 	NET_EVENT_HANDLER;
 }
 
@@ -647,11 +647,8 @@ void VCAI::makeTurn()
 			{
 				if (isWeeklyRevisitable(obj))
 				{
-					if (!vstd::contains(visitableObjs, obj))
-						visitableObjs.push_back(obj);
-					auto o = std::find (alreadyVisited.begin(), alreadyVisited.end(), obj);
-					if (o != alreadyVisited.end())
-						alreadyVisited.erase(o);
+					visitableObjs.insert(obj); //set doesn't need duplicate check
+					erase_if_present (alreadyVisited, obj);
 				}
 			}
 		}
@@ -689,8 +686,9 @@ void VCAI::makeTurnInternal()
 			}
 
 			cb->setSelection(hero.first.get());
-			boost::sort (hero.second, isCloser);
-			for (auto obj : hero.second)
+			std::vector<const CGObjectInstance *> vec(hero.second.begin(), hero.second.end());
+			boost::sort (vec, isCloser);
+			for (auto obj : vec)
 			{
 				if(!obj || !obj->defInfo || !cb->getObj(obj->id))
 				{
@@ -770,7 +768,7 @@ void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
 			moveCreaturesToHero (dynamic_cast<const CGTownInstance *>(obj));
 			if (h->visitedTown) //we are inside, not just attacking
 			{
-				townVisitsThisWeek[h].push_back(h->visitedTown);
+				townVisitsThisWeek[h].insert(h->visitedTown);
 				if (!h->hasSpellbook() && cb->getResourceAmount(Res::GOLD) >= GameConstants::SPELLBOOK_GOLD_COST + saving[Res::GOLD] &&
 					h->visitedTown->hasBuilt (BuildingID::MAGES_GUILD_1))
 					cb->buyArtifact(h.get(), ArtifactID::SPELLBOOK);
@@ -1302,7 +1300,7 @@ void VCAI::wander(HeroPtr h)
 
 		if(h->visitedTown)
 		{
-			townVisitsThisWeek[h].push_back(h->visitedTown);
+			townVisitsThisWeek[h].insert(h->visitedTown);
 			buildArmyIn(h->visitedTown);
 			break;
 		}
@@ -1380,13 +1378,13 @@ void VCAI::markObjectVisited (const CGObjectInstance *obj)
 		dynamic_cast<const CGBonusingObject *>(obj) || //or another time
 		(obj->ID == Obj::MONSTER))
 		return;
-	alreadyVisited.push_back(obj);
+	alreadyVisited.insert(obj);
 }
 
 void VCAI::reserveObject(HeroPtr h, const CGObjectInstance *obj)
 {
-	reservedObjs.push_back(obj);
-	reservedHeroesMap[h].push_back(obj);
+	reservedObjs.insert(obj);
+	reservedHeroesMap[h].insert(obj);
 	logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText();
 }
 
@@ -1435,6 +1433,17 @@ void VCAI::retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, boo
 		}
 	});
 }
+void VCAI::retreiveVisitableObjs(std::set<const CGObjectInstance *> &out, bool includeOwned /*= false*/) const
+{
+	foreach_tile_pos([&](const int3 &pos)
+	{
+		for(const CGObjectInstance *obj : myCb->getVisitableObjs(pos, false))
+		{
+			if(includeOwned || obj->tempOwner != playerID)
+				out.insert(obj);
+		}
+	});
+}
 
 std::vector<const CGObjectInstance *> VCAI::getFlaggedObjects() const
 {
@@ -1449,7 +1458,7 @@ std::vector<const CGObjectInstance *> VCAI::getFlaggedObjects() const
 
 void VCAI::addVisitableObj(const CGObjectInstance *obj)
 {
-	visitableObjs.push_back(obj);
+	visitableObjs.insert(obj);
 	helperObjInfo[obj] = ObjInfo(obj);
 }
 

+ 7 - 5
AI/VCAI/VCAI.h

@@ -142,14 +142,15 @@ public:
 
 	std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
 	//std::vector<const CGObjectInstance *> visitedThisWeek; //only OPWs
-	std::map<HeroPtr, std::vector<const CGTownInstance *> > townVisitsThisWeek;
+	std::map<HeroPtr, std::set<const CGTownInstance *> > townVisitsThisWeek;
 
 	std::map<HeroPtr, Goals::TSubgoal> lockedHeroes; //TODO: allow non-elementar objectives
-	std::map<HeroPtr, std::vector<const CGObjectInstance *> > reservedHeroesMap; //objects reserved by specific heroes
+	std::map<HeroPtr, std::set<const CGObjectInstance *> > reservedHeroesMap; //objects reserved by specific heroes
 
-	std::vector<const CGObjectInstance *> visitableObjs;
-	std::vector<const CGObjectInstance *> alreadyVisited;
-	std::vector<const CGObjectInstance *> reservedObjs; //to be visited by specific hero
+	//sets are faster to search, also do not contain duplicates
+	std::set<const CGObjectInstance *> visitableObjs;
+	std::set<const CGObjectInstance *> alreadyVisited;
+	std::set<const CGObjectInstance *> reservedObjs; //to be visited by specific hero
 
 	TResources saving;
 
@@ -281,6 +282,7 @@ public:
 	void validateObject(ObjectIdRef obj); //checks if object is still visible and if not, removes references to it
 	void validateVisitableObjs();
 	void retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned = false) const;
+	void retreiveVisitableObjs(std::set<const CGObjectInstance *> &out, bool includeOwned = false) const;
 	std::vector<const CGObjectInstance *> getFlaggedObjects() const;
 
 	const CGObjectInstance *lookForArt(int aid) const;