三维迷宫算法
回答
几年前,我使用Kruskal的算法here制作了2d迷宫。应该没有理由,这不适用于你描述的3D情况。基本上你会认为一个单元是一个立方体,并且有一个大的阵列(对于每个单元),在+/- x,y和z方向上有6个墙。该算法最初以所有墙壁开始,并随机使墙壁消失,直到连接迷宫中的每个单元格为止。
+1对于Kruskal算法。 :) –
我喜欢这个基本概念,但是也许目标不应该仅仅是让迷宫中的每个单元都连通,而是另外连接应该是无环的(图论理论中的一个“树”)。这将迫使迷宫的解决方案变得独一无二。这要求随机选择(内部)墙壁消失将被拒绝,只要它们会在连接中引入循环。相同地,这些“被拒绝”的选择是不减少图中连接组件的数量的选择。 – hardmath
hardmath;克鲁斯卡尔的算法负责这一点。我没有用我简单的解释来解释这一点。基本上,只有连接2个新区域时,墙才会被删除。它通过检查墙壁两侧的两个单元格是否属于不同的集合来完成此操作。这可以通过Disjoint-set数据结构非常有效地完成。维基百科链接更好地解释它。 –
我有用于在所有东西中生成2D迷宫的代码,RPGLE(我在学习语言时作为自我锻炼而做的)。由于我写的方式,关于通用算法必要的唯一更改是将Z尺寸作为附加尺寸添加...
整个事情是20页长(尽管这包括输入/输出) ,所以这里的一些的代码。你应该能够把它翻译成你需要的任何语言:我把它从BASIC的意大利面代码(goto
这里被过度使用,是的,但这是一个有趣的练习)。一个用于占据了“广场”,另为方是否已被访问过的墙壁:
//set out maximum maze size
maximumMazeSquareCounter = mazeHorizontalSize * mazeVerticalSize + 1;
// generate a starting horizontal positiongetRandomNumber(seed : randomNumber);
currentHorizontalPosition = %inth(randomNumber * (mazeHorizontalSize - 1)) + 1;
currentVerticalPosition = 1;
mazeSquareCounter = 1;
// generate the top row of the maze (with entrance)
mazeTopRow = generateEntrance(currentHorizontalPosition);
//write to the printer file
writeMazeDataLine(mazeTopRow);
mazeSquareCounter += 1;
//set the first position in the maze(the entry square
setPathPoint(currentHorizontalPosition : currentVerticalPosition);
//do until we've reached every square in the maze
dou mazeSquareCounter >= maximumMazeSquareCounter;
//get the next available random direction
mazeDirection = getNextRandomDirection(getNextAvailableDirection(currentHorizontalPosition : currentVerticalPosition));
//select what to do by the returned results
select;
//when FALSE is returned - when the maze is trapped
when mazeDirection = FALSE;
//if not at the horizontal end of the maze
if currentHorizontalPosition <> mazeHorizontalSize;
//add one to the position
currentHorizontalPosition += 1;
//else if not at the vertical end of the maze
elseif currentVerticalPosition <> mazeVerticalSize;
//reset the horizontal position
currentHorizontalPosition = 1;
//increment the vertical position
currentVerticalPosition += 1;
//otherwise
else;
//reset both positions
currentHorizontalPosition = 1;
currentVerticalPosition = 1;
endif;
//when 'N' is returned - going up (other directions removed)
when mazeDirection = GOING_NORTH;
//set the point above current as visited
setPathPoint(currentHorizontalPosition : currentVerticalPosition - 1);
//set the wall point to allow passage
setWallDirection(currentHorizontalPosition : currentVerticalPosition : GOING_NORTH);
//change the position variable to reflect change
currentVerticalPosition -= 1;
//increment square counter
mazeSquareCounter += 1;
endsl;
enddo;
//generate a random exit
// get a random number
getRandomNumber(seed : randomNumber);
// set to the horzontal position
currentHorizontalPosition = %inth(randomNumber * (mazeHorizontalSize - 1)) + 1;
//set the vertical position
currentVerticalPosition = mazeVerticalSize;
//set wall to allow for exit
setWallDirection(currentHorizontalPosition : currentVerticalPosition : GOING_SOUTH);
整个事情是由两个二维数组(当然,在RPG当量)的支持。迷宫在每个广场被访问后创建。只有一条道路,蠕虫迷宫。
为了使这个三维,使它使用三维数组,并添加必要的维度指数。
我前段时间为方形网格上的2D迷宫设计了一种算法,但没有理由说它不适用于立方网格上的3D迷宫。
从最初填满墙单元的3D网格开始。
...
开始在网格的边缘上的试剂,该试剂在X沿直线行进,Y,Z,-X,-Y或-Z方向结算壁她行进。
行动'N'发生每一步的几率很小。
当代理前面的单元格是wall并且前面的单元格为空时,会发生操作'M'。
“N”是的一个随机选择:
- 去除剂
- 左转或右转90度
- 并创建在同一正方形的试剂左转90度,向右或两者(两个代理商)。
'M' 是一个随机选择:
- 去除剂
- 除去该代理人的正面壁,然后除去该代理
- 并无所作为,进行
- 左转或右转90度。
- 并在同一方格上创建一个代理,向左,向右或两个方向(两个代理)转过90度。
迷宫是独特的,它们的字符是通过调节触发关于“M”(做有效结),并通过也调整为1机会8发生的高度灵活的。您可能希望删除一两个动作,或者引入您自己的动作,例如一个做一个小的清除或跳一步。
'N'的触发器也可以是另一种随机性,例如下面的例子可以用来创建仍然有一些长直线部分的相当多的迷宫。
float n = 1;
while (random_0_to_1 > 0.15)
{
n *= 1.2;
}
return (int)n;
一些小的调整,会从我的简单的描述是必要的,例如触发行动的“M”将需要检查与其相邻的检查,以及根据是什么样的路口的细胞的细胞可取的。
迷宫需要5或6个才能包含循环,至少有一个替代的'M'动作需要5和6才能让迷宫包含死角。
一些机会/动作和'M'触发器的选择会使迷宫不起作用,例如无法解决或充满空的或壁单元,但许多会产生一致的好结果。
- 1. 二维迷宫的递归算法?
- 2. DFS算法迷宫生成
- 3. 穿越迷宫的算法
- 4. 迷宫算法生成最困难的迷宫?
- 5. 递归迷宫算法(在迷宫中旋转件)
- 6. 迷宫/迷宫游戏
- 7. 迷宫算法路径查找器
- 8. 迷宫与路径寻找算法
- 9. 迷宫遍历算法递归
- 10. 用Floyd-Warshall算法寻找迷宫
- 11. 生成迷宫使用DFS算法
- 12. 迷宫解决算法Java(递归)
- 13. 迷宫算法,实际工作
- 14. 迷宫算法堆栈溢出
- 15. 洪水填充算法 - 迷宫导航
- 16. 在C++中的迷宫求解算法
- 17. 洪水填补算法迷宫
- 18. 迷宫算法KINDA的作品。一些迷宫,并非全部帮助
- 19. 解决迷宫问题的迷宫
- 20. 出界异常 - 二维数组迷宫
- 21. 迷宫中的路径(二维阵列)
- 22. 国王迷宫
- 23. 构建迷宫
- 24. 计算迷宫中的uniq路径数
- 25. 在android中用于迷宫生成的递归除法算法
- 26. Python迷宫递归
- 27. MatLab迷宫求解
- 28. Java递归迷宫
- 29. 迷宫不工作?
- 30. 递归迷宫代
你想要一个_solves_迷宫,或_generates_迷宫吗? –
@ X-Zero生成它。 – jmasterx
你可以在一个网格上创建一个2D迷宫,并使其成为3D每个网格单元将改为一个具有“高度”的框 – danca