mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
AI pathfinding const api and updatePaths
This commit is contained in:
@@ -330,7 +330,7 @@ bool AINodeStorage::isTileAccessible(const int3 & pos, const EPathfindingLayer l
|
||||
return node.action != CGPathNode::ENodeAction::UNKNOWN;
|
||||
}
|
||||
|
||||
std::vector<AIPath> AINodeStorage::getChainInfo(int3 pos, bool isOnLand) const
|
||||
std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand) const
|
||||
{
|
||||
std::vector<AIPath> paths;
|
||||
auto chains = nodes[pos.x][pos.y][pos.z][isOnLand ? EPathfindingLayer::LAND : EPathfindingLayer::SAIL];
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
bool isBattleNode(const CGPathNode * node) const;
|
||||
bool hasBetterChain(const PathNodeInfo & source, CDestinationNodeInfo & destination) const;
|
||||
boost::optional<AIPathNode *> getOrCreateNode(const int3 & coord, const EPathfindingLayer layer, int chainNumber);
|
||||
std::vector<AIPath> getChainInfo(int3 pos, bool isOnLand) const;
|
||||
std::vector<AIPath> getChainInfo(const int3 & pos, bool isOnLand) const;
|
||||
bool isTileAccessible(const int3 & pos, const EPathfindingLayer layer) const;
|
||||
|
||||
void setHero(HeroPtr heroPtr);
|
||||
|
||||
@@ -15,41 +15,29 @@
|
||||
|
||||
std::vector<std::shared_ptr<AINodeStorage>> AIPathfinder::storagePool;
|
||||
std::map<HeroPtr, std::shared_ptr<AINodeStorage>> AIPathfinder::storageMap;
|
||||
boost::mutex AIPathfinder::storageMutex;
|
||||
|
||||
AIPathfinder::AIPathfinder(CPlayerSpecificInfoCallback * cb, VCAI * ai)
|
||||
:cb(cb), ai(ai)
|
||||
{
|
||||
}
|
||||
|
||||
void AIPathfinder::clear()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> storageLock(storageMutex);
|
||||
storageMap.clear();
|
||||
}
|
||||
|
||||
void AIPathfinder::init()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> storageLock(storageMutex);
|
||||
storagePool.clear();
|
||||
storageMap.clear();
|
||||
}
|
||||
|
||||
bool AIPathfinder::isTileAccessible(const HeroPtr & hero, const int3 & tile)
|
||||
bool AIPathfinder::isTileAccessible(const HeroPtr & hero, const int3 & tile) const
|
||||
{
|
||||
boost::unique_lock<boost::mutex> storageLock(storageMutex);
|
||||
|
||||
std::shared_ptr<AINodeStorage> nodeStorage = getOrCreateStorage(hero);
|
||||
std::shared_ptr<const AINodeStorage> nodeStorage = getStorage(hero);
|
||||
|
||||
return nodeStorage->isTileAccessible(tile, EPathfindingLayer::LAND)
|
||||
|| nodeStorage->isTileAccessible(tile, EPathfindingLayer::SAIL);
|
||||
}
|
||||
|
||||
std::vector<AIPath> AIPathfinder::getPathInfo(HeroPtr hero, int3 tile)
|
||||
std::vector<AIPath> AIPathfinder::getPathInfo(const HeroPtr & hero, const int3 & tile) const
|
||||
{
|
||||
boost::unique_lock<boost::mutex> storageLock(storageMutex);
|
||||
|
||||
std::shared_ptr<AINodeStorage> nodeStorage = getOrCreateStorage(hero);
|
||||
std::shared_ptr<const AINodeStorage> nodeStorage = getStorage(hero);
|
||||
|
||||
const TerrainTile * tileInfo = cb->getTile(tile, false);
|
||||
|
||||
@@ -61,13 +49,14 @@ std::vector<AIPath> AIPathfinder::getPathInfo(HeroPtr hero, int3 tile)
|
||||
return nodeStorage->getChainInfo(tile, !tileInfo->isWater());
|
||||
}
|
||||
|
||||
std::shared_ptr<AINodeStorage> AIPathfinder::getOrCreateStorage(const HeroPtr & hero)
|
||||
void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes)
|
||||
{
|
||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||
storageMap.clear();
|
||||
|
||||
if(!vstd::contains(storageMap, hero))
|
||||
// TODO: go parallel?
|
||||
for(HeroPtr hero : heroes)
|
||||
{
|
||||
logAi->debug("Recalculate paths for %s", hero->name);
|
||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||
|
||||
if(storageMap.size() < storagePool.size())
|
||||
{
|
||||
@@ -84,13 +73,43 @@ std::shared_ptr<AINodeStorage> AIPathfinder::getOrCreateStorage(const HeroPtr &
|
||||
|
||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, nodeStorage);
|
||||
|
||||
logAi->debug("Recalculate paths for %s", hero->name);
|
||||
cb->calculatePaths(config, hero.get());
|
||||
}
|
||||
}
|
||||
|
||||
void AIPathfinder::updatePaths(const HeroPtr & hero)
|
||||
{
|
||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||
|
||||
if(!vstd::contains(storageMap, hero))
|
||||
{
|
||||
if(storageMap.size() < storagePool.size())
|
||||
{
|
||||
nodeStorage = storagePool.at(storageMap.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeStorage = std::make_shared<AINodeStorage>(cb->getMapSize());
|
||||
storagePool.push_back(nodeStorage);
|
||||
}
|
||||
|
||||
storageMap[hero] = nodeStorage;
|
||||
nodeStorage->setHero(hero.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeStorage = storageMap.at(hero);
|
||||
}
|
||||
|
||||
return nodeStorage;
|
||||
logAi->debug("Recalculate paths for %s", hero->name);
|
||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, nodeStorage);
|
||||
|
||||
cb->calculatePaths(config, hero.get());
|
||||
}
|
||||
|
||||
std::shared_ptr<const AINodeStorage> AIPathfinder::getStorage(const HeroPtr & hero) const
|
||||
{
|
||||
return storageMap.at(hero);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +19,15 @@ class AIPathfinder
|
||||
private:
|
||||
static std::vector<std::shared_ptr<AINodeStorage>> storagePool;
|
||||
static std::map<HeroPtr, std::shared_ptr<AINodeStorage>> storageMap;
|
||||
static boost::mutex storageMutex;
|
||||
CPlayerSpecificInfoCallback * cb;
|
||||
VCAI * ai;
|
||||
|
||||
std::shared_ptr<AINodeStorage> getOrCreateStorage(const HeroPtr & hero);
|
||||
std::shared_ptr<const AINodeStorage> getStorage(const HeroPtr & hero) const;
|
||||
public:
|
||||
AIPathfinder(CPlayerSpecificInfoCallback * cb, VCAI * ai);
|
||||
std::vector<AIPath> getPathInfo(HeroPtr hero, int3 tile);
|
||||
bool isTileAccessible(const HeroPtr & hero, const int3 & tile);
|
||||
void clear();
|
||||
std::vector<AIPath> getPathInfo(const HeroPtr & hero, const int3 & tile) const;
|
||||
bool isTileAccessible(const HeroPtr & hero, const int3 & tile) const;
|
||||
void updatePaths(std::vector<HeroPtr> heroes);
|
||||
void updatePaths(const HeroPtr & heroes);
|
||||
void init();
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ void PathfindingManager::setAI(VCAI * AI)
|
||||
ai = AI;
|
||||
}
|
||||
|
||||
Goals::TGoalVec PathfindingManager::howToVisitTile(int3 tile)
|
||||
Goals::TGoalVec PathfindingManager::howToVisitTile(const int3 & tile) const
|
||||
{
|
||||
Goals::TGoalVec result;
|
||||
|
||||
@@ -47,7 +47,7 @@ Goals::TGoalVec PathfindingManager::howToVisitTile(int3 tile)
|
||||
return result;
|
||||
}
|
||||
|
||||
Goals::TGoalVec PathfindingManager::howToVisitObj(ObjectIdRef obj)
|
||||
Goals::TGoalVec PathfindingManager::howToVisitObj(ObjectIdRef obj) const
|
||||
{
|
||||
Goals::TGoalVec result;
|
||||
|
||||
@@ -62,7 +62,7 @@ Goals::TGoalVec PathfindingManager::howToVisitObj(ObjectIdRef obj)
|
||||
return result;
|
||||
}
|
||||
|
||||
Goals::TGoalVec PathfindingManager::howToVisitTile(HeroPtr hero, int3 tile, bool allowGatherArmy)
|
||||
Goals::TGoalVec PathfindingManager::howToVisitTile(const HeroPtr & hero, const int3 & tile, bool allowGatherArmy) const
|
||||
{
|
||||
auto result = findPath(hero, tile, allowGatherArmy, [&](int3 firstTileToGet) -> Goals::TSubgoal
|
||||
{
|
||||
@@ -77,7 +77,7 @@ Goals::TGoalVec PathfindingManager::howToVisitTile(HeroPtr hero, int3 tile, bool
|
||||
return result;
|
||||
}
|
||||
|
||||
Goals::TGoalVec PathfindingManager::howToVisitObj(HeroPtr hero, ObjectIdRef obj, bool allowGatherArmy)
|
||||
Goals::TGoalVec PathfindingManager::howToVisitObj(const HeroPtr & hero, ObjectIdRef obj, bool allowGatherArmy) const
|
||||
{
|
||||
if(!obj)
|
||||
{
|
||||
@@ -102,7 +102,7 @@ Goals::TGoalVec PathfindingManager::howToVisitObj(HeroPtr hero, ObjectIdRef obj,
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<AIPath> PathfindingManager::getPathsToTile(HeroPtr hero, int3 tile)
|
||||
std::vector<AIPath> PathfindingManager::getPathsToTile(const HeroPtr & hero, const int3 & tile) const
|
||||
{
|
||||
return pathfinder->getPathInfo(hero, tile);
|
||||
}
|
||||
@@ -111,7 +111,7 @@ Goals::TGoalVec PathfindingManager::findPath(
|
||||
HeroPtr hero,
|
||||
crint3 dest,
|
||||
bool allowGatherArmy,
|
||||
const std::function<Goals::TSubgoal(int3)> doVisitTile)
|
||||
const std::function<Goals::TSubgoal(int3)> doVisitTile) const
|
||||
{
|
||||
Goals::TGoalVec result;
|
||||
boost::optional<uint64_t> armyValueRequired;
|
||||
@@ -184,7 +184,7 @@ Goals::TGoalVec PathfindingManager::findPath(
|
||||
return result;
|
||||
}
|
||||
|
||||
Goals::TSubgoal PathfindingManager::clearWayTo(HeroPtr hero, int3 firstTileToGet)
|
||||
Goals::TSubgoal PathfindingManager::clearWayTo(HeroPtr hero, int3 firstTileToGet) const
|
||||
{
|
||||
if(isBlockedBorderGate(firstTileToGet))
|
||||
{
|
||||
@@ -235,8 +235,13 @@ Goals::TSubgoal PathfindingManager::clearWayTo(HeroPtr hero, int3 firstTileToGet
|
||||
return sptr(Goals::VisitTile(firstTileToGet).sethero(hero).setisAbstract(true));
|
||||
}
|
||||
|
||||
void PathfindingManager::resetPaths()
|
||||
void PathfindingManager::updatePaths(std::vector<HeroPtr> heroes)
|
||||
{
|
||||
logAi->debug("AIPathfinder has been reseted.");
|
||||
pathfinder->clear();
|
||||
pathfinder->updatePaths(heroes);
|
||||
}
|
||||
|
||||
void PathfindingManager::updatePaths(const HeroPtr & hero)
|
||||
{
|
||||
pathfinder->updatePaths(hero);
|
||||
}
|
||||
|
||||
@@ -20,12 +20,13 @@ public:
|
||||
virtual void init(CPlayerSpecificInfoCallback * CB) = 0;
|
||||
virtual void setAI(VCAI * AI) = 0;
|
||||
|
||||
virtual void resetPaths() = 0;
|
||||
virtual Goals::TGoalVec howToVisitTile(HeroPtr hero, int3 tile, bool allowGatherArmy = true) = 0;
|
||||
virtual Goals::TGoalVec howToVisitObj(HeroPtr hero, ObjectIdRef obj, bool allowGatherArmy = true) = 0;
|
||||
virtual Goals::TGoalVec howToVisitTile(int3 tile) = 0;
|
||||
virtual Goals::TGoalVec howToVisitObj(ObjectIdRef obj) = 0;
|
||||
virtual std::vector<AIPath> getPathsToTile(HeroPtr hero, int3 tile) = 0;
|
||||
virtual void updatePaths(std::vector<HeroPtr> heroes) = 0;
|
||||
virtual void updatePaths(const HeroPtr & hero) = 0;
|
||||
virtual Goals::TGoalVec howToVisitTile(const HeroPtr & hero, const int3 & tile, bool allowGatherArmy = true) const = 0;
|
||||
virtual Goals::TGoalVec howToVisitObj(const HeroPtr & hero, ObjectIdRef obj, bool allowGatherArmy = true) const = 0;
|
||||
virtual Goals::TGoalVec howToVisitTile(const int3 & tile) const = 0;
|
||||
virtual Goals::TGoalVec howToVisitObj(ObjectIdRef obj) const = 0;
|
||||
virtual std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const = 0;
|
||||
};
|
||||
|
||||
class DLL_EXPORT PathfindingManager : public IPathfindingManager
|
||||
@@ -41,15 +42,16 @@ public:
|
||||
PathfindingManager() = default;
|
||||
PathfindingManager(CPlayerSpecificInfoCallback * CB, VCAI * AI = nullptr); //for tests only
|
||||
|
||||
Goals::TGoalVec howToVisitTile(HeroPtr hero, int3 tile, bool allowGatherArmy = true) override;
|
||||
Goals::TGoalVec howToVisitObj(HeroPtr hero, ObjectIdRef obj, bool allowGatherArmy = true) override;
|
||||
Goals::TGoalVec howToVisitTile(int3 tile) override;
|
||||
Goals::TGoalVec howToVisitObj(ObjectIdRef obj) override;
|
||||
std::vector<AIPath> getPathsToTile(HeroPtr hero, int3 tile) override;
|
||||
void resetPaths() override;
|
||||
Goals::TGoalVec howToVisitTile(const HeroPtr & hero, const int3 & tile, bool allowGatherArmy = true) const override;
|
||||
Goals::TGoalVec howToVisitObj(const HeroPtr & hero, ObjectIdRef obj, bool allowGatherArmy = true) const override;
|
||||
Goals::TGoalVec howToVisitTile(const int3 & tile) const override;
|
||||
Goals::TGoalVec howToVisitObj(ObjectIdRef obj) const override;
|
||||
std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
|
||||
void updatePaths(std::vector<HeroPtr> heroes) override;
|
||||
void updatePaths(const HeroPtr & hero) override;
|
||||
|
||||
STRONG_INLINE
|
||||
bool isTileAccessible(const HeroPtr & hero, const int3 & tile)
|
||||
bool isTileAccessible(const HeroPtr & hero, const int3 & tile) const
|
||||
{
|
||||
return pathfinder->isTileAccessible(hero, tile);
|
||||
}
|
||||
@@ -62,7 +64,7 @@ private:
|
||||
HeroPtr hero,
|
||||
crint3 dest,
|
||||
bool allowGatherArmy,
|
||||
const std::function<Goals::TSubgoal(int3)> goalFactory);
|
||||
const std::function<Goals::TSubgoal(int3)> goalFactory) const;
|
||||
|
||||
Goals::TSubgoal clearWayTo(HeroPtr hero, int3 firstTileToGet);
|
||||
Goals::TSubgoal clearWayTo(HeroPtr hero, int3 firstTileToGet) const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user