三维迷宫的算法

时间:2011-12-10 00:15:06

标签: c++ algorithm maze

是否有生成三维迷宫的算法?基本上与2D迷宫相同,但可以遍历Z深度轴?但是,从头到尾,这个想法仍然是一样的。还可以使用回溯吗?

我应该使用哪种算法来生成3D迷宫?

here。我的意思是你也可以进入立方体,不只是迭代它的面孔。

3 个答案:

答案 0 :(得分:8)

几年前我使用Kruskal的算法here制作了2d迷宫。应该没有理由这对你描述的3d情况不起作用。基本上你会认为一个单元格是一个立方体,并且有一个大的数组(对于每个单元格),在+/- x,y和z方向上有6个墙。该算法最初从所有墙壁开始,随机地使墙壁消失,直到迷宫中的每个细胞都连接起来。

答案 1 :(得分:0)

我有代码用于生成2D迷宫,其中包括RPGLE(我在学习语言时所做的自我练习)。由于我编写它的方式,关于一般算法所需的唯一变化是将Z维度添加为附加维度......

整个事情长达20页(虽然这包括输入/​​输出),所以这里是一些代码。你应该能够将它翻译成你需要的任何语言:我将它翻译成意大利面条代码BASIC(goto s在这里过度使用,是的。但这是一个有趣的练习。)

//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等价物):一个用于占据“正方形”的墙壁,另一个用于是否已经访问过这个方块。在访问每个方格之后创建迷宫。只有一条通道,一条蜗杆转弯的迷宫。

要使这个三维,使其使用三维数组,并添加必要的维度索引。

答案 2 :(得分:0)

我前段时间为方形网格上的二维迷宫设计了一种算法,没有理由认为它不适用于立方网格上的三维迷宫。

从最初完全填充墙细胞的3D网格开始。

...

在网格的边缘启动代理,代理在旅行时沿X,Y,Z,-X,-Y或-Z方向清除墙沿直线行进。

行动&#39; N&#39;每一步都很少发生。

行动&#39; M&#39;当直接位于代理前面的单元格是墙壁并且前面的单元格为空时发生。

&#39; N&#39;随机选择:

  1. 删除该代理
  2. 向左或向右转90度
  3. 并在同一个方格上创建一个代理,向左,向右或两者转动90度(两个代理)。
  4. &#39; M&#39;随机选择:

    1. 删除该代理
    2. 移除该代理前面的墙,然后删除该代理
    3. 无所事事,继续进行
    4. 向左或向右转90度。
    5. 并在同一个方格上创建一个代理,向左,向右或两者转动90度(两个代理)。
    6. 迷宫是独特的,通过调整“M&#39;”的触发器,它们的特性非常灵活。 (与有效的交叉点有关)并且还调整发生1到8的机会。您可能想要删除一两个动作,或者引入您自己的动作,例如一个动作进行小规模清理或回避一步。

      触发N&#39; N&#39;也可以是另一种随机性,例如下面的例子可以用来创建相当多的迷宫,它仍然有一些很长的直线部分。

      float n = 1;
      
      while (random_0_to_1 > 0.15)
      {
          n *= 1.2;
      }
      
      return (int)n;
      

      我的简单描述需要进行一些小的调整,例如触发操作&#39; M&#39;将需要检查它检查的细胞附近的细胞,这取决于所需的结点类型。

      迷宫需要5或6个来包含周期和至少一个替代方案&#39; M&#39;迷宫需要动作到5和6,以包含死角。

      一些机会/行动的选择以及&#39; M&#39;触发器往往会制造不起作用的迷宫,例如无法解决或充满空洞或墙壁细胞的迷宫,但许多会产生一致的好结果。