失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 手动搜索迷宫游戏 c语言 C语言实现一个走迷宫小游戏(深度优先算法)

手动搜索迷宫游戏 c语言 C语言实现一个走迷宫小游戏(深度优先算法)

时间:2018-09-08 20:31:04

相关推荐

手动搜索迷宫游戏 c语言 C语言实现一个走迷宫小游戏(深度优先算法)

接上一篇万年历博文,还是那位朋友的练习题。这次是使用C语言做一个小游戏程序,三选一(2048、8皇后和迷宫游戏),我选择的是迷宫(文章末尾有程序截图)。个人认为这个程序的难点在于迷宫地图的绘制,也就是怎么建立一个迷宫。如果迷宫地图是在程序里写死的,那可玩性就大大降低了。那么能不能像正常游戏一样生成一个随机地图呢?当然有!在网上查到的结果不外乎这三种:深度优先算法、prim算法和递归分割算法。这三种算法的优劣比较可前往这篇博文一探究竟:

至于代码实现我参考的是博主jjwwwww的三篇迷宫算法文章的第一篇,全部文章的链接如下:

下面来看一下思路和代码:

维基百科中给出的深度优先(递归回溯)算法思路如下:

1.将起点作为当前迷宫单元并标记为已访问

2.当还存在未标记的迷宫单元,进行循环

1.如果当前迷宫单元有未被访问过的的相邻的迷宫单元

1.随机选择一个未访问的相邻迷宫单元

2.将当前迷宫单元入栈

3.移除当前迷宫单元与相邻迷宫单元的墙

4.标记相邻迷宫单元并用它作为当前迷宫单元

2.如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空

1.栈顶的迷宫单元出栈

2.令其成为当前迷宫单元

如果你觉得上面这个表述不太容易理解,那么来看看下面这个思路(还是上面那个博主的,也是我的代码采用的):

首先假设迷宫只有一条正确的道路。

假设自己是一只地鼠,要在这个区域不停的挖,直到任何一块区域再挖就会挖穿了为止。

我们挖的道路就像树结构,树上有很多的分支,分支也有子分支,每个子分支都不能相交,相交了就说明墙被挖穿了,那么此时的迷宫就可能存在多条正确道路,这不是我想看到的。

那么基于唯一道路的原则,我们向某个方向挖一块新的区域时,要先判断新区域是否有挖穿的可能,如果可能挖穿要立即停止并换个方向再挖。如图:

有了思路,就有了下面的代码,创建迷宫:

1 void CreateMaze(int **maze, int x, int y) {//构建迷宫

2 maze[x][y] = ROUTE;

3 //确保四个方向随机,而不再是固定的上下左右这种排列

4 int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,-1 },{ 0,1 } };

5 for (int i = 0; i < 4; i++) {

6 int r = rand() % 4;

7 int temp = direction[0][0];

8 direction[0][0] = direction[r][0];

9 direction[r][0] = temp;

10 temp = direction[0][1];

11 direction[0][1] = direction[r][1];

12 direction[r][1] = temp;

13 }

14 //向四个方向开挖

15 for (int i = 0; i < 4; i++) {

16 int dx = x;

17 int dy = y;

18 //控制挖的距离,由Rank来调整大小

19 int range = 1 + (Rank == 0 ? 0 : rand() % Rank);

20 while (range > 0) {

21 //计算出将要访问到的坐标

22 dx += direction[i][0];

23 dy += direction[i][1];

24 //排除掉回头路

25 if (maze[dx][dy] == ROUTE) {

26 break;

27 }

28 //判断是否挖穿路径

29 int count = 0;

30 for (int j = dx - 1; j < dx + 2; j++) {

31 for (int k = dy - 1; k < dy + 2; k++) {

32 //abs(j - dx) + abs(k - dy) == 1 确保只判断九宫格的四个特定位置

33 if (abs(j - dx) + abs(k - dy) == 1 && maze[j][k] == ROUTE) {

34 count++;

35 }

36 }

37 }

38 //count大于1表明墙体会被挖穿,停止

39 if (count > 1)

40 break;

41 //确保不会挖穿时,前进

42 range -= 1;

43 maze[dx][dy] = ROUTE;

44 }

45 //没有挖穿危险,以此为节点递归

46 if (range <= 0) {

47 CreateMaze(maze, dx, dy);

48 }

49 }

