我是一名学生,遇到了我似乎无法解决的问题。我有一个Terrain映射,它是一个包含整数和名称的枚举数组。
enum ETerrainCost
{
Clear = 1,
Water = 2,
Wood = 3,
Wall = 0
};
// Maps of any size are implemented as 2D vectors
using TerrainMap = vector<vector<ETerrainCost>>;
在加载地图并添加“开始”和“目标”坐标后,我正在使用A *运行寻路,但是由于某种原因,它是错误的,即使进行了检查也不会忽略Walls。
inline bool WallCheck(TerrainMap& terrain, unique_ptr<SNode>& node)
{
if (static_cast<int>(terrain[node->x][node->y]) == 0)
{
return true;
}
return false;
}
我看了多个视频,试图模仿伪代码,但我仍然无法弄清出哪里出了问题。这是搜索的代码:
此函数获取从调用代码传递的开始和目标指针的所有权。 最终没有返回所有权,因此消耗了开始和目标节点。 通过引用参数返回路径。
bool CSearchAStar::FindPath(deque<unique_ptr<SNode>>& openList, deque<unique_ptr<SNode>>& closedList,
TerrainMap& terrain, unique_ptr<SNode>& start, unique_ptr<SNode>& goal,
NodeList& path, int& counter)
{
unique_ptr <SNode> startNode(new SNode);
unique_ptr <SNode> currentNode(new SNode);
//For .erase() function
deque <unique_ptr <SNode> >::iterator myIt;
//North, East, South, West are the options to move
int rulesNumber = 4;
//Set start and calculate score(heuristic only)
startNode->x = start->x;
startNode->y = start->y;
startNode->parent = 0;
startNode->cost = 0;
startNode->heuristic = utility::NodeHeuristic(startNode, goal);
startNode->score = startNode->heuristic;
//Moved to the openList
openList.push_back(move(startNode));
//If it's the goal, return
if (start->x == goal->x && start->y == goal->y)
{
return true;
}
while (currentNode->x != goal->x || currentNode->y != goal->y)
{
//If there is no element to expand, return
if (openList.empty())
{
return false;
}
//Take an element from the openList and make
//it current to expand it's neighbors
currentNode = move(openList.front());
openList.pop_front();
//tempNode is identical to currentNode,
//and will be pushed into the closed list instead of it
//To be pushed to the closedList
unique_ptr <SNode> tempNode(new SNode);
tempNode->x = currentNode->x;
tempNode->y = currentNode->y;
tempNode->parent = currentNode->parent;
tempNode->cost = currentNode->cost;
tempNode->heuristic = currentNode->heuristic;
tempNode->score = currentNode->score;
for (int i = 0; i < rulesNumber; ++i)
{
unique_ptr <SNode> neighborNode(new SNode);
switch (i)
{
case 0:
neighborNode->x = currentNode->x;
neighborNode->y = currentNode->y + 1;
neighborNode->cost = utility::NodeCost(terrain, currentNode, neighborNode);
neighborNode->parent = currentNode.get();
neighborNode->heuristic = utility::NodeHeuristic(neighborNode, goal);
neighborNode->score = neighborNode->cost + neighborNode->heuristic;
//If it's a wall - skip it
if (utility::WallCheck(terrain, neighborNode))
{
break;
}
//If it's on one of the lists and it's score is heigher with this route - skip it
if ((utility::FindOnOpenList(neighborNode, openList, myIt) || utility::FindOnClosedList(neighborNode, closedList, myIt))
&& neighborNode->score >= currentNode->score)
{
break;
}
//If it's on one of the lists and has a lower score with this route -
//refer to it from now on and take it from the list
if (utility::FindOnOpenList(neighborNode, openList, myIt))
{
auto temp = myIt;
neighborNode = move((*myIt));
openList.erase(temp);
//Refresh the parent and get the cost changed for the old element
neighborNode->parent = currentNode.get();
neighborNode->cost = utility::NodeCost(terrain, currentNode, neighborNode);
neighborNode->heuristic = utility::NodeHeuristic(neighborNode, goal);
neighborNode->score = neighborNode->cost + neighborNode->heuristic;
}
else if (utility::FindOnClosedList(neighborNode, closedList, myIt))
{
break;
}
//Push back onto the openList
openList.push_back(move(neighborNode));
//Reorder OpenList by score(since either the cost of the node has been updated
//or it has been pushed onto the OpenList).
std::sort(openList.begin(), openList.end(), [](unique_ptr<SNode>& lhs,
unique_ptr<SNode>& rhs) { return lhs->score < rhs->score; });
counter++;
break;
与案例1、2和3相同,并且在for循环之后:
//Push current to the closedList
closedList.push_back(move(tempNode));
}
return true;
很抱歉,代码和消息太长了,我们非常欢迎您提供任何帮助和注释,甚至在代码样式方面。