有没有算法可以生成三维迷宫?本质上与二维迷宫相同,但Z深度轴可以遍历。然而,想法仍然相同,即从起点到终点。能否仍然使用回溯算法?
我应该使用哪个算法来生成3D迷宫?
请参见这里。我的意思是你可以进入立方体内部,而不仅仅是遍历其表面。
我应该使用哪个算法来生成3D迷宫?
请参见这里。我的意思是你可以进入立方体内部,而不仅仅是遍历其表面。
我一段时间前设计了一个用于正方形网格上的2D迷宫的算法,没有理由这个算法不也适用于立方体网格上的3D迷宫。
从一个初始完全由墙细胞填充的3D网格开始。
...
在网格的边缘启动一个代理,代理沿X、Y、Z、-X、-Y或-Z方向直线行驶,并在行驶过程中清除墙壁。
每一步都有一定几率发生“N”操作。
当代理正前方的单元格是墙,而其前面的单元格为空时,“M”操作会发生。
“N”是以下选项的随机选择:
“M”是以下选项的随机选择:
迷宫是独特的,通过调整“M”触发器(与有效交叉口有关)和调整1到8出现的机会,其特性非常灵活。您可能想要删除一两个动作,或者引入自己的动作,例如制作一个小空地或向侧面移动一步。
“N”的触发器也可以是另一种随机性,例如下面的示例可用于创建相当分支的迷宫,但仍具有一些长直部分。
float n = 1;
while (random_0_to_1 > 0.15)
{
n *= 1.2;
}
return (int)n;
从我的简单描述中需要进行一些小的调整,例如触发动作'M'的触发器还需要检查相邻的单元格,具体取决于所需的交叉口类型。
迷宫中需要5或6个循环,至少需要一种替代'M'动作来避免死路。
某些机会/动作和'M'触发器的选择可能会导致迷宫无法解决或充满空单元格或墙壁,但许多选择可以产生一致好的结果。
我有生成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);