迷宮的非遞歸實現(回溯法)
首先在項目工程所在文件夾下放入存有迷宮數據的文件Maze.txt,通過fopen("Maze.txt","r")讀取文件中的數據,並進行轉化。也可以在代碼中直接定義一個二維數組來構建迷宮。
我們採用回溯法來取得迷宮的通路,我們從給出的入口(entry)出開始根據上、下、左、右的方向試探,若有通路,則將當前位置壓入棧中並做上標記(2)。若走入一個死角(除來路,其他路皆不通),則原路返回並做上標(3)。
代碼實現如下:
#include<iostream>
#include<assert.h>
#include<stack>
using namespace std;
#pragma warning (disable:4996)
const static size_t N = 10;
void Initmaze(int maze[][N], size_t n)//從文件中讀取數據,初始化迷宮
{
FILE *file = fopen("Maze.txt", "r");
assert(file);
for (size_t i = 0; i < n; i++)
{
for (size_t j = 0; j < n;)
{
char ch = fgetc(file);
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 Access(int maze[][N], size_t n, Pos next)//判斷位置是否合法及是否是通路
{
if (next._row<n && next._row>0
&& next._col<n && next._col>0
&& maze[next._row][next._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();
if (cur._row == n - 1)
{
return true;
}
Pos next = cur;
maze[cur._row][cur._col] = 2;//將走過的路標記爲2
//上
next = cur;
next._row--;
if (Access(maze, n, next))
{
path.push(next);
continue;
}
//下
next = cur;
next._row++;
if (Access(maze, n, next))
{
path.push(next);
continue;
}
//左
next = cur;
next._col--;
if (Access(maze, n, next))
{
path.push(next);
continue;
}
//右
next = cur;
next._col++;
if (Access(maze, n, next))
{
path.push(next);
continue;
}
Pos top = path.top();
maze[top._row][top._col] = 3;//重複走過的路標記爲3
path.pop();
}
return false;
}
int main()
{
int maze[N][N];
Pos entry;
entry._row = 3;
entry._col = 0;
Initmaze(maze, N);
Printmaze(maze, N);
GetMazePath(maze, N, entry);
Printmaze(maze, N);
system("pause");
return 0;
}