我正在尝试实现A *算法以找到到达目的地的最快路径。当目的地离玩家不远时,我可以找到路径。但当我采取远离玩家的位置时,它会冻结。任何人都可以帮我解决这个问题吗?无论如何都找不到它。
int Controller::findPathfindingNodes(int xdes, int ydes)
{
std::vector<std::shared_ptr<Tile>> tiles = model->getAllLimitTiles(); //all the tiles where we can move
std::shared_ptr<Protagonist> prota = model->getAllProtagonist(); //get data from protagonist
int currentX = prota->getXPos(); //get xpos of prota
int currentY = prota->getYPos(); //get ypos of prota
openList.clear();
closedList.clear();
mylist.clear();
//return 50;
std::shared_ptr<Tile> endPoint = model->getCoordinate(QPointF(xdes,ydes));
std::shared_ptr<Tile> startPoint = model->getCoordinate(QPointF(currentX,currentY));
int sumtotal = abs((currentX - xdes) + (currentY - ydes));
//we insert our start position, we have no parrent yet
PathFinding* start = new PathFinding(startPoint,currentX, currentY, 0, sumtotal,nullptr);
//this value we insert in our openList
openList.insert(start->getXCoord() + (model->getCols()+1)*start->getYCoord(), start);
bool pathFound = false;
int i = 0;
int pathcost;
//do whil path is found
while(!pathFound){
QHashIterator<int, PathFinding*> iterator(openList);
PathFinding* parent;
iterator.next();
parent = iterator.value();
//we take the next tile, and we take the one with the lowest value
while(iterator.hasNext()){
iterator.next();
//checking lowest f value
if((iterator.value()->getGcost() + iterator.value()->getHcost()) < (parent->getGcost() + parent->getHcost())){
parent = iterator.value();
}
}
//here we check if we are at the destionation. if we are we return our pathcost.
if(atDestionation(parent,endPoint)){
pathFound = true;
while(parent->hasParent()){
mylist.append(parent);
parent = parent->getParent();
}
//we calculate what the pathcost is and return it
pathcost = calculatePathCost(mylist);
return pathcost;
}else{
int parent_x = parent->getXCoord();
int parent_y = parent->getYCoord();
i++;
clearLists(parent);
filllists(parent,endPoint);
}
}
}
将节点的值放在open&amp;关闭清单我这样做:
void Controller::filllists(PathFinding *parent,std::shared_ptr<Tile> endPoint)
{
int xPosNode = parent->getXPos();
int yPosNode = parent->getYPos();
//while found location
for(int x = -1; x < 2; x++) {
for(int y = -1; y <2; y++) {
int p_x = xPosNode + x;
int p_y = yPosNode + y;
// Is this coordinate within the world?
if(p_x >= 0 && p_x < model->getCols() && p_y >= 0 && p_y < model->getRows()) {
//we check if the tile exist (if it's no infinity tile)
if(model->tileExist(QPointF(p_x,p_y))){
// Already in open list > Check if current node is a better parent
if((!openList.value(p_x))+ (model->getCols() + 1)*(p_y)){
// Not in open and not in closed list > Possible candidate
if((!closedList.value(p_x))+ (model->getCols() + 1)*(p_y)){
int h_value = calculateHvalue(parent->getXCoord(),parent->getYCoord(),endPoint->getXPos(),endPoint->getYPos());
//int g_value = parent->getGcost() + calculateTileCost(parent->getXCoord(),parent->getYCoord(),p_x,p_y);
int g_value = calculateGvalue(parent, p_x, p_y);
std::shared_ptr<Tile> tile = model->getCoordinate(QPointF(p_x,p_y));
PathFinding* move = new PathFinding(tile,p_x, p_y, g_value, h_value, parent);
int number = move->getXCoord() + (model->getCols()+1)*move->getYCoord();
openList.insert(move->getXCoord() + (model->getCols()+1)*move->getYCoord(), move);
}
}
}
}
}
}
}
我的标题文件如下:
class Controller : public QObject
{
Q_OBJECT
public:
Controller(std::shared_ptr<Model> &modelPtr,std::shared_ptr<View> &viewPtr);
// void checkTile(QString position,PathFinding *parent, std::shared_ptr<Tile> endPoint, int pos);
void checkAboveTile(PathFinding *parent, std::shared_ptr<Tile> endPoint, int pos);
void checkBelowTile(PathFinding *parent, std::shared_ptr<Tile> endPoint, int pos);
void checkLeftTile(PathFinding *parent, std::shared_ptr<Tile> endPoint, int pos);
void checkRightTile(PathFinding *parent, std::shared_ptr<Tile> endPoint, int pos);
bool atDestionation(PathFinding *parent, std::shared_ptr<Tile> endPoint);
float calculateTileCost(int xposnew,int yposnew, int xpos, int ypos);
int calculateHvalue(int p_x,int p_y, int des_x, int des_y);
int calculateGvalue(PathFinding *parent, int x, int y);
void filllists(PathFinding *parent, std::shared_ptr<Tile> endPoint);
//QPair<QList<QPointF>, float> generatePath(Tile* endPoint);
//Openlist contains the nodes to be examined
QHash <int, PathFinding *> openList;
//ClosedList has the nodes that are already examined
QHash <int, PathFinding *> closedList;
QList<QPointF> pathlist;
void clearLists(PathFinding *parent);
QList<PathFinding*> mylist;
int calculatePathCost(QList<PathFinding*> mylist);
int findPathfindingNodes(int xdes, int ydes);
private:
std::shared_ptr<Model> model;
std::shared_ptr<View> view;
int heurCost;
signals:
void atDestination(int xPos,int yPos);
void gotoview(int xPos,int yPos);
public slots :
void goToDestination(int xDestination, int yDestination);
};
#endif // CONTROLLER_H
当我尝试输出行进的路径时,我可以看到它有时在mylist中放置相同的位置。
X1 value : 2 Y1 value : 3
X1 value : 1 Y1 value : 3
X1 value : 0 Y1 value : 3
X1 value : 1 Y1 value : 3
X1 value : 1 Y1 value : 3
X1 value : 2 Y1 value : 3
X1 value : 2 Y1 value : 4
X1 value : 3 Y1 value : 4
X1 value : 3 Y1 value : 4
X1 value : 3 Y1 value : 5
X1 value : 2 Y1 value : 6
X1 value : 2 Y1 value : 6
X1 value : 1 Y1 value : 6
X1 value : 0 Y1 value : 6
X1 value : 0 Y1 value : 7
X1 value : 0 Y1 value : 6
X1 value : 0 Y1 value : 5
这就是玩家走路的方式,可以看出他有时会再次使用同一个父母。
答案 0 :(得分:1)
if((!openList.value(p_x)) + (model->getCols() + 1)*(p_y))
很可能是真的
(向(model->getCols() + 1)*p_y
添加0或1可能非零。)if(!openList.value(p_x + (model->getCols() + 1)*p_y))
(与封闭名单相同。)我建议抽象出指数计算:
int index(shared_ptr<Model> model, int x, int y)
{
return x * (model->getCols() + 1)* y;
}
并使用它而不是容易出错的代码再现,例如
openList.insert(index(model, start->getXCoord(), start->getYCoord()), start);
// ...
if(!openList.value(index(model, p_x, p_y)))
在此过程中添加跟踪输出也是一个好主意。