随机迷宫的生成
问题描述:迷宫指的是充满复杂通道,很难找到从入口或迷宫中某个位置到达出口的道路,道路复杂难辨,人进去不容易出来的事物。
要求:以二维数组模拟一-个矩形迷宫,利用随机深度优
先、随机广度优先或随机普里姆算法生成不含有回路的迷宫
并找到迷宫中任意两点的正确路径。
参考代码:
#include<stdio.h>
#include<windows.h>
#include<time.h>
#define N 2
#define M N*50
#define UPDATETIME 30
int map[M + 1][M + 1] = { 0 };
int count;
int Find = 0;
int dir[4][2] = {
{-1,0},
{1,0},
{0,-1},
{0,1}
};
renum state
{
wall,
empty,
self,
end,
testFlag
};
char info[][3] = {
"[]",//墙壁
" ",//空地
"人",//玩家
"☆",//终点
"◇",//测试图案
};
int my_x, my_y;
void Init(int count);
void CreateMaze(int x,int y);
int InArea(int x,int y);
void print(int x,int y);
int Run();
void menu();
void Pos(int x, int y);
int Seek(int x,int y);
int Neighbor(int x, int y);
int main(void)
{
int flag = 0;
srand((unsigned)time(NULL));
menu();
Init(count);
while (1)
{
flag = Run();
if (flag == 1 || flag == -1)
return 0;
}
return 0;
system("pause");
return 0;
}
int InArea(int x,int y)
{
if(x > 0 && x < count-1 && y > 0 && y < count-1)
return 1;
return 0;
}
int Seek(int x,int y)
{
int i,r = 0;
for(i = 0;i < 4;++i)//依次探索4个方向
{
if(Find == 1)
return 1;
if(!InArea(x + dir[i][0],y + dir[i][1]) || map[x+dir[i][0]][y+ dir[i][1]] == 7)
continue;
if(map[x+dir[i][0]][y+ dir[i][1]] == empty)
{
map[x + dir[i][0]][y + dir[i][1]] = testFlag;
print(x,y);
Sleep(UPDATETIME);
if(Find = Seek(x+dir[i][0],y+dir[i][1]))
return 1;
map[x + dir[i][0]][y + dir[i][1]] = 7;
print(x,y);
}
else if(map[x+dir[i][0]][y+dir[i][1]] == end)
return 1;
}
return 0;
}
void CreateMaze(int x,int y)
{
int i;
while(Neighbor(x,y))
{
i = rand()%4;
if(InArea(x + 2 * dir[i][0],y + 2 * dir[i][1]) &&
map[x+2 * dir[i][0]][y+2 * dir[i][1]] == empty)
{
map[x + dir[i][0]][y + dir[i][1]] = testFlag;
map[x+2 * dir[i][0]][y+2 * dir[i][1]] = testFlag;
print(x + dir[i][0],y + dir[i][1]);
Sleep(UPDATETIME);
CreateMaze(x+2 * dir[i][0],y+2 * dir[i][1]);
}
}
}
int Neighbor(int x, int y)
{
int i = 0,flag = 0;
for(i = 0;i < 4;++i)
if(InArea(x + 2 * dir[i][0],y + 2 * dir[i][1]) && map[x + 2 * dir[i][0]][y + 2 * dir[i][1]] == empty)
{
flag = 1;
break;
}
return flag;
}
void Init(int num)
{
int i, j;
my_x = my_y = 1;//开始位置
if (num % 2 == 0)
count++;
for (i = 0;i < count;i++)
for (j = 0;j < count;j++)
map[i][j] = wall;
for (i = 1;i < count - 1;i++)//将奇数点变成空地
{
for (j = 1;j < count - 1;j++)
{
if (i % 2 != 0 && j % 2 == 1)
map[i][j] = empty;
}
}
for (i = 0;i < count;++i)
{
for (j = 0;j < count;j++)
{
print(i,j);
}
}
CreateMaze(my_x,my_y);//创造迷宫
for (i = 0;i < count;i++)
{
for (j = 0;j < count;j++)
if (map[i][j] == testFlag)
map[i][j] = empty;
}
my_x=my_y=rand()%(count-2)+1;
map[my_x][my_y] = self;//设置随机起点
i=j=rand()%(count-2)+1;
map[i][j] = end;//设置随机终点
for (i = 0;i < count;++i)
{
for (j = 0;j < count;j++)
{
print(i,j);
}
}
}
void Pos(int x, int y)
{
COORD pos;
HANDLE hOutput;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, pos);
}
void print(int x,int y)
{
int i = 0;
Pos(y*2,x);
printf("%s",info[map[x][y]]);
for(i = 0;i < 4;++i)
{
if(InArea(x + dir[i][0],y + dir[i][1]))
{
Pos(2* (y+ dir[i][1]),x + dir[i][0]);
if(map[x + dir[i][0]][y + dir[i][1]] < 5)
printf("%s",info[map[x + dir[i][0]][y + dir[i][1]]]);
else if(map[x + dir[i][0]][y + dir[i][1]] == 7)
printf("%s",info[1]);
}
}
}
int Run()
{
Seek(my_x,my_y);
return 0;
}
void menu()
{
char select[10];
printf("按Esc退出\n");
printf("请输入地图大小:");
scanf("%d", &count);
system("cls");
编写中遇到的问题:
1、在寻找路径时,遇到了无限循环的错误,后来发现是回溯后系统不知道曾经探索过此路径,后来增加了一个探索标记函数,回溯过的路径系统能判断出,即所有被探索过的路径系统将自动识别,则不会出现无限循环情况。
2、出现找的终点还在继续寻找路径现象,增加了一个判断变量,变量一旦改变,则函数停止,即在找到终点后,此变量值出现改变,使系统判断出终点已找到,程序停止。
收获体会
通过完成课程设计,我巩固了以前学过的知识,更深刻的理解了深度优先遍历与递归思想,懂得了理论与实践相结合的重要性,只有理论知识是远远不够的,理论知识是为将来的实践服务的,理论知识很重要,但是实践活动更重要。通过课程设计我看到自己实际操作能力的不足,知识理解不够深刻,掌握不够牢固。与同学合作和相关资料的帮助下,最终完成了小组课程设计。通过这次设计,我看到自身学习的不足,我决心在以后的学习过程中,要多锻炼自己处理实际问题的动手能力,要提高独立分析问题和解决问题的能力,多动手多上机操作。
以最少的成本、最快的速度、最好的质量开发出合适各种各样应用需求的软件,必须遵循软件工程的原则,设计出高效率的程序。一个高效的程序不仅需要编程技巧,更需要合理的数据组织和清晰高效的算法。这正是计算机科学领域里数据结构与算法设计所研究的主要内容。在计算机专业中算法分析与设计是一门非常重要的课程。很多问题的解决,程序的编写都要依赖它,所以学好这门课程对我们来说是受益匪浅的。