zoukankan      html  css  js  c++  java
  • [转载]规则满迷宫地图生成算法2

    现在介绍第二种算法,使用并查集 合并生成。

    简单介绍一下算法思想:首先把地图关键点的连结(墙),编号1-x*y*2,然后random shuffle

    然后按照打乱后的次序,打通一些墙,用并查集检查是否要打通的两边是已经连通的就行了,

    生成的例子如下:

    █████████████████████
              █   █     █
    █████████ █ █ █ █████
    █   █     █ █   █ █ █
    █ █ █ ███ █████ █ █ █
    █ █ █ █   █ █   █   █
    █ █ ███ ███ ███ ███ █
    █ █   █             █
    █████ ███ █ █ ███ ███
    █         █ █   █ █ █
    █████ ███ ███████ █ █
    █       █   █       █
    █ ███ █ ███ █ █ █████
    █   █ █ █   █ █     █
    ███ ███████ █ █ ███ █
    █   █       █ █   █  
    █████████████████████

    这种算法生成的特点是,分支数非常的多,较多短小分支,难度往往较DFS生成的简单

    但效率非常高,生成1000*1000的迷宫,只要1秒(DFS生成的常数上要大一些)

    但需要一个辅助的并查集数据结构,空间消耗大。

    代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define SWAP(a,b,c) {c t=a;a=b;b=t;}
    int uf[9000000], Map[3000][3000]; //并查集表,迷宫地图
    struct PT{int x; int y;}que[5000000]; //生成序列
    int x=10,y=8,xy=0; //x,y指定要生成的大小
    int findP(int& n)
    {
        int a=++n;
        while (uf[a]) a=uf[a];
        if (a!=n) uf[n] = a;
        return n=a;
    }
    int Ins(PT xy)
    {
        int a=(xy.y-1)/2*x+(xy.x-1)/2, b=(xy.y&1)?a+1:a+x;
        if (findP(a)!=findP(b)) {uf[b] = a; return 1;}
        return 0;
    }
    int main()
    {
        int n=0,_y,_x,o;
        srand(time(NULL)); Map[1][0]=Map[y*2-1][x*2]=1;
        for (_y=1; o=_y!=y,_y<=y; ++_y)
            for (_x=1; _x<=x; ++_x)
            {
                if (_x<x)que[n].y = _y*2-1, que[n].x = _x*2,++n;
                 if (o)que[n].y = _y*2, que[n].x = _x*2-1,++n;
            }
        for (xy=n,n=0; n<xy; ++n) {int z=rand()%xy; SWAP(que[n],que[z],PT);}
        for (n=0; n<xy; ++n)
        {
            if (!Ins(que[n])) continue;
            Map[que[n].y][que[n].x] = 1;
            if (que[n].y&1) Map[que[n].y][que[n].x-1] = Map[que[n].y][que[n].x+1] = 1;
            else Map[que[n].y-1][que[n].x] = Map[que[n].y+1][que[n].x] = 1;
         }
        for (_y=0; _y<=y*2; ++_y)
        {
            for (_x=0; _x<=x*2; ++_x)
                if (Map[_y][_x]) fputs(" ", stdout); else fputs("█", stdout);
            putchar(10);
        }
        return 0;
    }

    作者:BuildNewApp
    出处:http://syxchina.cnblogs.comBuildNewApp.com
    本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
    如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。
  • 相关阅读:
    如何修改运行中的docker容器的端口映射和挂载目录
    kubernetes集群应用部署实例
    linux centos7磁盘格式化挂载之parted
    mysql授权用户,撤销用户,撤销权限基本操作
    MySQL数据库基础备份
    实现Kubernetes跨集群服务应用的高可用
    使用Harbor配置Kubernetes私有镜像仓库
    kubernetes1.5新特性(二):支持Photon卷插件
    kubernetes1.4新特性(一):支持sysctl命令
    说说我心中的Linux系统
  • 原文地址:https://www.cnblogs.com/syxchina/p/2197323.html
Copyright © 2011-2022 走看看