随机Prim算法生成迷宫
前言
以前写过一篇博客,用栈走迷宫,然后就想着自己生成迷宫,自己走,就上网查了查自动生成迷宫的算法,也是研究了好一会,才用代码实现了这个算法,采用的就是常见的随机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算法生成迷宫相关推荐
- C 语言 随机prim算法 生成迷宫
使用 随机prim算法生成迷宫,效果如下: 随机prim迷宫生成算法思想: 1.普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不 ...
- c语言随机prim算法的迷宫生成,Prim算法生成迷宫
初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...
- Prim算法生成迷宫
初始化地图 function initMaze(r,c){let row = new Array(2 * r + 1)for(let i = 0; i < row.length; i++){le ...
- Python Prim 算法 生成迷宫
之前,我们在另外一篇文章中使用Prim算法生成了一个完美迷宫,利用的是遍历网格的方法,这一次,我们要教教大家用遍历墙的方法生成,上一篇文章链接:Python Prim 算法 生成迷宫_Leleprog ...
- 实验三、prim算法生成迷宫,A*算法解迷宫(实验准备)
目录 实验要求: 算法简介: prim算法: A*算法: 实验要求: 该项目的主要要求是:首先生成一个迷宫,要求随机生成.而生成迷宫有深度优先算法.prim算法.递归分割算法等.老师说建议使用prim ...
- Kruskal与Prim算法生成最小树
Kruskal算法适用于边稀疏的情形 Prim算法适用于边稠密的情形 点击:Kruskal算法的理解 书上的代码: n:图G上的顶点 e:G上的边数 vest:看是否属于同一连通分量的数组,数值相等则 ...
- Prime算法生成迷宫
prime迷宫生成 结果展示 算法解析 实现代码 结果展示 算法解析 参考链接 Prime迷宫生成算法的原理: (1)初始地图所有位置均设为墙 (2)任意插入一个墙体进墙队列 (3)判断此时墙体是否可 ...
- 实验三:基于A*算法的迷宫
实验要求: 1.迷宫随机生成 2.玩家走迷宫,留下足迹: 3.系统用A*算法寻路,输出路径 解决问题: 1.如何显示迷宫的图形界面: 2.如何生成随机的迷宫: 3.怎样移动游戏中走迷宫的"玩 ...
- prim算法_自动生成随机迷宫(1)prim算法
"程序 = 数据 + 算法",一款好的作品不单单是代码的堆砌,还有其灵魂的部分,那就是算法:算法是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机 ...
最新文章
- 使用antd报less的错误
- C++与C#混合编程
- 6 键盘高级操作技巧
- cat >> ipconf << EOF > EOF是什么意思
- 数据结构/排序/选择排序/简单选择排序
- xml和html的区别和联系
- 国信长天蓝桥杯嵌入式类——stm32——使用keil4建立工程文件过程
- for循环和for in循环
- 4.花瓣特效----js+旋转+位移+随机颜色+随机位置
- 中国机器人最新统计数据发布及分析(附图)
- 《程序员》专访:对话张宏江
- SQL SERVER 数据库delete 未加where 条件数据误删恢复办法
- 指令集创始人潘爱民受邀出席CCF系统软件技术论坛,探讨泛在操作系统技术发展...
- Ubuntu18.04安装ROS(melodic)
- NAO V6 开发环境的配置(附所有文件)
- 有没有老照片修复软件可以高清修复照片?
- 踩过springcloud的坑
- Java——list的四种遍历
- 小朱的Java学习之旅--出发
- GPU服务器:全球市值最大的半导体公司