前言

以前写过一篇博客,用栈走迷宫,然后就想着自己生成迷宫,自己走,就上网查了查自动生成迷宫的算法,也是研究了好一会,才用代码实现了这个算法,采用的就是常见的随机Prim算法。

原理

参考博客:https://blog.csdn.net/juzihongle1/article/details/73135920/
这篇博客讲的原理就很清楚,我就是按照这个思路写出来的,不过这篇博客用的是Python实现的,我用纯C语言实现了一下。
引用博客里的原理:

1.让迷宫全是墙.
2.选一个单元格作为迷宫的通路,然后把它的邻墙放入列表
3.当列表里还有墙时1.从列表里随机选一个墙,如果这面墙分隔的两个单元格只有一个单元格被访问过1.那就从列表里移除这面墙,即把墙打通,让未访问的单元格成为迷宫的通路2.把这个格子的墙加入列表2.如果墙两面的单元格都已经被访问过,那就从列表里移除这面墙

程序中用到了链表,因为要动态分配内存,实现动态数组。

程序

运行截图:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <windows.h>#define MAX_NUM 9/******************************link**********************************/typedef struct node
{int x;int y;struct node *next;
}node;node sentinel = {0, 0, 0, NULL};
node *head = &sentinel;
int sum = 0;//创建节点
node *mk_node(int x, int y)
{node *p = (node *)malloc(sizeof(node));if (p == NULL){printf("malloc failed!\n");exit(1);}p->x = x;p->y = y;p->next = NULL;return p;
}//释放节点
void free_node(node *p)
{free(p);
}//插入节点
void insert_node(node *p)
{sum++;p->next = head->next;head->next = p;
}//遍历节点
void traverse()
{node *p = head->next;while (p != NULL){printf("[%d, %d] ", p->x, p->y);p = p->next;}printf("\n");
}//销毁链表
void destroy_link()
{node *p = head->next;while (head->next != NULL){sum--;p = head->next;head->next = p->next;free_node(p);}
}//查找节点
node *search_node(int x, int y)
{node *p = head->next;while (p != NULL){if (p->x == x && p->y == y){return p;}p = p->next;}return NULL;
}//查找节点
node *search_index(int index)
{int i = 0;node *p = head->next;while (p != NULL){if (i == index){return p;}else{i++;p = p->next;}}return NULL;
}void rm_node(node *p)
{node *pre = head;while (pre->next != NULL){if (pre->next == p){sum--;pre->next = p->next;p->next = NULL;//free_node(p);return;}pre = pre->next;}
}/******************************link**********************************/int map[MAX_NUM][MAX_NUM] = {0};int count_map()
{int i = 0;int j = 0;int count = 0;for (i = 0; i < MAX_NUM; i++){for (j = 0; j < MAX_NUM; j++){if (map[j][i] == 7)count++;}}return count;
}//将邻墙放入链表
void insert_around(node *p)
{node *p_t;if (search_node((p->x) - 1, p->y) == NULL &&(p->x)-1 > -1 && map[(p->x)-1][p->y] == 7) //左边没越界且为墙{p_t = mk_node((p->x) - 1, p->y);insert_node(p_t);}if (search_node((p->x) + 1, p->y) == NULL &&(p->x)+1 < MAX_NUM && map[(p->x)+1][p->y] == 7) //右边没越界且为墙{p_t = mk_node((p->x)+1, p->y);insert_node(p_t);}if (search_node((p->x), (p->y) - 1) == NULL &&(p->y)-1 > -1 && map[p->x][(p->y)-1] == 7) //上边没越界且为墙{p_t = mk_node(p->x, (p->y)-1);insert_node(p_t);}if (search_node((p->x),(p->y) + 1) == NULL &&(p->y)+1 < MAX_NUM && map[p->x][(p->y)+1] == 7) //下边没越界且为墙{p_t = mk_node(p->x, (p->y)+1);insert_node(p_t);}
}void show_map()
{int i = 0;int j = 0;for (i = 0; i < MAX_NUM; i++){for (j = 0; j < MAX_NUM; j++){printf("%d ", map[j][i]);}printf("\n");}
}void print_map()
{int i = 0;int j = 0;for (i = 0; i < MAX_NUM; i++){for (j = 0; j < MAX_NUM; j++){if (map[j][i] == 7)printf("* ");elseprintf("1 ");}printf("\n");}
}//7 墙
int main()
{int i = 0;int j = 0;srand((int)time(0));//全部为墙for (i = 0; i < MAX_NUM; i++){for (j = 0; j < MAX_NUM; j++){map[i][j] = 7;}}show_map();map[0][0] = 1; //00被访问node *p;p = mk_node(0, 0);//insert_around(p);   //放入邻墙p = mk_node(1, 0);insert_node(p);p = mk_node(0, 1);insert_node(p);//traverse();while (sum != 0){node *p_t;int index = rand() % sum;//printf("index = %d\n", index);p = search_index(index);//printf("p = [%d, %d]\n", p->x, p->y);if ( (p->x)-1 > -1 && (p->x)+1 < MAX_NUM&& map[(p->x)-1][(p->y)] == 1 && map[(p->x)+1][(p->y)] == 7)//左被访问右未被访问{map[(p->x)][(p->y)] = 1;map[(p->x)+1][(p->y)] = 1;p_t = mk_node((p->x)+1, (p->y));insert_around(p_t);rm_node(p);free_node(p);//printf("LR1\n");}else if ( (p->x)-1 > -1 && (p->x)+1 < MAX_NUM&& map[(p->x)-1][(p->y)] == 7 && map[(p->x)+1][(p->y)] == 1)//右被访问左未被访问{map[(p->x)][(p->y)] = 1;map[(p->x)-1][(p->y)] = 1;p_t = mk_node((p->x)-1, (p->y));insert_around(p_t);rm_node(p);//printf("LR2\n");}else if ( (p->y)-1 > -1 && (p->y)+1 < MAX_NUM&& map[(p->x)][(p->y)-1] == 1 && map[(p->x)][(p->y)+1] == 7)//上被访问下未被访问{map[(p->x)][(p->y)] = 1;map[(p->x)][(p->y)+1] = 1;p_t = mk_node((p->x), (p->y)+1);insert_around(p_t);rm_node(p);//printf("UD1\n");}else if ( (p->y)-1 > -1 && (p->y)+1 < MAX_NUM&& map[(p->x)][(p->y)-1] == 7 && map[(p->x)][(p->y)+1] == 1)//下被访问上未被访问{map[(p->x)][(p->y)] = 1;map[(p->x)][(p->y)-1] = 1;p_t = mk_node((p->x), (p->y)-1);insert_around(p_t);rm_node(p);//printf("UD2\n");}else{//map[(p->x)][(p->y)] = 1;rm_node(p);//printf("全部被访问\n");}//traverse();//show_map();//Sleep(100);}printf("wall is %d\n", count_map());//show_map();print_map();traverse();destroy_link();return 0;
}

总结

与我联系

QQ:1570553025
github:https://github.com/myzcl
微信公众号,扫二维码即可关注:

随机Prim算法生成迷宫相关推荐

  1. C 语言 随机prim算法 生成迷宫

    使用 随机prim算法生成迷宫,效果如下: 随机prim迷宫生成算法思想: 1.普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不 ...

  2. c语言随机prim算法的迷宫生成,Prim算法生成迷宫

    初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...

  3. Prim算法生成迷宫

    初始化地图 function initMaze(r,c){let row = new Array(2 * r + 1)for(let i = 0; i < row.length; i++){le ...

  4. Python Prim 算法 生成迷宫

    之前,我们在另外一篇文章中使用Prim算法生成了一个完美迷宫,利用的是遍历网格的方法,这一次,我们要教教大家用遍历墙的方法生成,上一篇文章链接:Python Prim 算法 生成迷宫_Leleprog ...

  5. 实验三、prim算法生成迷宫,A*算法解迷宫(实验准备)

    目录 实验要求: 算法简介: prim算法: A*算法: 实验要求: 该项目的主要要求是:首先生成一个迷宫,要求随机生成.而生成迷宫有深度优先算法.prim算法.递归分割算法等.老师说建议使用prim ...

  6. Kruskal与Prim算法生成最小树

    Kruskal算法适用于边稀疏的情形 Prim算法适用于边稠密的情形 点击:Kruskal算法的理解 书上的代码: n:图G上的顶点 e:G上的边数 vest:看是否属于同一连通分量的数组,数值相等则 ...

  7. Prime算法生成迷宫

    prime迷宫生成 结果展示 算法解析 实现代码 结果展示 算法解析 参考链接 Prime迷宫生成算法的原理: (1)初始地图所有位置均设为墙 (2)任意插入一个墙体进墙队列 (3)判断此时墙体是否可 ...

  8. 实验三:基于A*算法的迷宫

    实验要求: 1.迷宫随机生成 2.玩家走迷宫,留下足迹: 3.系统用A*算法寻路,输出路径 解决问题: 1.如何显示迷宫的图形界面: 2.如何生成随机的迷宫: 3.怎样移动游戏中走迷宫的"玩 ...

  9. prim算法_自动生成随机迷宫(1)prim算法

          "程序 = 数据  + 算法",一款好的作品不单单是代码的堆砌,还有其灵魂的部分,那就是算法:算法是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机 ...

最新文章

  1. 使用antd报less的错误
  2. C++与C#混合编程
  3. 6 键盘高级操作技巧
  4. cat >> ipconf << EOF > EOF是什么意思
  5. 数据结构/排序/选择排序/简单选择排序
  6. xml和html的区别和联系
  7. 国信长天蓝桥杯嵌入式类——stm32——使用keil4建立工程文件过程
  8. for循环和for in循环
  9. 4.花瓣特效----js+旋转+位移+随机颜色+随机位置
  10. 中国机器人最新统计数据发布及分析(附图)
  11. 《程序员》专访:对话张宏江
  12. SQL SERVER 数据库delete 未加where 条件数据误删恢复办法
  13. 指令集创始人潘爱民受邀出席CCF系统软件技术论坛,探讨泛在操作系统技术发展...
  14. Ubuntu18.04安装ROS(melodic)
  15. NAO V6 开发环境的配置(附所有文件)
  16. 有没有老照片修复软件可以高清修复照片?
  17. 踩过springcloud的坑
  18. Java——list的四种遍历
  19. 小朱的Java学习之旅--出发
  20. GPU服务器:全球市值最大的半导体公司

热门文章

  1. python图片识别
  2. Qt加载MySql5.6驱动问题
  3. C51——oled显示图片(128x64,图片可自己创建)
  4. (九)python网络爬虫(理论+实战)——爬虫实战:指定关键词的百度新闻爬取
  5. 八个前端开发必备的面试刷题网站
  6. Linux之Ubuntu命令行常见命令
  7. 关于gzip zgrep zcat 的使用
  8. 天马资产 | 金融数据分析师招聘(社招+实习)
  9. HRNet、HRNet V2网络结构解读
  10. 实验5、白盒测试:覆盖测试及测试用例设计