关于java:Prim的生成迷宫的算法:获取邻居单元

Prim's algorithm for generating a maze: Getting the neighbour cell

我将迷宫生成器程序基于Prim的算法:

该算法是Prim算法的随机版本。

  • Start with a grid full of walls.
  • Pick a cell, mark it as part of the maze. Add the walls of the cell to the wall list.
  • While there are walls in the list:

  • Pick a random wall from the list.
    If the cell on the opposite side isn't in the maze yet:

  • Make the wall a passage and mark the cell on the opposite side as part of the maze.
  • Add the neighboring walls of the cell to the wall list.
  • If the cell on the opposite side already was in the maze, remove the wall from the list.
  • (来自维基百科)

    我已经了解了算法,只是停留在这一部分:
    "知道相邻单元格是否构成迷宫的一部分"(这意味着,首先获取相邻单元格)
    由于单元格实际上是一棵树的节点(迷宫,单元格的二维阵列),而墙是这些节点之间的边缘,我认为有必要用一对点(x,y )。我如何知道两个单元是否通过墙连接?
    (请记住,每个单元都有4面墙)

    我考虑过使用equals()函数。我只是要求提供一个伪代码或您的最佳解释,以使事情变得容易。

    我的Wall类具有三个属性:bool isWall(确定它是墙还是单元格之间的通道); int x; int y(标识符)。

    如果您认为我需要更多属性,我将很高兴知道。我知道有一种简单的方法,只是卡住了;)
    谢谢你的时间!


    让我们看看我们可以定义什么:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     Cell[][] maze; // prepopulate with cells in a rectangular fashion.
                    // Populate adjacent cells with walls.
     {
         maze = new Cell[m][n];
         for (i = 0 .. m) {
             for (j = 0 .. n) {
                 cell = maze[i][j] = new Cell(m, n);

                 // fix top wall
                 if (i == 0) { // first row
                     cell.wall[0] = new Wall();
                     cell.wall[0].setIsEdge();
                 } else {
                     cell.wall[0] = maze[i-1][j].wall[2]; // my up is last row's down
                 }

                 // fix bottom wall
                 cell.wall[2] = new Wall();
                 if (i == m-1) { // last row
                     cell.wall[2].setIsEdge();
                 }

                 // fix left wall
                 if (j == 0) { // leftmost column
                     cell.wall[3] = new Wall();
                     cell.wall[3].setIsEdge();
                 } else {
                     cell.wall[3] = maze[i][j-1].wall[1]; // my left is last col's right
                 }

                 // fix right wall
                 cell.wall[1] = new Wall();
                 if (j == n-1) { // rightmost column
                     cell.wall[1].setIsEdge();
                 }
             }
         }
     }

     List walls = new List();

     class Cell {
         Wall[] walls = new Wall[4]; // 0 is up, 1 is right, 2 is down, 3 is left (count clockwise)
         boolean isInMaze = false;
         int x;
         int y;
         Cell(col, row) {
             x = col;
             y = row;
         }
     }

     class Wall {
         boolean isOpen = false; // open walls are passages
         boolean isEdge = false; // edges have nothing on the other side.
         Cell[] cells = new Cell[2];
     }

     Cell aCell = maze[randomx][randomy]; // make sure x,y in bounds
     initializeCellInMaze(aCell, null);

     while (!walls.isEmpty()) {
        aWall = walls.get(randomWall); // in range
        if (!(aWall.cell[0].isInMaze && aWall.cell[1].isInMaze)) {
            // opposite cell NOT in maze
            wall.setIsOpen();
            Cell otherCell;
            if (wall.cell[0].isInMaze) {
                otherCell = wall.cell[1];
            } else {
                otherCell = wall.cell[0];
            }
            initializeCellInMaze(otherCell, aWall);
        }
        walls.remove(aWall); // or use index
     }

     initializeCellInMaze(cell, wallToSkip) {
         cell.setIsInMaze();
         for (i = 0 .. 3) if (cell.wall[i] != wallToSkip) walls.add(cell.wall[i]);
     }

    我无法评论添加到讨论中,所以请回答一个答案。基本上,Lee Meandor具有正确的想法。

    enter image description here

    这是细胞与壁对细胞关系的基本结构。

    因此,一个单元具有南北西和东壁。

    一堵墙在连接它们的两个相邻单元之间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Class Cell{

       Wall North;
       Wall South;
       Wall East;
       Wall West;

    }


    Class Wall{
        // You can store the cells that are connected to the wall but it's not necessary.
        Cell 1;
        Cell 2;

        bool isUP;
    }

    请记住,重要的是细胞要指向正确的墙。

    那是一些重要的逻辑工作:)。

    如果您需要帮助,请发表评论。


    好吧,我整个下午都在您的帮助下为迷宫发生器编码。
    现在,我迷上了这种迷宫(抱歉,我的大屏幕截图没有照片编辑器。)

    enter image description here

    我认为问题是我如何返回邻居小区。也许不吧。
    这就是我返回邻居单元格的方式,我用@progenhard方式完成了,墙上有2个单元格,cell1和cell2,如果cell1被占用,则返回cell2,反之亦然:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public Cell getNeighbourCell(Wall wall, Cell cell) {
        if (wall.getCell1().equals(cell)) {
            return wall.getCell2();

        } else {

            return  wall.getCell1();

        }
    }

    再次感谢!