1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

CPathfinder: implement priority queue and node locking

This commit is contained in:
ArseniyShestakov
2015-11-07 21:11:07 +03:00
parent 148355908d
commit 3f2cdf3137
2 changed files with 31 additions and 7 deletions

View File

@@ -84,12 +84,13 @@ void CPathfinder::calculatePaths()
CGPathNode *initialNode = out.getNode(out.hpos, hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND);
initialNode->turns = 0;
initialNode->moveRemains = hero->movement;
mq.push_back(initialNode);
pq.push(initialNode);
while(!mq.empty())
while(!pq.empty())
{
cp = mq.front();
mq.pop_front();
cp = pq.top();
pq.pop();
cp->locked = true;
int movement = cp->moveRemains, turn = cp->turns;
if(!movement)
@@ -110,6 +111,9 @@ void CPathfinder::calculatePaths()
if(dp->accessible == CGPathNode::NOT_SET)
continue;
if(dp->locked)
continue;
if(cp->layer != i && !isLayerTransitionPossible())
continue;
@@ -142,7 +146,7 @@ void CPathfinder::calculatePaths()
dp->theNodeBefore = cp;
if(isMovementAfterDestPossible())
mq.push_back(dp);
pq.push(dp);
}
}
} //neighbours loop
@@ -154,12 +158,15 @@ void CPathfinder::calculatePaths()
for(auto & neighbour : neighbours)
{
dp = out.getNode(neighbour, cp->layer);
if(dp->locked)
continue;
if(isBetterWay(movement, turn))
{
dp->moveRemains = movement;
dp->turns = turn;
dp->theNodeBefore = cp;
mq.push_back(dp);
pq.push(dp);
}
}
}
@@ -386,6 +393,7 @@ void CPathfinder::initializeGraph()
auto updateNode = [&](int3 pos, EPathfindingLayer layer, const TerrainTile *tinfo)
{
auto node = out.getNode(pos, layer);
node->locked = false;
node->accessible = evaluateAccessibility(pos, tinfo);
node->turns = 0xff;
node->moveRemains = 0;
@@ -513,6 +521,7 @@ bool CPathfinder::canVisitObject() const
CGPathNode::CGPathNode()
: coord(-1,-1,-1)
{
locked = false;
accessible = NOT_SET;
land = 0;
moveRemains = 0;

View File

@@ -5,6 +5,8 @@
#include "IGameCallback.h"
#include "int3.h"
#include <boost/heap/priority_queue.hpp>
/*
* CPathfinder.h, part of VCMI engine
*
@@ -30,6 +32,7 @@ struct DLL_LINKAGE CGPathNode
BLOCKED //tile can't be entered nor visited
};
bool locked;
EAccessibility accessible;
ui8 land;
ui8 turns; //how many turns we have to wait before reachng the tile - 0 means current turn
@@ -96,7 +99,19 @@ private:
CPathsInfo &out;
const CGHeroInstance *hero;
std::list<CGPathNode*> mq; //BFS queue -> nodes to be checked
struct NodeComparer
{
bool operator()(const CGPathNode * lhs, const CGPathNode * rhs) const
{
if(rhs->turns > lhs->turns)
return false;
else if(rhs->turns == lhs->turns && rhs->moveRemains < lhs->moveRemains)
return false;
return true;
}
};
boost::heap::priority_queue<CGPathNode *, boost::heap::compare<NodeComparer> > pq;
std::vector<int3> neighbours;