1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

NKAI: fix potential concurrency and town treat calculation

This commit is contained in:
Andrii Danylchenko 2023-08-06 08:57:14 +03:00
parent b9e804954d
commit a4297ebdf6
2 changed files with 48 additions and 29 deletions

View File

@ -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,15 +102,10 @@ void DangerHitMapAnalyzer::updateHitMap()
node.fastestDanger = newTreat;
}
if(newTreat.turn == 0)
{
auto objects = cb->getVisitableObjs(pos, false);
for(auto obj : objects)
{
if(cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES)
enemyHeroAccessibleObjects[path.targetHero].insert(obj);
if(obj->ID == Obj::TOWN && obj->getOwner() == ai->playerID)
{
auto & treats = townTreats[obj->id];
@ -122,6 +124,11 @@ void DangerHitMapAnalyzer::updateHitMap()
{
*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<const CGObjectInstance *> empty = {};
const std::set<const CGObjectInstance *> & DangerHitMapAnalyzer::getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const
std::set<const CGObjectInstance *> DangerHitMapAnalyzer::getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const
{
auto result = enemyHeroAccessibleObjects.find(enemy);
std::set<const CGObjectInstance *> result;
if(result == enemyHeroAccessibleObjects.end())
for(auto & obj : enemyHeroAccessibleObjects)
{
return empty;
if(obj.hero == enemy)
result.insert(obj.obj);
}
return result->second;
return result;
}
void DangerHitMapAnalyzer::reset()

View File

@ -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<HitMapNode, 3> hitMap;
std::map<const CGHeroInstance *, std::set<const CGObjectInstance *>> enemyHeroAccessibleObjects;
tbb::concurrent_vector<EnemyHeroAccessibleObject> 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<const CGObjectInstance *> & getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const;
std::set<const CGObjectInstance *> getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const;
void reset();
void resetTileOwners() { tileOwnersUpToDate = false; }
PlayerColor getTileOwner(const int3 & tile) const;