当前位置: 首页 > 知识库问答 >
问题:

迷宫(递归除法)算法设计

壤驷康裕
2023-03-14

我目前正在开发一个随机迷宫生成器,它将迷宫存储在一个名为< code>grid的二维数组中。这将随后用于生成一个真实的3D迷宫,用户可以在其中穿行。

在做了一些研究之后,我试图使用递归除法算法创建这个迷宫生成器,但是由于迷宫格式的性质,这对我来说并不是真的有效。

据我所知,递归分裂方法并不将壁视为细胞。

例如,我的网格如下所示:

  a b c d e f g h
1 - - - - - - - -
2 |   |   | |   |
3 |       |     |
4 | -   - |   - |
5 |     |     | |
6 |   - |   -   |
7 x             |
8 - - - - - - - -

我想在这里说的是,我试图创建的网格将像这样表示:

w w w w w w w w
w   w   w w   w
w       w     w
w w   w w   w w
w     w     w w
w   w w   w   w
g             w
w w w w w w w w

其中“w”是墙,“g”是入口/出口。因此,墙被放置在网格中,例如,网格[1][2]='w'

递归除法算法的问题是墙不被视为单元格的成员。所有的“单元格”基本上都包含空白,墙将被放置在它们周围。

从本质上讲,用户将从红色方块开始,必须穿过迷宫并找到可以打开门(红色方块)以逃脱的钥匙,因此迷宫中的所有空白都必须是可访问的。

有人知道我如何重写这个算法,以确保迷宫中始终有一条从红色方块到任何其他空间的路径吗?理想情况下,路径永远不会超过一个正方形宽。

var grid;

function generate(dimensions, numDoors) {
    //numDoors is unused right now

    grid = new Array();
    for (var i = 0; i < dimensions; i++) {
        grid[i] = new Array();

        for (var j = 0; j < dimensions; j++) {
            grid[i][j] = "";
        }
    }

    addOuterWalls();
    var ent = addEntrance();
    addInnerWalls(true, 1, grid.length - 2, 1, grid.length - 2, ent);
}

function addOuterWalls() {
    for (var i = 0; i < grid.length; i++) {
        if (i == 0 || i == (grid.length - 1)) {
            for (var j = 0; j < grid.length; j++) {
                grid[i][j] = "w";
            }
        } else {
            grid[i][0] = "w";
            grid[i][grid.length - 1] = "w";
        }
    }
}

function addEntrance() {
    var x = randomNumber(1, grid.length - 1);
    grid[grid.length - 1][x] = "g";
    return x;
}

function addInnerWalls(h, minX, maxX, minY, maxY, gate) {
    if (h) {

        if (maxX - minX < 2) {
            return;
        }

        var y = randomNumber(minY, maxY);
        addHWall(minX, maxX, y);

        addInnerWalls(!h, minX, maxX, minY, y-1, gate);
        addInnerWalls(!h, minX, maxX, y + 1, maxY, gate);
    } else {
        if (maxY - minY < 2) {
            return;
        }

        var x = randomNumber(minX, maxX);
        addVWall(minY, maxY, x);

        addInnerWalls(!h, minX, x-1, minY, maxY, gate);
        addInnerWalls(!h, x + 1, maxX, minY, maxY, gate);
    }
}

function addHWall(minX, maxX, y) {
    var hole = randomNumber(minX, maxX);

    for (var i = minX; i <= maxX; i++) {
        if (i == hole) grid[y][i] = "";
        else grid[y][i] = "w";
    }
}

function addVWall(minY, maxY, x) {
    var hole = randomNumber(minY, maxY);

    for (var i = minY; i <= maxY; i++) {
        if (i == hole) grid[i][x] = "";
        else grid[i][x] = "w";
    }
}

function randomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

function display() {
    document.getElementById("cnt").innerHTML = "";

    for (var i = 0; i < grid.length; i++) {
        var output = "<div>";
        for (var j = 0; j < grid.length; j++) {
            output += "<b " + grid[i][j] + "></b>";
        }
        output += "</div>";
        document.getElementById("cnt").innerHTML += output;
    }
}
generate(30, 1, 1);
display();

共有1个答案

锺星洲
2023-03-14

只在偶数单元格中设置墙壁,在奇数单元格中设置门,并使“维度”奇数。http://jsfiddle.net/tPm3s/1/

Code:
var grid;

function generate(dimensions, numDoors) {
    grid = new Array();
    for (var i = 0; i < dimensions; i++) {
        grid[i] = new Array();

        for (var j = 0; j < dimensions; j++) {
            grid[i][j] = "";
        }
    }

    addOuterWalls();
    var ent = addEntrance();
    addInnerWalls(true, 1, grid.length - 2, 1, grid.length - 2, ent);
}

