所谓迷宫,就是在一个矩阵中,从开始位置有一条通路可以走到最末尾的位置
先画一个迷宫,格式为txt,和编译的文件夹放在一起
在迷宫中,0表示可以走通的路,而1则表示不可走通的墙
首先定义一个结构体,用来存放行和列
struct Pos
{
size_t row;
size_t col;
};
接下来从文件中获得迷宫 的矩阵
void GetMaze(int *maze, size_t N)
{
FILE *fp = fopen("MazeMap.txt", "r");
if (fp == NULL)
{
throw invalid_argument("Read maze filed");
}
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < N;)
{
char ch = fgetc(fp);
if (ch == '0' || ch == '1')
{
maze[i*N + j] = ch - '0';
}
else if (ch == EOF)
{
throw invalid_argument("Maze Error");
}
}
}
}
然后就要判断迷宫中的每一个坐标的路是否为通路
bool CheckIsAccess(int* maze, size_t N, Pos next)
{
if (maze[next.row*N + next.col] == 0)
{
return true;
}
return false;
}
接下俩对于路径的求解的算法有两种方法,递归和非递归
非递归求解:
bool GetMazePath(int *maze, size_t n, Pos entry, stack<Pos>&path)
{
maze[entry.row*N + entry.col] = 2;
Pos cur, next;
cur = entry;
path.push(entry);
while (!path.empty())
{
cur = path.top();
if (cur.row == N - 1)
{
return true;
}
next = cur;
next.row += 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.row -= 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.col += 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.col -= 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
path.pop();
}
return false;
}
用递归的方法:
void GetMazePath_R(int *maze, size_t N,Pos entry, stack<Pos>&path,stack<Pos>&shortpath)
{
if (entry.row == N - 1)
{
if (path.size() < shortpath.size() || shortpath.size() == 0)
{
shortpath = path;
}
path.pop();
return;
}
Pos cur, next;
cur = entry;
next = cur;
next.row += 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R(maze, N, next, path, shortpath);
}
next = cur;
next.row -= 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R((int*)maze, N, next,path, shortpath);
}
next.col += 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R((int*)maze, N, next, path, shortpath);
}
next.col -= 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + next.col] + 1;
GetMazePath_R((int*)maze, N, next, path, shortpath);
}
path.pop();
}
其中的-=1和+=1是表示在一个位置处有四个方向,通过行和列的+1和-1来表示这四个方向。
下面就是完整的代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<stack>
const int N = 10;
struct Pos
{
size_t row;
size_t col;
};
void PrintMaze(int *maze, size_t N)
{
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < N; ++j)
{
cout << maze[i*N + j] << " ";
}
cout << endl;
}
cout << endl;
}
bool CheckIsAccess(int *maze, size_t N, Pos next)
{
if (maze[next.row*N + next.col] == 0)
{
return true;
}
return false;
}
bool CheckIsAccess(int *maze, size_t N, Pos next, Pos cur)
{
if (next.row < 0 || next.row >= N || next.col < 0 || next.col >= N)
{
return false;
}
if (maze[next.row*N + next.col] == 0)
{
return true;
}
return(maze[next.row*N + next.col]>(maze[cur.row*N + next.col] + 1));
}
void GetMaze(int *maze, size_t N)
{
FILE *fp = fopen("MazeMap.txt", "r");
if (fp == NULL)
{
throw invalid_argument("Read maze filed");
}
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < N;)
{
char ch = fgetc(fp);
if (ch == '0' || ch == '1')
{
maze[i*N + j] = ch - '0';
++j;
}
else if (ch == EOF)
{
throw invalid_argument("Maze Error");
}
}
}
}
bool GetMazePath(int *maze, size_t n, Pos entry, stack<Pos>&path)
{
maze[entry.row*N + entry.col] = 2;
Pos cur, next;
cur = entry;
path.push(entry);
while (!path.empty())
{
cur = path.top();
if (cur.row == N - 1)
{
return true;
}
next = cur;
next.row += 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.row -= 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.col += 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
next.col -= 1;
if (CheckIsAccess((int*)maze, N, next) == true)
{
path.push(next);
maze[next.row*N + next.col] = 2;
continue;
}
next = cur;
path.pop();
}
return false;
}
void GetMazePath_R(int *maze, size_t N,Pos entry, stack<Pos>&path,stack<Pos>&shortpath)
{
if (entry.row == N - 1)
{
if (path.size() < shortpath.size() || shortpath.size() == 0)
{
shortpath = path;
}
path.pop();
return;
}
Pos cur, next;
cur = entry;
next = cur;
next.row += 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R(maze, N, next, path, shortpath);
}
next = cur;
next.row -= 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R((int*)maze, N, next,path, shortpath);
}
next.col += 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + cur.col] + 1;
GetMazePath_R((int*)maze, N, next, path, shortpath);
}
next.col -= 1;
if (CheckIsAccess((int*)maze, N, next, cur) == true)
{
path.push(next);
maze[next.row*N + next.col] = maze[cur.row*N + next.col] + 1;
GetMazePath_R((int*)maze, N, next, path, shortpath);
}
path.pop();
}
void ReMaze(int* maze)
{
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < N; ++j)
{
if (maze[i*N + j] != 1)
{
maze[i*N + j] = 0;
}
}
}
}
stack<Pos>MinPath()
{
int maze[N][N] = { 0 };
int curmaze[N][N] = { 0 };
GetMaze((int*)maze, N);
stack<Pos>path, MinPath, empty;
while (GetMazePath((int*)maze, N, { 0, 0 }, path))
{
if (path.size() < MinPath.size()||MinPath.size() == 0)
{
MinPath = path;
}
ReMaze((int*)maze);
maze[path.top().row][path.top().col] = 1;
path = empty;
}
return MinPath;
}
void Test()
{
try
{
int maze[N][N] = { 0 };
int curmaze[N][N] = { 0 };
GetMaze((int*)maze, N);
stack<Pos>path, shortpath;
path.push({ 0, 0 });
GetMazePath_R((int*)maze, N, { 0, 0 }, path, shortpath);
cout << shortpath.size() << endl;
}
catch (exception &e)
{
cout << e.what() << endl;
}
}
int main()
{
Test();
system("pause");
return 0;
}