Knuth学徒 发表于 2011-2-12 21:37:04

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

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

如果 RP是负无穷的话,可能要搜很长时间。。。。
/*
*   Auther:Knuth学徒
*   Lang:C++
*   Date:2011-2-12
*/

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
using namespace std;

const int M = 5;
const int N = 5;
const int direction = {(0,-1),(0,1),(-1,0),(1,0)};

int father;   //并查集的父节点记录数组
int map;         //地图数组

/////////////////////////////////////////////////
//   函数名:hash
//   参数:横坐标和纵坐标以及棋盘的列大小
//   前提:None
//   返回:坐标的散列值
/////////////////////////////////////////////////
int hash(int x,int y, int col)
{
      return ( x * col + y );
}

/////////////////////////////////////////////////
//   函数名:id
//   参数:点的散列值,存在a和b中
//   前提:None
//   返回:引用传值回去
/////////////////////////////////////////////////
void id(int val, int &a,int &b)
{
      a = val/M;
      b = val%M;
}

/////////////////////////////////////////////////
//   函数名:Make
//   参数:None
//   前提:None
//   返回:None
//   描述:并查集的初始化过程
/////////////////////////////////////////////////
void Make()
{
      for(int i=0;i<N;++i)
                for(int j = 0;j<M;++j)
                {
                        father = hash(i,j,M);
                //      printf("f[%d] = %d ",hash(i,j,M),father);
                }
}

/////////////////////////////////////////////////
//   函数名:FindSet
//   参数:节点X表示某个点的散列值
//   前提:None
//   返回:节点x的祖先
//   描述:递归时采用了路径压缩
/////////////////////////////////////////////////
int FindSet(int x)
{
      if( x != father)
      {
                father = FindSet(x);
      }
      return father;
}

/////////////////////////////////////////////////
//   函数名:Union
//   参数:两个散列值
//   前提:None
//   返回:None
//   描述:合并两个集合
/////////////////////////////////////////////////
void Union(int a,int b)
{
      father = b;
}

int main()
{
      Make();
      int sx,sy,ex,ey;
      srand((unsigned)time(0));
      int a = rand() % M*N; //入口
      int b = rand() % M*N;//出口
      id(a,sx,sy);
      id(b,ex,ey);
      map = map = 0;
//      cout<<"a = "<<a<<endl;
//      cout<<"b = "<<b<<endl;
//cout<<"f="<<father<<endl;
    //cout<<"fb="<<father<<endl;
      while(FindSet(a) != FindSet(b))
      //如果入口和出口不联通
      {
                int tmp = rand() % M*N;
                //随机选一点

                int dire = rand()%4;
                int tx,ty,ttx,tty;
                id(tmp,tx,ty);
      //      printf("%d %d",tx,ty);
                ttx = tx + direction;
                tty = ty + direction;

                if(map || map)
                {
                        map = (map == 1 ? 0:0);
                        map = (map == 1 ? 0:0);
                        Union(hash(tx,ty,M),hash(ttx,tty,M));
                }
      }
   // cout<<"OK2"<<endl;
      for(int m = 0;m<N;++m)
      {
                for(int n =0;n<M;++n)
                {
                        printf("%d",map);
                }
                printf("\n");
      }
      return 0;
}

hu251405204 发表于 2015-1-26 16:55:42

好东西,收藏了

独尚尚 发表于 2015-1-30 21:16:21

看着 好复杂呀

287965881 发表于 2015-2-2 19:23:11

学习下!!!不错!
页: [1]
查看完整版本: [C++] 实现迷宫生成算法 采用了并查集数据结构