From 7af9b0ea744d8e809eda41ff7800fbbcabbb469c Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Wed, 25 Dec 2013 13:38:20 +0000 Subject: [PATCH] Replaced AI vectors by sets for both performance and safety. --- AI/VCAI/Goals.cpp | 4 ++-- AI/VCAI/VCAI.cpp | 37 +++++++++++++++++++++++-------------- AI/VCAI/VCAI.h | 12 +++++++----- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/AI/VCAI/Goals.cpp b/AI/VCAI/Goals.cpp index c16096a18..27b9f98ec 100644 --- a/AI/VCAI/Goals.cpp +++ b/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 diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 3665b8730..6b3dc0668 100644 --- a/AI/VCAI/VCAI.cpp +++ b/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 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(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(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 &out, boo } }); } +void VCAI::retreiveVisitableObjs(std::set &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 VCAI::getFlaggedObjects() const { @@ -1449,7 +1458,7 @@ std::vector VCAI::getFlaggedObjects() const void VCAI::addVisitableObj(const CGObjectInstance *obj) { - visitableObjs.push_back(obj); + visitableObjs.insert(obj); helperObjInfo[obj] = ObjInfo(obj); } diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index d4410e4cd..c5d467d96 100644 --- a/AI/VCAI/VCAI.h +++ b/AI/VCAI/VCAI.h @@ -142,14 +142,15 @@ public: std::map knownSubterraneanGates; //std::vector visitedThisWeek; //only OPWs - std::map > townVisitsThisWeek; + std::map > townVisitsThisWeek; std::map lockedHeroes; //TODO: allow non-elementar objectives - std::map > reservedHeroesMap; //objects reserved by specific heroes + std::map > reservedHeroesMap; //objects reserved by specific heroes - std::vector visitableObjs; - std::vector alreadyVisited; - std::vector reservedObjs; //to be visited by specific hero + //sets are faster to search, also do not contain duplicates + std::set visitableObjs; + std::set alreadyVisited; + std::set 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 &out, bool includeOwned = false) const; + void retreiveVisitableObjs(std::set &out, bool includeOwned = false) const; std::vector getFlaggedObjects() const; const CGObjectInstance *lookForArt(int aid) const;