飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 5232|回复: 3

[C++] 实现迷宫生成算法 采用了并查集数据结构

[复制链接]

该用户从未签到

发表于 2011-2-12 21:37:04 | 显示全部楼层 |阅读模式
随机生成一个迷宫,一般这种问题要用并查集的,但是具体算法我没有上网查找过,所以自己想了一个,但是我的想法还不成熟,存在很多缺陷,望大牛们指正。
算法的思想是:
while( 入口和出口 不通)
{
....随机找个点 -> (x,y)
....随机找个方向->上/下/左/右 -> dx,dy = {0,1,-1}
....如果(x,y)和( x + dx , y + dy)有一个是墙
.........把墙去掉
.........联通(x,y) 和 (x+dx,y+dy)
}

如果 RP是负无穷的话,可能要搜很长时间。。。。

  1. /*
  2. *   Auther:Knuth学徒
  3. *   Lang:C++
  4. *   Date:2011-2-12
  5. */

  6. #include<cstdio>
  7. #include<cstring>
  8. #include<cstdlib>
  9. #include<ctime>
  10. #include<iOStream>
  11. using namespace std;

  12. const int M = 5;
  13. const int N = 5;
  14. const int direction[4][2] = {(0,-1),(0,1),(-1,0),(1,0)};

  15. int father[M*N + 1];   //并查集的父节点记录数组
  16. int map[N][M];         //地图数组

  17. /////////////////////////////////////////////////
  18. //     函数名:hash
  19. //     参数:横坐标和纵坐标以及棋盘的列大小
  20. //     前提:None
  21. //     返回:坐标的散列值
  22. /////////////////////////////////////////////////
  23. int hash(int x,int y, int col)
  24. {
  25.         return ( x * col + y );
  26. }

  27. /////////////////////////////////////////////////
  28. //     函数名:id
  29. //     参数:点的散列值,存在a和b中
  30. //     前提:None
  31. //     返回:引用传值回去
  32. /////////////////////////////////////////////////
  33. void id(int val, int &a,int &b)
  34. {
  35.         a = val/M;
  36.         b = val%M;
  37. }

  38. /////////////////////////////////////////////////
  39. //     函数名:Make
  40. //     参数:None
  41. //     前提:None
  42. //     返回:None
  43. //     描述:并查集的初始化过程
  44. /////////////////////////////////////////////////
  45. void Make()
  46. {
  47.         for(int i=0;i<N;++i)
  48.                 for(int j = 0;j<M;++j)
  49.                 {
  50.                         father[hash(i,j,M)] = hash(i,j,M);
  51.                 //        printf("f[%d] = %d ",hash(i,j,M),father[hash(i,j,M)]);
  52.                 }
  53. }

  54. /////////////////////////////////////////////////
  55. //     函数名:FindSet
  56. //     参数:节点X表示某个点的散列值
  57. //     前提:None
  58. //     返回:节点x的祖先
  59. //     描述:递归时采用了路径压缩
  60. /////////////////////////////////////////////////
  61. int FindSet(int x)
  62. {
  63.         if( x != father[x])
  64.         {
  65.                 father[x] = FindSet(x);
  66.         }
  67.         return father[x];
  68. }

  69. /////////////////////////////////////////////////
  70. //     函数名:Union
  71. //     参数:两个散列值
  72. //     前提:None
  73. //     返回:None
  74. //     描述:合并两个集合
  75. /////////////////////////////////////////////////
  76. void Union(int a,int b)
  77. {
  78.         father[a] = b;
  79. }

  80. int main()
  81. {
  82.         Make();
  83.         int sx,sy,ex,ey;
  84.         srand((unsigned)time(0));
  85.         int a = rand() % M*N; //入口
  86.         int b = rand() % M*N;  //出口
  87.         id(a,sx,sy);
  88.         id(b,ex,ey);
  89.         map[sx][sy] = map[ex][ey] = 0;
  90. //        cout<<"a = "<<a<<endl;
  91. //        cout<<"b = "<<b<<endl;
  92.   //  cout<<"f[a]="<<father[a]<<endl;
  93.     //cout<<"f  b="<<father[b]<<endl;
  94.         while(FindSet(a) != FindSet(b))
  95.         //如果入口和出口不联通
  96.         {
  97.                 int tmp = rand() % M*N;
  98.                 //随机选一点

  99.                 int dire = rand()%4;
  100.                 int tx,ty,ttx,tty;
  101.                 id(tmp,tx,ty);
  102.         //        printf("%d %d",tx,ty);
  103.                 ttx = tx + direction[dire][0];
  104.                 tty = ty + direction[dire][1];

  105.                 if(map[tx][ty] || map[ttx][tty])
  106.                 {
  107.                         map[tx][ty] = (map[tx][ty] == 1 ? 0:0);
  108.                         map[ttx][tty] = (map[ttx][tty] == 1 ? 0:0);
  109.                         Union(hash(tx,ty,M),hash(ttx,tty,M));
  110.                 }
  111.         }
  112.    // cout<<"OK2"<<endl;
  113.         for(int m = 0;m<N;++m)
  114.         {
  115.                 for(int n =0;n<M;++n)
  116.                 {
  117.                         printf("%d",map[m][n]);
  118.                 }
  119.                 printf("\n");
  120.         }
  121.         return 0;
  122. }
复制代码
PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-9-18 09:23
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2015-1-26 16:55:42 | 显示全部楼层
    好东西,收藏了
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-1-30 21:16:21 | 显示全部楼层
    看着 好复杂呀
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2015-7-20 09:42
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2015-2-2 19:23:11 来自手机 | 显示全部楼层
    学习下!!!不错!
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表