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); return cl->getPathsInfo(h);
} }
void CCallback::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
{
cl->calculatePaths(config, hero);
}
int3 CCallback::getGuardingCreaturePosition(int3 tile) int3 CCallback::getGuardingCreaturePosition(int3 tile)
{ {
if (!gs->map->isInTheMap(tile)) if (!gs->map->isInTheMap(tile))

View File

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

View File

@ -628,6 +628,13 @@ const CPathsInfo * CClient::getPathsInfo(const CGHeroInstance * h)
return pathInfo.get(); 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 PlayerColor CClient::getLocalPlayer() const
{ {
if(LOCPLINT) if(LOCPLINT)

View File

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

View File

@ -1979,6 +1979,12 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
pathfinder.calculatePaths(); 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 * Tells if the tile is guarded by a monster as well as the position
* of the monster that will attack on it. * of the monster that will attack on it.

View File

@ -178,6 +178,7 @@ public:
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2); 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 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(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; int3 guardingCreaturePosition (int3 pos) const;
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const; std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
void updateRumor(); void updateRumor();

View File

@ -41,7 +41,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateNeighbours(
{ {
for(EPathfindingLayer i = EPathfindingLayer::LAND; i <= EPathfindingLayer::AIR; i.advance(1)) 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) if(node->accessible == CGPathNode::NOT_SET)
continue; continue;
@ -63,7 +63,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateTeleportations(
for(auto & neighbour : accessibleExits) 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); neighbours.push_back(node);
} }
@ -96,19 +96,24 @@ std::vector<int3> CNeighbourFinder::getNeighbourTiles(
return neighbourTiles; return neighbourTiles;
} }
class CPathfinderNodeHelper : public CNodeHelper class CPathfinderNodeStorage : public CNodeStorage
{ {
private: private:
CPathsInfo & out; CPathsInfo & out;
public: public:
CPathfinderNodeHelper(CPathsInfo & pathsInfo, const CGHeroInstance * hero) CPathfinderNodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
:out(pathsInfo) :out(pathsInfo)
{ {
out.hero = hero; out.hero = hero;
out.hpos = hero->getPosition(false); out.hpos = hero->getPosition(false);
} }
virtual boost::mutex & getMutex()
{
return out.pathMx;
}
virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer) virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer)
{ {
return out.getNode(coord, layer); return out.getNode(coord, layer);
@ -189,10 +194,10 @@ public:
}; };
CPathfinderConfig::CPathfinderConfig( CPathfinderConfig::CPathfinderConfig(
std::shared_ptr<CNodeHelper> nodeHelper, std::shared_ptr<CNodeStorage> nodeStorage,
std::shared_ptr<CNeighbourFinder> neighbourFinder, std::shared_ptr<CNeighbourFinder> neighbourFinder,
std::vector<std::shared_ptr<IPathfindingRule>> rules) 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, _gs,
_hero, _hero,
std::make_shared<CPathfinderConfig>( std::make_shared<CPathfinderConfig>(
std::make_shared<CPathfinderNodeHelper>(_out, _hero), std::make_shared<CPathfinderNodeStorage>(_out, _hero),
std::make_shared<CNeighbourFinder>(), std::make_shared<CNeighbourFinder>(),
std::vector<std::shared_ptr<IPathfindingRule>>{ std::vector<std::shared_ptr<IPathfindingRule>>{
std::make_shared<CMovementCostRule>(), 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); //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 //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 if(!isInTheMap(initialNode->coord)/* || !gs->map->isInTheMap(dest)*/) //check input
{ {
@ -759,7 +764,7 @@ CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
bool CPathfinder::isSourceInitialPosition() 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 bool CPathfinder::isSourceGuarded() const
@ -810,7 +815,7 @@ void CPathfinder::initializeGraph()
{ {
auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo) 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); auto accessibility = evaluateAccessibility(pos, tinfo, layer);
node->update(pos, layer, accessibility); node->update(pos, layer, accessibility);
}; };

View File

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