这是我的代码。
#include <iostream>
using namespace std;
enum Direction { EAST, NORTH, WEST, SOUTH };
const int size = 12;
int xStart = 2; int yStart = 0;
char *maze2[ ] = {
"############",
"#...#......#",
"..#.#.####.#",
"###.#....#.#",
"#....###.#..",
"####.#.#.#.#",
"#..#.#.#.#.#",
"##.#.#.#.#.#",
"#........#.#",
"######.###.#",
"#......#...#",
"############",
};
void printMaze ( char maze[][ size ] );
void mazeTraverse( char maze[][ size ], int x, int y, int direction );
int main()
{
char maze[ size ][ size ];
for (int x = 0; x < size; x++ )
for (int y = 0; y < size; y++)
maze[ x ][ y ] = maze2[ x ][ y ];
printMaze( maze );
mazeTraverse( maze, xStart, yStart, EAST);
}
void printMaze ( char maze[][ size ] )
{
for ( int x = 0; x < size; x++)
{
for ( int y = 0; y < size; y++)
cout << maze[ x ][ y ];
cout << endl;
}
cout << endl;
cout << "\nHit return to see next move\n";
cin.get();
}
bool validMove( char maze[][ size ], int x, int y )
{
return x >= 0 && x < size && y >= 0 && y < size && maze[x][y] != '#';
}
bool coordsAreEdge( int x, int y )
{
return x== 0 || x== size - 1 || y == 0 || y== size - 1;
}
void mazeTraverse( char maze[][ size ], int x, int y, int direction )
{
maze[ x ][ y ] = 'x';
printMaze( maze );
if (coordsAreEdge(x, y) && (x != xStart || y!= yStart ))
{
cout <<"\nMaze successfully exited!\n\n";
return;
}else{
for ( int move = direction, count = 0; count < 4;
count++, move++, move %=4 )
{
int nextX; int nextY;
switch ( move )
{
case SOUTH: nextX = x + 1; nextY = y; break;
case EAST: nextX = x; nextY = y + 1; break;
case NORTH: nextX = x - 1; nextY = y; break;
case WEST: nextX = x; nextY = y - 1; break;
default: ;
}
if (validMove( maze, nextX, nextY ))
{
//Recursion move part 1
//mazeTraverse ( maze, nextX , nextY, (move + 3)%4 );
return;
}
}
}
}
我正在尝试使我的void mazeTraverse函数成为一个while循环,而不是递归而且我被卡住了。
答案 0 :(得分:2)
创建一个结构来保存X,Y和方向(调用之间改变的三件事)。我们称之为结构State
;
创建一个std::stack<State>
对象。在更改之前将X,Y,方向的当前值推入堆栈,在完成工作后弹出它们。
因此
while(.....)
{
push state
Do work of mazeTraverse
pop state
}
答案 1 :(得分:0)
如果您描述遍历的工作方式,那将会很棒。如果我没有错误地阅读代码,那么你基本上是在任何不包含#的位置向南/东/北/向西移动,并且在矩阵的范围内。
您可以使用BF搜索迭代地执行此操作:http://en.wikipedia.org/wiki/Breadth-first_search或应用于矩阵的Lee算法:http://en.wikipedia.org/wiki/Lee_algorithm可以使用FIFO队列高效实现,我将其描述如何在这里:Change FloodFill-Algorithm to get Voronoi Territory for two data points?
您的validMove函数将保持不变:仅当该位置有效时才向队列添加位置。基本上所有检查都保持不变,只是你使用FIFO队列来保存状态而不是隐式堆栈。
答案 2 :(得分:0)
您可以使用广度优先搜索,而不是使用标准queue
和while
循环。
typedef pair<int, int> Point;
queue<Point> path;
Point start(xStart, yStart);
path.push(start);
const int move_x[] = {-1, 0, 1, 0};
const int move_y[] = {0, -1, 0, 1};
while (!path.empty())
{
Point p = path.front();
int x = p.first, y = p.second;
maze[x][y] = 'x';
path.pop();
if (coordsAreEdge(x,y) && p != start)
{
// Finished
break;
}
for (int i = 0; i < 4; ++i)
{
int newx = x + move_x[i];
int newy = y + move_y[i];
if (validMove(maze, newx, newy))
path.push(Point(newx, newy));
}
}
这应该可以解决问题。请注意,它未经测试。
您可以使用A *来改善其性能,但这有点复杂。如果您需要从此代码中找到最短路径,请告诉我。
编辑:请注意,如果您将queue
更改为stack
(并将path.front()
更改为path.top()
),那么您将获得深度优先搜索(DFS)而是,这是你的代码所做的。但是,DFS找不到最短路径(如果有必要)。