#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<conio.h>
#include<graphics.h>
#include <random>
#include <functional>
#define MaxSize 10010
#define side 101
using namespace std;
typedef struct
{
int x, y, la;
}position;
typedef struct {
position data[MaxSize];
int front, rear;
}Queue;
char maze[side][side] = {};
char maze1[side][side] = {};
int dy[4] = { 1,0,-1,0 };
int dx[4] = { 0,1,0,-1 };
bool fi[side][side] = { };
int m, n;
int way_proportion = 70;
bool find_ = true;
void create_Maze();//创建迷宫
void print_maze();//输出迷宫
void reduction_maze();//还原迷宫/赋值副本
void initialize_maze();//初始化墙
void initQueue(Queue& que);
void enQueue(Queue& q, position d);
void deQueue(Queue& q);
void dfs_find_way(int x, int y);
void bfs_find_way();
void getsize();//获取m,n
void create_maze_dfs(int x,int y);
void dfs_create(int row, int col);
void mgpath(int xi, int yi, int xe, int ye);
struct Node {
int x; // 当前节点的 x 坐标
int y; // 当前节点的 y 坐标
int dir; // 下一个坐标方向
Node* next; // 指向下一个节点的指针
};
class LinkedStack {
private:
Node* top; // 栈顶节点指针
public:
LinkedStack() {
top = nullptr;
}
bool isEmpty() {
return top == nullptr;
}
void push(int x, int y, int dir) {
Node* newNode = new Node;
newNode->x = x;
newNode->y = y;
newNode->dir = dir;
newNode->next = top;
top = newNode;
}
void pop() {
if (isEmpty()) {
return;
}
Node* temp = top;
top = top->next;
delete temp;
}
Node* getTop() {
return top;
}
};
//寻路8
void mgpath(int startX, int startY, int endX, int endY) {
LinkedStack stack;
stack.push(startX, startY, 0);
maze1[startX][startY] =maze1[endX][endY]= ' ';
bool foundPath = false;
while (!stack.isEmpty()) {
Node* top = stack.getTop();
int x = top->x;
int y = top->y;
int dir = top->dir;
// 到达终点
if (x == endX && y == endY) {
// 打印路径
maze1[1][1] = 'S';
maze1[m - 2][n - 2] = 'E';
print_maze();
cout << "路径: ";
while (!stack.isEmpty()) {
Node* node = stack.getTop();
cout << "(" << node->x << "," << node->y << ") ";
stack.pop();
}
cout << endl;
foundPath = true;
break;
}
bool found = false;
// 尝试四个方向的移动:右、下、左、上
for (int i = dir; i < 4; i++) {
if (i == 0 && y + 1 < n && maze1[x][y + 1] == ' ') {
stack.push(x, y + 1, 0); // 向右走
maze1[x][y + 1] = '@';
found = true;
break;
}
else if (i == 1 && x + 1 < m && maze1[x + 1][y] == ' ') {
stack.push(x + 1, y, 0); // 向下走
maze1[x + 1][y] = '@';
found = true;
break;
}
else if (i == 2 && y - 1 >= 0 && maze1[x][y - 1] == ' ') {
stack.push(x, y - 1, 0); // 向左走
maze1[x][y - 1] = '@';
found = true;
break;
}
else if (i == 3 && x - 1 >= 0 && maze1[x - 1][y] == ' ') {
stack.push(x - 1, y, 0); // 向上走
maze1[x - 1][y] = '@';
found = true;
break;
}
}
if (!found) {
// 如果四个方向都不能移动,回溯
stack.pop();
maze1[x][y] = 'V';
}
else {
// 更新下一个坐标方向
top->dir = dir + 1;
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 设置控制台窗口缓冲区大小
COORD bufferSize = { 120, 120 };
SetConsoleScreenBufferSize(hOut, bufferSize);
print_maze();
}
if (!foundPath) {
// 没有找到路径
cout << "没有找到路径" << endl;
}
}
//改比例
void change_way_proportion()
{
while (1)
{ cout << "请输入路径比例" << endl;
cin >> way_proportion;
if (way_proportion <= 0 || way_proportion > 99)
{
cout << "数值不规范" << endl;
continue;
}
break;
}
create_Maze();
print_maze();
return;
}
//初始化
void initialize_maze()//初始化
{
for (int i = 0;i < m;i++)
{
for (int j = 0;j < n;j++)
{
maze[i][j] = '#';
}
}
maze[1][1] = 'S';
maze[m - 2][n - 2] = 'E';
}//初始化迷宫
int IsHaveNeighbor(int X_index, int Y_index)//判断是否有邻居
{
if ((X_index >= 3 && maze[X_index - 2][Y_index] == '#') || (X_index < m - 3 && maze[X_index + 2][Y_index] == '#') || (Y_index >= 3 && maze[X_index][Y_index - 2] == '#') || (Y_index < n - 3 && maze[X_index][Y_index + 2] == '#'))
return 1;//有邻居
return 0;
}
void dfs_create(int X_index, int Y_index){
int rand_position, x, y, flag = 0;
x = X_index;
y = Y_index;
//如果四个方向都没有了,返回上一步的xy,否则,继续
while (1)
{
flag = IsHaveNeighbor(X_index, Y_index);
if (flag == 0)
{
return;//返回该函数的上一条
}
else
{
maze[X_index][Y_index] =' ';
while (1)
{
rand_position = rand() % 4;
if (rand_position == 0 && X_index >= 3 && maze[X_index - 2][Y_index] == '#')//上
{
X_index = X_index - 2;
}
else if (rand_position == 1 && X_index < m- 3 && maze[X_index + 2][Y_index] == '#')//下
{
X_index = X_index + 2;
}
else if (rand_position == 2 && Y_index >= 3 && maze[X_index][Y_index - 2] == '#')//左
{
Y_index -= 2;
}
else if (rand_position == 3 && Y_index < n - 3 && maze[X_index][Y_index + 2] == '#')//右
{
Y_index += 2;
}
maze[(x + X_index) / 2][(y + Y_index) / 2] =' ';//当前位置,移动后位置中间位置打通,表示路径
maze[X_index][Y_index] = ' ';
dfs_create(X_index, Y_index);
break;
}
}
}
}
void create_maze_dfs(int rows,int columns)
{
initialize_maze();
random_device rd;
mt19937 generator(rd());
int start_row = generator() % rows;
int start_col = generator() % columns;
dfs_create( start_row, start_col); // 调用DFS算法生成迷宫
maze[1][2] = ' ';
maze[2][1] = ' ';
maze[m-2][n-3] = ' ';
maze[m-3][n-2] = ' ';
maze[1][1] = 'S';
print_maze();
}
void deQueue(Queue& q)
{
q.front++;
}
void enQueue(Queue& q, position d)
{
q.data[q.rear] = d;
q.rear++;
}
void initQueue(Queue& que) {
que.front = que.rear = 0;
}
void reduction_maze()
{
for (int i = 1; i < m - 1; ++i) {
for (int j = 1; j < n - 1; ++j)
{
maze1[i][j] = maze[i][j];
}
}
print_maze();
}
void print_maze()
{
Sleep(20);
system("cls");
int i = 0, j = 0;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
if (maze1[i][j] == 'S'|| maze1[i][j] == 'E')
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
cout << "█ ";
}
else if (maze1[i][j] == '#')
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
cout << "█ ";
}
else if (maze1[i][j] == ' ')
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
cout << "█ ";
}
else if (maze1[i][j] == 'V')
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
cout << "█ ";
}
else if (maze1[i][j] == '@')
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
cout << "█ ";
}
// cout << maze1[i][j] << " ";
}
cout << endl;
}
cout<< "***********星树***************" << endl
<< "* 输入1重新随机生成迷宫 *" << endl
<< "* 输入2生成基于DFS迷宫 *" << endl
<< "* 输入3还原迷宫 *" << endl
<< "* 输入4深搜 *" << endl
<< "* 输入5广搜 *" << endl
<< "* 输入6修改迷宫大小 *" << endl
<< "* 输入7修改可行路径比例 *" << endl
<< "* 输入8非递归寻路 *" << endl
<< "* 输入q退出 *" << endl
<< "******************************" << endl;
//system("pause");
}
void create_Maze() {
// 初始化迷宫为墙
initialize_maze();
// 随机生成路径
srand(time(NULL));
for (int i = 1; i < m - 1; i++) {
for (int j = 1; j < n - 1; j++) {
// 生成0~99之间的随机数
int randomNumber = rand() % 100;
if (randomNumber < way_proportion&& maze[i][j]=='#') { // 50%的概率生成路径
maze[i][j] = ' ';
}
}
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j)
{
maze1[i][j] = maze[i][j];
}
}
}
void dfs_find_way(int x, int y)
{
if (find_)
{
return;
}
else {
for (int i = 0;i < 4;i++)
{
int nextx = x + dx[i], nexty = y + dy[i];
if (maze1[nextx][nexty] == 'E')
{
find_ = true;
return;
}
if (maze1[nextx][nexty] == ' ' && !fi[nextx][nexty] && !find_)
{
maze1[nextx][nexty] = '@';
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 设置控制台窗口缓冲区大小
COORD bufferSize = { 120, 120 };
SetConsoleScreenBufferSize(hOut, bufferSize);
print_maze();
fi[nextx][nexty] = true;
dfs_find_way(nextx, nexty);
if (!find_)
maze1[nextx][nexty] = 'V';
}
}
}
}
void bfs_find_way()
{
reduction_maze();
Queue que;
position d;
d.x = 1;
d.y = 1;
d.la = 0;
initQueue(que);
enQueue(que, d);
while (que.front != que.rear)
{
auto fr = que.data[que.front];
for (int i = 0;i < 4;i++)
{
d.x = fr.x + dx[i];
d.y = fr.y + dy[i];
if (maze1[d.x][d.y] == ' ')
{
d.la = que.front;
enQueue(que, d);
maze1[d.x][d.y] = 'V';
}
if (maze1[d.x][d.y] == 'E')
{
int lt = que.front;
while (que.data[lt].la != 0) {
maze1[que.data[lt].x][que.data[lt].y] = '@';
lt = que.data[lt].la;
}
maze1[que.data[lt].x][que.data[lt].y] = '@';
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 设置控制台窗口缓冲区大小
COORD bufferSize = { 120, 120 };
SetConsoleScreenBufferSize(hOut, bufferSize);
print_maze();
cout << "已找到路径" << endl;
return;
}
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 设置控制台窗口缓冲区大小
COORD bufferSize = { 120,120 };
SetConsoleScreenBufferSize(hOut, bufferSize);
print_maze();
deQueue(que);
}
cout << "无路径" << endl;
return;
}
void getsize()
{
while (1)
{
cout << "请输入迷宫的长(5-100):" << endl;
cin >> m;
cout << "请输入迷宫的宽(5-100):" << endl;
cin >> n;
if (m <=4 || n <=4)
{
cout << "迷宫太小了";
continue;
}
if (m >= 100 || n >= 100)
{
cout << "迷宫太大了";
continue;
}
break;
}
}
int main()
{
while (1)
{
getsize();
create_Maze();
print_maze();
while (true)
{
char c;
cin >> c;
switch (c)
{
case '1'://重新生成迷宫
create_Maze();
print_maze();
break;
case'2'://dsf生成
create_maze_dfs(m,n);
reduction_maze();
break;
case'3'://还原迷宫
reduction_maze();
break;
case'4'://dfs
reduction_maze();
find_ = false;
memset(fi, false, sizeof(fi));
dfs_find_way(1, 1);
if (!find_)
cout << "无路径" << endl;
else
cout << "已找到路径" << endl;
break;
case'5'://bfs
bfs_find_way();
break;
case'6'://改尺寸
getsize();
create_Maze();
print_maze();
break;
case'7'://改比例
change_way_proportion();
create_Maze();
break;
case'8':
reduction_maze();
mgpath(1,1,m - 2, n - 2);
break;
case'q'://退出
return 0;
default:
string error_in;
cin >> error_in;
cout << "输入错误" << endl;
break;
}
}
}
}
‘#’为墙
‘@’为路径
‘S'E’分别为起点终点
‘V’为可到达的点