DFS的C语言迷宫生成算法

时间:2018-12-30 18:59:39

标签: c maze dfs

最近,我阅读了有关在c中生成迷宫的主题。见这里https://www.algosome.com/articles/maze-generation-depth-first.html 我想用c编写它。这是我的代码,它不能正常工作。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int check[5][5];
int v[5][5];
int border(int x , int y ){
    if(x> -1 && x< 6 && y > -1 && y<6)
        return 1;
    else
        return 0 ;
}
int wall[6][6][6][6];
void dfs ( int x , int y){
    srand(time(NULL));
    int s = 1/*rand() % 4 ;*/ ;
    if(s=1 ){
        if(border(x ,y-1)&& check[x][y-1]==0){
            check[x][y]=1;
            wall[x][y][x+1][y]=1;
            dfs(x , y-1);
        }
        else
            return ;
    }
    else if(s=2){
        if(border(x+1 ,y)&&check[x+1][y]==0){
            check[x][y]=1;
            wall[x+1][y][x+1][y+1]=1;
            dfs(x+1 , y);
        }
        else return ;
    }
    else if(s=3){
        if(border(x ,y+1)&&check[x][y+1]==0){
            check[x][y]=1;
            wall[x][y+1][x+1][y+1]=1;
            dfs(x , y+1);
        }
        else return ;
    }
    else if(s=0){
        if(border(x-1 ,y)&&check[x-1][y]==0){
            check[x][y]=1;
            wall[x][y][x][y+1]=1;
            dfs(x-1 , y);
        }
        else return ;
    }
return ;
}

int main(){
dfs( 4, 4);
for(int i =0 ; i < 6 ; i++)
    for (int j =0 ; j < 6 ; j++)
        for ( int h =0 ; h <6 ; h++)
            for (int k =0 ; k < 6 ; k ++)
                printf("%d \n" , wall[i][j][h][k]);

return 0 ;
}
我把桌子翻转成图表,我想给我看墙壁的坐标。 有什么问题吗?

1 个答案:

答案 0 :(得分:0)

您的代码中有几个错误-编程错误和逻辑错误:

  • 当您对两个方向进行区分时,s=1等应为s == 1。您需要比较而不是分配。 (您的代码是合法的C,因此没有错误。)
  • 您可以在srand的开头调用dfs,然后递归调用。这将使您的单个(注释)rand调用始终创建相同的随机数。您应该只在main的开头为伪随机数生成器提供一次种子。
  • 您可以按照自己的方式存储路径,但这很浪费。每个单元格只有四个可能的路径,因此,您不需要一个允许在(0,0)和(3,4)之间创建路径的数组。
  • 您的代码将受益于使用常量或枚举值,而不是硬编码的5和6。这样一来,您以后就可以轻松更改尺寸。

但是您的主要错误在于如何实现算法。您随机选择一个for方向,然后测试该方向是否导致有效的未访问单元格。如果是这样,则递归。如果没有,则停止。这将在单元格中创建一条独立的路径。请注意,如果您从角落单元格开始,则已经有50%的机会停止递归短暂操作。

但是您还需要其他东西:您想要一个迷宫,它有许多分支,通向迷宫中的每个单元。因此,当第一个递归返回时,您必须尝试分支到其他单元格。算法如下:

  • 列出所有可能的出口。
  • 如果有可能的出口:
    • 选择一个出口,为该出口创建路径并递归。
    • 更新可能出口的列表。

请注意,您不能重用旧的退出列表,因为递归可能通过访问目标单元格使某些可能的退出无效。

下面是使用描述的算法创建迷宫的代码。我使用了两个不同的数组来描述水平和垂直路径:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

enum {
    W = 36,         // width of maze
    H = 25          // height of maze
};

enum {
    North,
    East,
    South,
    West,
    NDir
};

char visited[H][W];
char horz[H][W - 1];        // horizontal E-W paths in the maze
char vert[H - 1][W];        // veritcal N-S paths in the maze

/*
 *      Fill dir with directions to unvisited cells, return count
 */
int adjacent(int dir[], int x, int y)
{
    int ndir = 0;

    if (y > 0     && visited[y - 1][x] == 0) dir[ndir++] = North;
    if (x < W - 1 && visited[y][x + 1] == 0) dir[ndir++] = East;
    if (y < H - 1 && visited[y + 1][x] == 0) dir[ndir++] = South;
    if (x > 0     && visited[y][x - 1] == 0) dir[ndir++] = West;

    return ndir;
}

/*
 *      Traverse cells depth first and create paths as you go
 */
void dfs(int x, int y)
{
    int dir[NDir];
    int ndir;

    visited[y][x] = 1;

    ndir = adjacent(dir, x, y);

    while (ndir) {
        int pick = rand() % ndir;

        switch (dir[pick]) {
        case North: vert[y - 1][x] = 1; dfs(x, y - 1); break;
        case East:  horz[y][x] = 1;     dfs(x + 1, y); break;
        case South: vert[y][x] = 1;     dfs(x, y + 1); break;
        case West:  horz[y][x - 1] = 1; dfs(x - 1, y); break;
        }

        ndir = adjacent(dir, x, y);
    }
}

/*
 *      Print a map of the maze
 */
void map(void)
{
    int i, j;

    for (i = 0; i < W; i++) {
        putchar('_');
        putchar('_');
    }

    putchar('\n');

    for (j = 0; j < H; j++) {
        putchar('|');

        for (i = 0; i < W; i++) {
            putchar(j < H - 1 && vert[j][i] ? ' ' : '_');
            putchar(i < W - 1 && horz[j][i] ? '_' : '|');
        }

        putchar('\n');
    }
}

int main()
{
    srand(time(NULL));

    dfs(0, 0);
    map();

    return 0;
}

您可以here对其进行测试。如果将while中的dsf替换为简单的if,您将获得或多或少的实现。请注意,这只会创建一条通常较短的路径。