用深度优先搜索创建迷宫

时间:2015-08-16 08:59:44

标签: java algorithm graph

我尝试使用深度优先搜索算法创建迷宫,并且我尝试使用堆栈和递归算法,并且我在先前的示例中测试了算法并且它们工作正常但我无法做到让它与迷宫一起工作。我也认为我展示迷宫的方式是错误的。

public void depthFirstSearch(){  
    for(int row = 0; row < dim; row++){
        for(int column = 0; column < dim; column++){

            Node current    =   maze[row][column];
            if(!current.isVisited()){
                search(current);
            }
        }
    }
}

    public void search(Node node){

        node.visit();
        Random rand  =   new Random();
        int direction   =   rand.nextInt(4);

//west wall
        if(direction == 0 && left(node) != null && !left(node).isVisited()){
            node.breakLeft();
            left(node).breakRight();
            search(left(node));
        }

//east wall
        if(direction == RIGHT_DIRECTION && right(node) != null && !right(node).isVisited()){
            node.breakRight();
            right(node).breakLeft();
            search(right(node));
        }

//south wall
        if(direction == BOTTOM_DIRECTION && down(node) != null && !down(node).isVisited())
        {
            node.breakDown();
            down(node).breakUp();
            search(down(node));
        }

//north wall
        if(direction == TOP_DIRECTION && up(node) != null && !up(node).isVisited()){
            node.breakUp();
            up(node).breakDown();
            search(up(node));
        }
    }

public char[][] fillMaze(){
    depthFirstSearch();
    char[][] filledMaze  =   new char[dim][dim];

    for(int row = 0; row < dim; row++)
        for(int column = 0; column < dim; column++){
             //Fill left wall
            if(inRange(row, column - 1) && maze[row][column].left && filledMaze[row][column - 1] != '#')
                filledMaze[row][column - 1] = '#';

            //Fill top wall
            if(inRange(row - 1, column) && maze[row][column].up && filledMaze[row - 1][column] != '#')
                filledMaze[row - 1][column] = '#';

            //Fill right wall
            if(inRange(row, column + 1) && maze[row][column].right && filledMaze[row][column + 1] != '#')
                filledMaze[row][column + 1] = '#';

            //Fill bottom wall
            if(inRange(row + 1, column) && maze[row][column].down && filledMaze[row + 1][column] != '#')
                filledMaze[row + 1][column] = '#';    
        }

    return filledMaze;
}

    public void drawMaze(char[][] filledMaze){
    for(int row = 0; row < dim; row++){
        for(int column = 0; column < dim; column++){
            if(filledMaze[row][column] != '#') {
                System.out.print(" ");
            }
            else {
               System.out.print("#"); 
            }
        }
        System.out.println();
    }
}

输出10x10迷宫,其中|代表一堵墙,这里迷宫基本上都是墙壁:

||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||

所以迷宫非常密集,如果我切换到dfs的堆叠算法,它会好一点,但我觉得无论是我绘制迷宫的方式还是我的方式都有一些非常错误实现了dfs来创建迷宫..

1 个答案:

答案 0 :(得分:1)

问题在于印刷。我尝试了你的DFS实现,它的工作原理,因为我不了解打印的实现,我创建了自己的。

打印的想法是每个Node都有自己的nodeMat[3][3],它将填充#,即:

###
#
#

之后只需打印整个迷宫:

for (int row = 0; row < matrix.length; row++) {
    for (int nodeRow = 0; nodeRow < 3; nodeRow++) {
        for (int col = 0; col < matrix.length; col++) {
            Node cur = matrix[row][col];
            cur.printRow(nodeRow);
            if (col == matrix.length - 1)
                System.out.println();
       }
    }
}

迷宫看起来像:

##############################
# ## ## ##    ##    ## ## ## #
# ##########  ####  ##########
# ########### #####  #########
# ## ## ## ## ## ##       ## #
#### ## ################  ####
###  ## #################  ###
#    ## ## ## ##       ##    #
########## #####  ###  #######
#########  ####  #####  ######
# ## ##    ##    ## ##    ## #
#######  ####  #### ##########
#######  ###  ####  ##########
#    ##       ##    ## ## ## #
###################### ## ####
###################### ##  ###
# ## ## ## ##       ## ##    #
# ##### ## ########### ####  #
# ##### ##  ########## ##### #
# ## ## ##    ## ## ## ## ## #
######################### ## #
######################### ## #
#       ##    ## ## ## ## ## #
######  ####  ########### ####
####### #####  ########## ####
# ## ## ## ##    ## ## ## ## #
##############################
##############################
# ## ## ##       ##    ## ## #
##############################

您看到从一个角落到另一个角落没有单一路径。这是因为当您致电search(node)时,您只有一次机会找到未访问过的Node

我添加了一个list个数字0,1,2,3。每个数字是位置LEFT,RIGHT,UP,DOWN。并在课程Node

中添加了两种方法
public boolean randomExist() {
    return list.size()>0;
}

public int getRandom() {
    int randomNumber = random.nextInt(list.size());
    return list.remove(randomNumber);
}

search(node)方法更改为:

public void search(Node node) {
node.visit();

while (node.randomExist()) {
    int direction = node.getRandom();
    if (direction == LEFT && leftOK(node) && !left(node).isVisited()) {
        node.breakLeft();
        left(node).breakRight();
        search(left(node));
        return;
    }

    if (direction == RIGHT && rightOK(node) && !right(node).isVisited()){
        node.breakRight();
...

重要的部分是return声明中的if声明。

现在迷宫看起来好多了:

##############################
#       ##       ##    ##    #
######  ##  ###  ##    #######
#######    #####    ##  ######
#    ##    ## ##    ##       #
#    ######## #############  #
# ## #######  #############  #
# ## ##       ## ## ##       #
# ## ##  ####### ## ##  ######
# ##    #######  ## ## #######
# ##    ## ##    ## ## ##    #
# ######## ##  #### ## ####  #
# ######## ##  ###  ##  #### #
# ##    ## ##       ##    ## #
# ######## #############  ## #
#  ####### ############## ## #
#       ## ##          ## ## #
######  #####  ######  ## ## #
#######  #### ########    ## #
#    ##    ## ##    ##    ## #
###  ####  ## ##    ######## #
#### #####    ## ##  ####### #
# ## ## ##    ## ##       ## #
#### ## ######## ########### #
###  ## #######  ##########  #
#    ## ##       ## ##       #
#  #######  ####### ##  ######
#  ######  #######  ##  ######
#          ##       ##       #
##############################
相关问题