mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
* better new hero initialization
* faster pathfinder
This commit is contained in:
134
CPathfinder.cpp
134
CPathfinder.cpp
@@ -49,149 +49,143 @@ CPath * CPathfinder::getPath(int3 src, int3 dest, const CGHeroInstance * hero, u
|
||||
graph[i].resize(CGI->ac->map.height);
|
||||
for(int j=0; j<graph[i].size(); ++j)
|
||||
{
|
||||
graph[i][j] = new CPathNode;
|
||||
graph[i][j]->accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
|
||||
graph[i][j].accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
|
||||
if(i==dest.x && j==dest.y && CGI->mh->ttiles[i][j][src.z].visitable)
|
||||
graph[i][j]->accesible = true; //for allowing visiting objects
|
||||
graph[i][j]->dist = -1;
|
||||
graph[i][j]->theNodeBefore = NULL;
|
||||
graph[i][j]->visited = false;
|
||||
graph[i][j]->coord.x = i;
|
||||
graph[i][j]->coord.y = j;
|
||||
graph[i][j]->coord.z = dest.z;
|
||||
graph[i][j].accesible = true; //for allowing visiting objects
|
||||
graph[i][j].dist = -1;
|
||||
graph[i][j].theNodeBefore = NULL;
|
||||
graph[i][j].visited = false;
|
||||
graph[i][j].coord.x = i;
|
||||
graph[i][j].coord.y = j;
|
||||
graph[i][j].coord.z = dest.z;
|
||||
if (CGI->mh->ttiles[i][j][src.z].terType==EterrainType::rock)
|
||||
graph[i][j]->accesible = false;
|
||||
graph[i][j].accesible = false;
|
||||
if ((blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType==EterrainType::water))
|
||||
graph[i][j]->accesible = false;
|
||||
graph[i][j].accesible = false;
|
||||
else if ((!blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType!=EterrainType::water))
|
||||
graph[i][j]->accesible = false;
|
||||
graph[i][j].accesible = false;
|
||||
}
|
||||
}
|
||||
|
||||
//graph initialized
|
||||
|
||||
graph[src.x][src.y]->dist = 0;
|
||||
graph[src.x][src.y].dist = 0;
|
||||
|
||||
std::queue<CPathNode *> mq;
|
||||
std::queue<CPathNode> mq;
|
||||
mq.push(graph[src.x][src.y]);
|
||||
|
||||
unsigned int curDist = 4000000000;
|
||||
|
||||
while(!mq.empty())
|
||||
{
|
||||
CPathNode * cp = mq.front();
|
||||
CPathNode cp = mq.front();
|
||||
mq.pop();
|
||||
if ((cp->coord.x == dest.x) && (cp->coord.y==dest.y))
|
||||
if ((cp.coord.x == dest.x) && (cp.coord.y==dest.y))
|
||||
{
|
||||
if (cp->dist < curDist)
|
||||
curDist=cp->dist;
|
||||
if (cp.dist < curDist)
|
||||
curDist=cp.dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cp->dist > curDist)
|
||||
if (cp.dist > curDist)
|
||||
continue;
|
||||
}
|
||||
if(cp->coord.x>0)
|
||||
if(cp.coord.x>0)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x-1][cp->coord.y];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x-1][cp.coord.y];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.y>0)
|
||||
if(cp.coord.y>0)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x][cp->coord.y-1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y-1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x][cp.coord.y-1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y-1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.x>0 && cp->coord.y>0)
|
||||
if(cp.coord.x>0 && cp.coord.y>0)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x-1][cp->coord.y-1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y-1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x-1][cp.coord.y-1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y-1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y-1, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y-1, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.x<graph.size()-1)
|
||||
if(cp.coord.x<graph.size()-1)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x+1][cp->coord.y];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x+1][cp.coord.y];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.y<graph[0].size()-1)
|
||||
if(cp.coord.y<graph[0].size()-1)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x][cp->coord.y+1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y+1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x][cp.coord.y+1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y+1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y+1, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y+1, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.x<graph.size()-1 && cp->coord.y<graph[0].size()-1)
|
||||
if(cp.coord.x<graph.size()-1 && cp.coord.y<graph[0].size()-1)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x+1][cp->coord.y+1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y+1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x+1][cp.coord.y+1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y+1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y+1, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y+1, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.x>0 && cp->coord.y<graph[0].size()-1)
|
||||
if(cp.coord.x>0 && cp.coord.y<graph[0].size()-1)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x-1][cp->coord.y+1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y+1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x-1][cp.coord.y+1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y+1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y+1, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y+1, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
if(cp->coord.x<graph.size()-1 && cp->coord.y>0)
|
||||
if(cp.coord.x<graph.size()-1 && cp.coord.y>0)
|
||||
{
|
||||
CPathNode * dp = graph[cp->coord.x+1][cp->coord.y-1];
|
||||
if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y-1, src.z), hero))) && dp->accesible)
|
||||
CPathNode & dp = graph[cp.coord.x+1][cp.coord.y-1];
|
||||
if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y-1, src.z), hero))) && dp.accesible)
|
||||
{
|
||||
dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y-1, src.z), hero);
|
||||
dp->theNodeBefore = cp;
|
||||
dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y-1, src.z), hero);
|
||||
dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
|
||||
mq.push(dp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CPathNode * curNode = graph[dest.x][dest.y];
|
||||
if(!curNode->theNodeBefore)
|
||||
CPathNode curNode = graph[dest.x][dest.y];
|
||||
if(!curNode.theNodeBefore)
|
||||
return NULL;
|
||||
|
||||
CPath * ret = new CPath;
|
||||
|
||||
while(curNode!=graph[src.x][src.y] && curNode != NULL)
|
||||
while(curNode.coord!=graph[src.x][src.y].coord)
|
||||
{
|
||||
ret->nodes.push_back(*curNode);
|
||||
curNode = curNode->theNodeBefore;
|
||||
ret->nodes.push_back(curNode);
|
||||
curNode = *(curNode.theNodeBefore);
|
||||
}
|
||||
|
||||
ret->nodes.push_back(*graph[src.x][src.y]);
|
||||
ret->nodes.push_back(graph[src.x][src.y]);
|
||||
|
||||
for(int i=0; i<graph.size(); ++i)
|
||||
{
|
||||
for(int j=0; j<graph[0].size(); ++j)
|
||||
delete graph[i][j];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user