50 }

当然这样还不够,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿,我们把最外层全部设为路径。此外还需要设置入口以及寻找出口,如下:

1 int init(int** Maze) {//初始化迷宫

2 //最外围层设为路径的原因,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿

3 for (int i = 0; i < L; i++) {

4 Maze[i][0] = ROUTE;

5 Maze[0][i] = ROUTE;

6 Maze[i][L - 1] = ROUTE;

7 Maze[L - 1][i] = ROUTE;

8 }

9 //创造迷宫,(2,2)为起点

10 CreateMaze(Maze, 2, 2);

11 //画迷宫的入口和出口,给出玩家初始位置

12 Maze[2][1] = PLAYER;

13 //由于算法随机性,出口有一定概率不在(L-3,L-2)处,此时需要寻找出口

14 for (int i = L - 3; i >= 0; i--) {

15 if (Maze[i][L - 3] == ROUTE) {

16 Maze[i][L - 2] = ROUTE;

17 //返回出口所在的纵坐标

18 return i;

19 }

20 }

21 }

至此,我们已经能够生成一幅迷宫地图了,下面用函数把它展示出来:

1 void print(int** Maze) {//画迷宫

2 for (int i = 0; i < L; i++) {

3 for (int j = 0; j < L; j++) {

4 if (Maze[i][j] == ROUTE)

5 printf(" ");//表示道路

6 else if(Maze[i][j] == WALL)

7 printf("回");//表示墙体

8 else

9 printf("十");//表示玩家

10 }

11 printf("\n");

12 }

13 }

实际绘制效果如下:

至此我们已经完成80%的工作了,如何互动起来就看我们的输入了。我的想法是利用w,s,a,d四个键作为控制键控制角色 “十” 上下左右移动,当移动到出口处游戏结束。把这个想法转换为代码如下:

1 void start() { //开始一局游戏

2 char t;

3 //y,x表示角色横纵坐标, out表示出口的纵坐标

4 int x = 2, y = 1, out = 0;

5 //随机数发生器初始化函数

6 srand((unsigned)time(NULL));

7 //申请数组空间

8 int **Maze = (int**)malloc(L * sizeof(int *));

9 for (int i = 0; i < L; i++) {

10 Maze[i] = (int*)calloc(L, sizeof(int));

11 }

12 //得到出口纵坐标

13 out = init(Maze);

14 //游戏开始

15 system("cls");

16 print(Maze);

17 while(t = getch()) {

18 if(t == 27) //如果输入为ESC键,结束游戏回到主菜单

19 break;

20 system("cls");//清屏

21 move(Maze, t, x, y);//根据输入t进行移动

22 print(Maze);//重新绘制迷宫

23 if(x == out && y == L-2) {//已经到出口,游戏结束

24 system("cls");

25 printf("=============\n");

26 printf("游 戏 胜 利!\n");

27 printf("=============\n");

28 printf("即将后返回主菜单……");

29 Sleep(1500);//执行挂起一段时间,暂停1.5秒后打印

30 break;

31 }

32 }

33 //一局游戏结束,释放内存

34 for (int i = 0; i < L; i++) free(Maze[i]);

35 free(Maze);

36 }

为了游戏体验我使用了getch()这个库函数代替getchar(),好处就是不回显。为了让这个游戏看起来还比较像样,我就把他做成了下面这个样子:

开始界面:难度调整界面:

说明界面:

编辑工具:Dev-C++(版本:5.11.0.0)

编译器:TDM-GCC4.9.264-bit Release

源码下载链接:等上传完毕后我会第一时间贴出来的。

非常感谢您的观看,如果对你有所帮助的话实在是再好不过了。

标签:direction,int,ROUTE,迷宫,C语言,小游戏,Maze,挖穿

来源: /xiao-qi-w/p/13031637.html

如果觉得《手动搜索迷宫游戏 c语言 C语言实现一个走迷宫小游戏(深度优先算法)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。