2021-06-22

随机迷宫的生成

问题描述:迷宫指的是充满复杂通道,很难找到从入口或迷宫中某个位置到达出口的道路,道路复杂难辨,人进去不容易出来的事物。
要求:以二维数组模拟一-个矩形迷宫,利用随机深度优
先、随机广度优先或随机普里姆算法生成不含有回路的迷宫
并找到迷宫中任意两点的正确路径。

参考代码

#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、出现找的终点还在继续寻找路径现象,增加了一个判断变量,变量一旦改变,则函数停止,即在找到终点后,此变量值出现改变,使系统判断出终点已找到,程序停止。

收获体会
通过完成课程设计,我巩固了以前学过的知识,更深刻的理解了深度优先遍历与递归思想,懂得了理论与实践相结合的重要性,只有理论知识是远远不够的,理论知识是为将来的实践服务的,理论知识很重要,但是实践活动更重要。通过课程设计我看到自己实际操作能力的不足,知识理解不够深刻,掌握不够牢固。与同学合作和相关资料的帮助下,最终完成了小组课程设计。通过这次设计,我看到自身学习的不足,我决心在以后的学习过程中,要多锻炼自己处理实际问题的动手能力,要提高独立分析问题和解决问题的能力,多动手多上机操作。
以最少的成本、最快的速度、最好的质量开发出合适各种各样应用需求的软件,必须遵循软件工程的原则,设计出高效率的程序。一个高效的程序不仅需要编程技巧,更需要合理的数据组织和清晰高效的算法。这正是计算机科学领域里数据结构与算法设计所研究的主要内容。在计算机专业中算法分析与设计是一门非常重要的课程。很多问题的解决,程序的编写都要依赖它,所以学好这门课程对我们来说是受益匪浅的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值