迷宫这一小游戏,相信大家都不是过太陌生,可是会玩并不代表会用C++编写出来,呜呜~~
好滴,废话不多说,直接进入主题吧!!!
迷宫问题主要分为:
①如何寻找可通行的道路,即探测法
②进入死胡同后如何回退以便重新寻找通路, 即回溯法
首先,我们初始化并打印迷宫的地图,代码如下:
void InitMaze(int maze[][N], size_t n) //初始化迷宫图
{
FILE* fout = fopen("Maze.txt","r");
assert(fout);
for(size_t i=0; i<n; ++i)
{
for(size_t j=0; j<n; )
{
char ch = fgetc(fout);
if((ch == '0') || (ch == '1'))
{
maze[i][j] = ch - '0';
++j;
}
}
}
}
void PrintMaze(int maze[][N], size_t N) //打印迷宫图
{
for(size_t i=0; i<N; ++i)
{
for(size_t j=0; j<N; ++j)
{
cout<<maze[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
我们将每探测一步看作为探测迷宫地图上的一个坐标,故需要创建一个位置结点类,代码如下:
struct Pos //定义位置结点
{
size_t _row; //行
size_t _col; //列
};
在探测时,我们需要确定该位置结点是否是合格的,即需要判断坐标的合理性,代码如下:
bool CheckAccess(int maze[][N], size_t N, Pos pos) //判断坐标的位置是否合理
{
if(((pos._row>=0) && (pos._row<N))
&& ((pos._col>=0) && (pos._col<N))
&& (maze[pos._row][pos._col] == 0))
{
return true;
}
return false;
}
然后,我们利用探测法、回溯法寻找迷宫的通路,代码如下:
bool GetMazePath(int maze[][N], size_t N, Pos entry)
{
stack<Pos> path;
path.push(entry);
while(!path.empty())
{
Pos cur = path.top(); //当前所在迷宫的位置
maze[cur._row][cur._col] = 2; //将已走过的位置赋值为2
if(cur._row == N-1) //找到出口 方法: 1.出口给定迷宫地图的一个位置 2.出口给定迷宫地图的一行/列
{
return true;
}
Pos next = cur;
//探测该点的上方
next = cur;
next._row--;
if(CheckAccess(maze, N, next))
{
path.push(next);
continue;
}
//探测该点的右方
next = cur;
next._col++;
if(CheckAccess(maze, N, next))
{
path.push(next);
continue;
}
//探测该点的下方
next = cur;
next._row++;
if(CheckAccess(maze, N, next))
{
path.push(next);
continue;
}
//探测该点的左方
next = cur;
next._col--;
if(CheckAccess(maze, N, next))
{
path.push(next);
continue;
}
Pos top = path.top();
maze[top._row][top._col] = 3; //将回溯过的坐标记为3
path.pop();
}
return false;
}
这样就可以编写出一份简易迷宫代码,测试用例如下:
void TestMaze()
{
int maze[N][N];
InitMaze(maze, N);
PrintMaze(maze, N);
Pos entry;
entry._row = 2;
entry._col = 0;
GetMazePath(maze, N, entry);
PrintMaze(maze, N);
}
我们打印迷宫地图时,采用了文件的方式,如果有志同道合的人看到了这篇文章,想要动手操作一下的话,需要编写一份文本文件Maze.txt,并将它加载到项目的文件夹中,下图是样例。