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

AI: pathfinder api supports configuration

This commit is contained in:
Andrii Danylchenko 2018-07-28 15:30:57 +03:00
parent 9ab44b950a
commit 7150fc9f71
8 changed files with 41 additions and 13 deletions

View File

@ -291,6 +291,11 @@ const CPathsInfo * CCallback::getPathsInfo(const CGHeroInstance *h)
return cl->getPathsInfo(h);
}
void CCallback::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
{
cl->calculatePaths(config, hero);
}
int3 CCallback::getGuardingCreaturePosition(int3 tile)
{
if (!gs->map->isInTheMap(tile))

View File

@ -25,6 +25,7 @@ class IShipyard;
struct CGPathNode;
struct CGPath;
struct CPathsInfo;
class CPathfinderConfig;
struct CPack;
class IBattleEventsReceiver;
class IGameEventsReceiver;
@ -106,6 +107,7 @@ public:
virtual bool canMoveBetween(const int3 &a, const int3 &b);
virtual int3 getGuardingCreaturePosition(int3 tile);
virtual const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
virtual void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);

View File

@ -628,6 +628,13 @@ const CPathsInfo * CClient::getPathsInfo(const CGHeroInstance * h)
return pathInfo.get();
}
void CClient::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
{
boost::unique_lock<boost::mutex> pathLock(config->nodeStorage->getMutex());
gs->calculatePaths(config, hero);
}
PlayerColor CClient::getLocalPlayer() const
{
if(LOCPLINT)

View File

@ -151,6 +151,7 @@ public:
void invalidatePaths();
const CPathsInfo * getPathsInfo(const CGHeroInstance * h);
void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
virtual PlayerColor getLocalPlayer() const override;
friend class CCallback; //handling players actions

View File

@ -1979,6 +1979,12 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
pathfinder.calculatePaths();
}
void CGameState::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
{
CPathfinder pathfinder(this, hero, config);
pathfinder.calculatePaths();
}
/**
* Tells if the tile is guarded by a monster as well as the position
* of the monster that will attack on it.

View File

@ -178,6 +178,7 @@ public:
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
int3 guardingCreaturePosition (int3 pos) const;
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
void updateRumor();

View File

@ -41,7 +41,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateNeighbours(
{
for(EPathfindingLayer i = EPathfindingLayer::LAND; i <= EPathfindingLayer::AIR; i.advance(1))
{
auto node = pathfinderConfig->nodeHelper->getNode(neighbour, i);
auto node = pathfinderConfig->nodeStorage->getNode(neighbour, i);
if(node->accessible == CGPathNode::NOT_SET)
continue;
@ -63,7 +63,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateTeleportations(
for(auto & neighbour : accessibleExits)
{
auto node = pathfinderConfig->nodeHelper->getNode(neighbour, source.node->layer);
auto node = pathfinderConfig->nodeStorage->getNode(neighbour, source.node->layer);
neighbours.push_back(node);
}
@ -96,19 +96,24 @@ std::vector<int3> CNeighbourFinder::getNeighbourTiles(
return neighbourTiles;
}
class CPathfinderNodeHelper : public CNodeHelper
class CPathfinderNodeStorage : public CNodeStorage
{
private:
CPathsInfo & out;
public:
CPathfinderNodeHelper(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
CPathfinderNodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
:out(pathsInfo)
{
out.hero = hero;
out.hpos = hero->getPosition(false);
}
virtual boost::mutex & getMutex()
{
return out.pathMx;
}
virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer)
{
return out.getNode(coord, layer);
@ -189,10 +194,10 @@ public:
};
CPathfinderConfig::CPathfinderConfig(
std::shared_ptr<CNodeHelper> nodeHelper,
std::shared_ptr<CNodeStorage> nodeStorage,
std::shared_ptr<CNeighbourFinder> neighbourFinder,
std::vector<std::shared_ptr<IPathfindingRule>> rules)
: nodeHelper(nodeHelper), neighbourFinder(neighbourFinder), rules(rules), options()
: nodeStorage(nodeStorage), neighbourFinder(neighbourFinder), rules(rules), options()
{
}
@ -204,7 +209,7 @@ CPathfinder::CPathfinder(
_gs,
_hero,
std::make_shared<CPathfinderConfig>(
std::make_shared<CPathfinderNodeHelper>(_out, _hero),
std::make_shared<CPathfinderNodeStorage>(_out, _hero),
std::make_shared<CNeighbourFinder>(),
std::vector<std::shared_ptr<IPathfindingRule>>{
std::make_shared<CMovementCostRule>(),
@ -238,7 +243,7 @@ void CPathfinder::calculatePaths()
//logGlobal->info("Calculating paths for hero %s (adress %d) of player %d", hero->name, hero , hero->tempOwner);
//initial tile - set cost on 0 and add to the queue
CGPathNode * initialNode = config->nodeHelper->getInitialNode();
CGPathNode * initialNode = config->nodeStorage->getInitialNode();
if(!isInTheMap(initialNode->coord)/* || !gs->map->isInTheMap(dest)*/) //check input
{
@ -759,7 +764,7 @@ CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
bool CPathfinder::isSourceInitialPosition() const
{
return source.node->coord == config->nodeHelper->getInitialNode()->coord;
return source.node->coord == config->nodeStorage->getInitialNode()->coord;
}
bool CPathfinder::isSourceGuarded() const
@ -810,7 +815,7 @@ void CPathfinder::initializeGraph()
{
auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo)
{
auto node = config->nodeHelper->getNode(pos, layer);
auto node = config->nodeStorage->getNode(pos, layer);
auto accessibility = evaluateAccessibility(pos, tinfo, layer);
node->update(pos, layer, accessibility);
};

View File

@ -127,11 +127,12 @@ struct DLL_LINKAGE CDestinationNodeInfo : public CPathNodeInfo
virtual bool isBetterWay();
};
class CNodeHelper
class CNodeStorage
{
public:
virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer) = 0;
virtual CGPathNode * getInitialNode() = 0;
virtual boost::mutex & getMutex() = 0;
};
class CPathfinderHelper;
@ -237,13 +238,13 @@ struct DLL_LINKAGE PathfinderOptions
class CPathfinderConfig
{
public:
std::shared_ptr<CNodeHelper> nodeHelper;
std::shared_ptr<CNodeStorage> nodeStorage;
std::shared_ptr<CNeighbourFinder> neighbourFinder;
std::vector<std::shared_ptr<IPathfindingRule>> rules;
PathfinderOptions options;
CPathfinderConfig(
std::shared_ptr<CNodeHelper> nodeHelper,
std::shared_ptr<CNodeStorage> nodeStorage,
std::shared_ptr<CNeighbourFinder> neighbourFinder,
std::vector<std::shared_ptr<IPathfindingRule>> rules);
};