如何解决为什么这个迷宫生成算法会产生单向道路?
我正在尝试编写一个算法来创建迷宫。算法 (DFS) 如下所示:
而且我不知道为什么算法会创建完整的车道而不是创建死胡同,使其看起来更像迷宫而不是单向道路。
我怀疑错误的随机选择、错误的回溯或算法将每个单元格标记为在递归步骤中访问过,导致没有死胡同,因为它无法返回到单元格,但我无法缩小问题的范围。 小迷宫似乎也会产生同样的问题。
代码:
std::vector<std::pair<int,int>> getAdjacentCells(Cell arr[N][M],int i,int j)
{
std::vector<std::pair<int,int>> neighbor_vec;
if(i-2 >= 0)
neighbor_vec.push_back(std::pair<int,int>(i-2,j));
if(i+2 < N)
neighbor_vec.push_back(std::pair<int,int>(i+2,j));
if(j-2 >= 0)
neighbor_vec.push_back(std::pair<int,int>(i,j-2));
if(j+2 < M)
neighbor_vec.push_back(std::pair<int,j+2));
return neighbor_vec;
}
void genMaze(Cell arr[N][M],int j)
{
// mark the current cell as visited
Cell &curCell = arr[i][j];
curCell.visited = true;
curCell.isWall = false;
// get a list of its neighbors
std::vector<std::pair<int,int>> neighbors = getAdjacentCells(arr,i,j);
// shuffle neighbor vector
std::random_shuffle( neighbors.begin(),neighbors.end() );
for(std::pair<int,int> coord : neighbors)
{
int x,y;
x = coord.first;
y = coord.second;
Cell &curNeighbor = arr[x][y];
if(!curNeighbor.visited) // remove wall inbetween given cell and neighbor
{
if(!(i-x)) // on the same column
{
if(j-y < 0) // right hand neighbor
{
arr[i][j+1].isWall = false;
return genMaze(arr,x,y);
}
else // left hand neighbor
{
arr[i][j-1].isWall = false;
return genMaze(arr,y);
}
}
else // not in the same column
{
if(i-x < 0) // bottom neighbor
{
arr[i+1][j].isWall = false;
return genMaze(arr,y);
}
else // top neighbor
{
arr[i-1][j].isWall = false;
return genMaze(arr,y);
}
}
}
}
arr[i][j].isEnd = true; // mark ending
}
单元类只包含标志。 它似乎与 post 算法相同(尽管问题不同):maze problem and Recursive backtracker algorithm
如有任何想法或解释,我将不胜感激。
解决方法
该算法生成单向路径,因为不包括其他路径的进一步生成。 创建第一个后需要进一步产生死胡同。在我实现的算法中,我没有考虑其他路径的进一步生成;
因此,当到达死胡同时,它需要通过路径回溯,直到到达一个有未访问邻居的单元格。然后它以新路径继续生成,直到到达死胡同。当访问完所有单元格的所有有效邻居时,这将停止。
在标记结束前添加的代码:
for(int a = 0; a < N; a++)
{
for(int b = 0; b < M; b++)
{
if(arr[a][b].visited) // for every visited cell in the maze,get their neighbors
{
std::vector<std::pair<int,int>> neighborOfCurCell = getAdjacentCells(arr,a,b);
int visitedNeighborCount = 0;
// for every neighbor,count the unvisited cells
for(auto neighbor : neighborOfCurCell)
{
Cell ¤tNeighbor = arr[neighbor.first][neighbor.second];
if(currentNeighbor.visited)
visitedNeighborCount++;
}
// if there is an unvisited neighbor after completing a path,backtrack with current cell
if(visitedNeighborCount < neighborOfCurCell.size())
return genMaze( arr,b );
}
}
}
示例:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。