读书人

一段迷宫生成算法有一处不理解求讲

发布时间: 2012-08-02 11:35:25 作者: rapoo

一段迷宫生成算法,有一处不理解,求讲解

C/C++ code
#include <stdio.h>#include <stdlib.h>#include <time.h>#define MAZE_MAX    50char map[MAZE_MAX+2][MAZE_MAX+2];int search(int x,int y){    static int d[4][2]={0,1,1,0,0,-1,-1,0};    int zx=x*2,zy=y*2,next,turn,i;    map[zx][zy]=0; turn=rand()%2? 1:3;    for(i=0,next=rand()%4;i<4;i++,next=(next+turn)%4)        if(map[zx+2*d[next][0]][zy+2*d[next][1]]==1)   //这里是zx + 2*d[next][0]...            map[zx+d[next][0]][zy+d[next][1]]=0,       // 这里是zx + d[next][0]...            search(x+d[next][0],y+d[next][1]);         // 这里是x + d[next][0]                                                       // 以上不太明白,那个乘以2,不乘以2,都是干嘛的?    return 0;}void Make_Maze(int x,int y){    int z1,z2;    for(z1=0,z2=2*y+2;z1<=2*x+2;z1++)  // 数组最外围置0,表示无墙        map[z1][0]=0,map[z1][z2]=0;        for(z1=0,z2=2*x+2;z1<=2*y+2;z1++)        map[0][z1]=0,map[z2][z1]=0;            map[1][2]=0;map[2*x+1][2*y]=0;      //入口和出口    srand((unsigned)time(NULL));    search(rand()%x+1,rand()%y+1);}int main(void{    int x=2,y=2,z1,z2; //x和y的值指定了这个要生成的迷宫的大小    for(int i=0; i<=x*2+2; ++i)        for(int j=0; j<=y*2+2; ++j)            map[i][j] = 1;    Make_Maze(x, y);    for(z2=1; z2<=y*2+1; z2++)    {        for(z1=1;z1<=x*2+1;z1++)             fputs(map[z2][z1]==0?" ":"",stdout);        putchar(10);    }    return 0;}


在search函数中有这么一段代码

for(i=0,next=rand()%4;i<4;i++,next=(next+turn)%4)
if(map[zx+2*d[next][0]][zy+2*d[next][1]]==1) //这里是zx + 2*d[next][0]...
map[zx+d[next][0]][zy+d[next][1]]=0, // 这里是zx + d[next][0]...
search(x+d[next][0],y+d[next][1]); // 这里是x + d[next][0]
// 以上不太明白,那个乘以2,不乘以2,都是干嘛的?

[解决办法]
额,我问了一下,种子函数放在主函数里,别放在递归调用里,这样就完美了.
C/C++ code
#include <cstdio>#include <cstdlib>#include <ctime>static int direct[4][2]={    {0,1},{1,0},{0,-1},{-1,0}};const int SIZE = 100;bool maze[SIZE][SIZE];int h,w,sx,sy,ex,ey;bool checkAround(int fX,int fY,int toX,int toY){    for(int i=0;i<4;++i)    {        int x=toX+direct[i][0];        int y=toY+direct[i][1];        if(maze[x][y]==false && x!=fX && y!=fY)        {            return false;        }    }    return true;}bool dfs(int x,int y){    maze[x][y]=false;    if(x==ex && y==ey)    {        return true;    }    bool flag[4]={0,0,0,0};    for(int i=rand()%4,cnt=0;cnt<4;i=rand()%4)    {        if(!flag[i])        {            flag[i]=true;            ++cnt;            int toX=x+direct[i][0];            int toY=y+direct[i][1];            if(0<toX && toX<h+1 && 0<toY && toY<w+1 && maze[toX][toY]==true && checkAround(x,y,toX,toY)==true)            {                if(dfs(toX,toY))                {                    return true;                }            }        }    }    maze[x][y]=true;    return false;}int main(){    scanf("%d%d%d%d%d%d",&h,&w,&sx,&sy,&ex,&ey); //输入高,宽        /*        深搜起点到终点    */    while(getchar())    {        srand( (unsigned int ) time(0) );        for(int i=0;i<=h+1;++i)        {            for(int j=0;j<=w+1;++j)            {                maze[i][j]=true;            }        }        dfs(sx,sy);        printf("\n");        for(int i=0;i<=h+1;++i)        {            for(int j=0;j<=w+1;++j)            {                printf("%c",maze[i][j]==true ? '#':' ');            }            printf("\n");        }    }    return 0;}
------解决方案--------------------


你这个程序我运行了下,随机性不错,生成的迷宫也挺好看。
这个迷宫可以看成是路和墙都占一个格子,然后行数和列数均为偶数的视为路,其余格子视为墙。
调试了几步,我感觉这几个乘2应该是如下含义:

C/C++ code
int search(int x,int y){    static int d[4][2]={0,1,1,0,0,-1,-1,0};            //这个不用说了吧,四个方向    int zx=x*2,zy=y*2,next,turn,i;    map[zx][zy]=0;                                     //这一步是在打通当前格子,默认该格子为路,因为该格子的行数和列数均为偶数。    turn=rand()%2? 1:3;    for(i=0,next=rand()%4;i<4;i++,next=(next+turn)%4)  //不得不说这个turn和next的随机很好,turn表示可以顺时针递归,也可以逆时针递归,而next则正好是随机了转圈的起点        if(map[zx+2*d[next][0]][zy+2*d[next][1]]==1)   //判断下一个应该为路的格子是否还是1,如果是1的话应该打通才对            map[zx+d[next][0]][zy+d[next][1]]=0,       //所以此时这句话的作用相当于打掉墙,打掉的是(zx,zy)和(zx+2*d[next][0],zy+2*d[next][1])之间的墙,为下一步打通路做准备。            search(x+d[next][0],y+d[next][1]);         //然后,进入递归,即进入下一个路径    return 0;} 

读书人网 >C++

热点推荐