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具有正确的想法。
这是细胞与壁对细胞关系的基本结构。
因此,一个单元具有南北西和东壁。
一堵墙在连接它们的两个相邻单元之间。
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; } |
请记住,重要的是细胞要指向正确的墙。
那是一些重要的逻辑工作:)。
如果您需要帮助,请发表评论。
好吧,我整个下午都在您的帮助下为迷宫发生器编码。
现在,我迷上了这种迷宫(抱歉,我的大屏幕截图没有照片编辑器。)
我认为问题是我如何返回邻居小区。也许不吧。
这就是我返回邻居单元格的方式,我用@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(); } } |
再次感谢!