function addOuterWalls() {
    for (var i = 0; i < grid.length; i++) {
        if (i == 0 || i == (grid.length - 1)) {
            for (var j = 0; j < grid.length; j++) {
                grid[i][j] = "w";
            }
        } else {
            grid[i][0] = "w";
            grid[i][grid.length - 1] = "w";
        }
    }
}

function addEntrance() {
    var x = randomNumber(1, grid.length - 1);
    grid[grid.length - 1][x] = "g";
    return x;
}

function addInnerWalls(h, minX, maxX, minY, maxY, gate) {
    if (h) {

        if (maxX - minX < 2) {
            return;
        }

        var y = Math.floor(randomNumber(minY, maxY)/2)*2;
        addHWall(minX, maxX, y);

        addInnerWalls(!h, minX, maxX, minY, y-1, gate);
        addInnerWalls(!h, minX, maxX, y + 1, maxY, gate);
    } else {
        if (maxY - minY < 2) {
            return;
        }

        var x = Math.floor(randomNumber(minX, maxX)/2)*2;
        addVWall(minY, maxY, x);

        addInnerWalls(!h, minX, x-1, minY, maxY, gate);
        addInnerWalls(!h, x + 1, maxX, minY, maxY, gate);
    }
}

function addHWall(minX, maxX, y) {
    var hole = Math.floor(randomNumber(minX, maxX)/2)*2+1;

    for (var i = minX; i <= maxX; i++) {
        if (i == hole) grid[y][i] = "";
        else grid[y][i] = "w";
    }
}

function addVWall(minY, maxY, x) {
    var hole = Math.floor(randomNumber(minY, maxY)/2)*2+1;

    for (var i = minY; i <= maxY; i++) {
        if (i == hole) grid[i][x] = "";
        else grid[i][x] = "w";
    }
}

function randomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

function display() {
    document.getElementById("cnt").innerHTML = "";

    for (var i = 0; i < grid.length; i++) {
        var output = "<div>";
        for (var j = 0; j < grid.length; j++) {
            output += "<b " + grid[i][j] + "></b>";
        }
        output += "</div>";
        document.getElementById("cnt").innerHTML += output;
    }
}
generate(31, 1, 1);
display();
 类似资料:
  • 我在用递归解迷宫。我的矩阵是这样的 这是更大矩阵的原型。我的求解递归方法如下所示 你们可以注意到,这里我返回一个布尔值,如果我找到一条路径,它应该会给我一个真值。但它总是给我错误的答案。我不确定我在递归方法中犯的逻辑错误。方法如下 endX=3;endY=10;

  • (这不是一个复制品)我们有一个2D迷宫,四面都有X,还有内部的方块<迷宫的所有这些特征都存储在2D数组中。程序必须找到从开始“S”到目标“G”的路径。为此,将使用一个名为“solve(int row,int col)”的布尔方法,并使用“S”的行和列索引初始化该方法。算法必须是递归的。如果它能够找到通往“G”的路径,那么它应该返回true,否则返回false。下面是我试图解决这个问题的方法,它显示

  • 我一直在试图做一个程序,可以递归地解决一个迷宫(应该适用于任何迷宫)。该算法的大部分递归是有效的,但是当迷宫检查死胡同和重新路由以找到解决方案(终点)的方法时,代码就不起作用了。我已经尝试了多种方法来调试,但它没有让我走远;我要么得到StackOverflowError,要么算法返回一个位置。 注意2D阵列的“字符指示符”: '*' = 墙壁 '#' = 开始 “$” = 结束 ' ' = 可能的

  • 给定一个填充了0和1的二维字符数组,其中0代表一堵墙,1代表一条有效路径,我开发了一个名为findPath(int r,int c)的递归方法,用于在标有“x”的迷宫中找到出口。该方法接收迷宫的当前行和列,并通过N、E、S、W方向,直到找到有效路径,并用“”标记该有效路径。假设所有方向都被一堵墙挡住,那么该方法假设是回溯,直到情况不再如此,然后用“F”标记该路径,以表示坏路径。 现在我不明白为什么

  • 我做了一个递归算法来找到迷宫的解决方案,格式如下 其中一个“#”代表一堵墙,“#”代表一个开放空间(可以自由移动)。”S'代表开始位置,E'代表结束位置。 我的算法运行得很好,但我想知道如何修改它以获得最短路径。 在第一个街区,我找到了那条路并把它打开。还设置了写有路径的char[][]数组,该数组随后作为结果打印出来。 它工作得很好,但是我想知道什么是最好的方法来修改它,使它在找到第一条成功的路

  • 我正在尝试寻找到EndPotion的路径。这是一个递归函数。请帮助,我要自杀了。 这是给定的地图 我想递归地使用GetPath来到达上面地图中的EndPotion。参数是当前位置、结束位置和地图。对于这个例子,起始位置是(0,0)和结束,EndPotionis是(0,3),右上角。0代表墙壁,1代表路径。 我需要返回一个包含有效点的arraylist到结束位置。虽然我的数组大小始终为0,并且基本大