diff --git a/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.cpp b/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.cpp index efc4bde8e..3651e567f 100644 --- a/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.cpp +++ b/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.cpp @@ -53,6 +53,13 @@ void DangerHitMapAnalyzer::updateHitMap() } } + auto ourTowns = cb->getTownsInfo(); + + for(auto town : ourTowns) + { + townTreats[town->id]; // insert empty list + } + foreach_tile_pos([&](const int3 & pos){ hitMap[pos.x][pos.y][pos.z].reset(); }); @@ -95,33 +102,33 @@ void DangerHitMapAnalyzer::updateHitMap() node.fastestDanger = newTreat; } - if(newTreat.turn == 0) + auto objects = cb->getVisitableObjs(pos, false); + + for(auto obj : objects) { - auto objects = cb->getVisitableObjs(pos, false); - - for(auto obj : objects) + if(obj->ID == Obj::TOWN && obj->getOwner() == ai->playerID) { - if(cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES) - enemyHeroAccessibleObjects[path.targetHero].insert(obj); + auto & treats = townTreats[obj->id]; + auto treat = std::find_if(treats.begin(), treats.end(), [&](const HitMapInfo & i) -> bool + { + return i.hero.hid == path.targetHero->id; + }); - if(obj->ID == Obj::TOWN && obj->getOwner() == ai->playerID) + if(treat == treats.end()) { - auto & treats = townTreats[obj->id]; - auto treat = std::find_if(treats.begin(), treats.end(), [&](const HitMapInfo & i) -> bool - { - return i.hero.hid == path.targetHero->id; - }); + treats.emplace_back(); + treat = std::prev(treats.end(), 1); + } - if(treat == treats.end()) - { - treats.emplace_back(); - treat = std::prev(treats.end(), 1); - } + if(newTreat.value() > treat->value()) + { + *treat = newTreat; + } - if(newTreat.value() > treat->value()) - { - *treat = newTreat; - } + if(newTreat.turn == 0) + { + if(cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES) + enemyHeroAccessibleObjects.emplace_back(path.targetHero, obj); } } } @@ -274,16 +281,17 @@ const HitMapNode & DangerHitMapAnalyzer::getTileTreat(const int3 & tile) const const std::set empty = {}; -const std::set & DangerHitMapAnalyzer::getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const +std::set DangerHitMapAnalyzer::getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const { - auto result = enemyHeroAccessibleObjects.find(enemy); - - if(result == enemyHeroAccessibleObjects.end()) + std::set result; + + for(auto & obj : enemyHeroAccessibleObjects) { - return empty; + if(obj.hero == enemy) + result.insert(obj.obj); } - return result->second; + return result; } void DangerHitMapAnalyzer::reset() diff --git a/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.h b/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.h index 79c56c2c4..614312649 100644 --- a/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.h +++ b/AI/Nullkiller/Analyzers/DangerHitMapAnalyzer.h @@ -55,11 +55,22 @@ struct HitMapNode } }; +struct EnemyHeroAccessibleObject +{ + const CGHeroInstance * hero; + const CGObjectInstance * obj; + + EnemyHeroAccessibleObject(const CGHeroInstance * hero, const CGObjectInstance * obj) + :hero(hero), obj(obj) + { + } +}; + class DangerHitMapAnalyzer { private: boost::multi_array hitMap; - std::map> enemyHeroAccessibleObjects; + tbb::concurrent_vector enemyHeroAccessibleObjects; bool hitMapUpToDate = false; bool tileOwnersUpToDate = false; const Nullkiller * ai; @@ -73,7 +84,7 @@ public: uint64_t enemyCanKillOurHeroesAlongThePath(const AIPath & path) const; const HitMapNode & getObjectTreat(const CGObjectInstance * obj) const; const HitMapNode & getTileTreat(const int3 & tile) const; - const std::set & getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const; + std::set getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const; void reset(); void resetTileOwners() { tileOwnersUpToDate = false; } PlayerColor getTileOwner(const int3 & tile) const;