这里通过回溯生成迷宫的工作正常但事实是我试图在像素游戏(Minecraft)中实现这一点......所以问题在于绘制迷宫。在这个游戏中,墙块的大小应该与空块/空间的大小完全相同,所以我想到的唯一解决方案是名为totalmaze的奖励2d阵列。它的目的是存储空的空间和墙块,所以我做了它的大小(x * 3,y * 3)并尝试输出墙,但不幸的是,这会导致很多问题,例如空间太大/阻塞路径。注意:X,Z因为它是一个3d迷宫。
如果这是JavaScript和一个简单的应用程序,我只会画墙作为线条,但在Minecraft中,尺寸应该相同,所以即使算法是正确的,这也是麻烦的地方。请帮忙。
这就是我试图修复它的方法,但可能不是这样:https://prnt.sc/fbp88o
public function generateMaze($dim_x, $walls_height, $dim_z){
$maze = array();
$moves = array();
$cell_count = $dim_x*$dim_z;
for($position=0; $position<$cell_count; $position++){
$maze[$position] = "01111"; // visited, NSEW
}
$pos=0;
$maze[0]{0} = 1; /// initial
$visited = 1;
// determine possible directions
while($visited<$cell_count){
$possible = "";
if((floor($pos/$dim_x)==floor(($pos-1)/$dim_x)) and ($maze[$pos-1]{0}==0)){
$possible .= "W";
}
if((floor($pos/$dim_x)==floor(($pos+1)/$dim_x)) and ($maze[$pos+1]{0}==0)){
$possible .= "E";
}
if((($pos+$dim_x)<$cell_count) and ($maze[$pos+$dim_x]{0}==0)){
$possible .= "S";
}
if((($pos-$dim_x)>=0) and ($maze[$pos-$dim_x]{0}==0)){
$possible .= "N";
}
if($possible){
$visited ++;
array_push($moves,$pos);
$direction = $possible{rand(0,strlen($possible)-1)};
switch($direction){
case "N":
$maze[$pos]{1} = 0;
$maze[$pos-$dim_x]{2} = 0;
$pos -= $dim_x;
break;
case "S":
$maze[$pos]{2} = 0;
$maze[$pos+$dim_x]{1} = 0;
$pos += $dim_x;
break;
case "E":
$maze[$pos]{3} = 0;
$maze[$pos+1]{4} = 0;
$pos ++;
break;
case "W":
$maze[$pos]{4} = 0;
$maze[$pos-1]{3} = 0;
$pos --;
break;
}
$maze[$pos]{0} = 1;
}
else{
$pos = array_pop($moves);
}
}
$totalmaze = array();
for($i=0; $i<$dim_x*3+1; $i++){
$totalmaze[$i][0] = 1;
$totalmaze[$i][$dim_z*3-1]=1;
}
for($i=0; $i<$dim_z*3+1; $i++){
$totalmaze[0][$i] = 1;
$totalmaze[$dim_x*3-1][$i]=1;
}
for($position=0; $position<$cell_count; $position++){
$x = $position % $dim_x;
$z = floor($position / $dim_x);
if($maze[$position]{1} == 1){
$totalmaze[$x*3+1][$z*3]=1;
}
if($maze[$position]{2} == 1){
$totalmaze[$x*3+1][$z*3+2]=1;
}
if($maze[$position]{3} == 1){
$totalmaze[$x*3+2][$z*3+1]=1;
}
if($maze[$position]{4} == 1){
$totalmaze[$x*3][$z*3+1]=1;
}
}
答案 0 :(得分:3)
我认为在评论中很难解释随机化的Prim算法。所以我决定发一个新答案。
随机化Prim算法中的壁细胞实际上具有&#34;方向&#34;。考虑下面的迷宫,其中#表示墙和。表示空单元格(位置从0开始)。
#####
#...#
###.#
#...#
#####
位于(2,1)的墙壁连接两个单元(1,1)和(3,1),但不是(2,0)和(2,2)(因为它们都是墙壁)。一旦我们选择了第一个空单元,就会确定所有墙的方向。这是因为墙在图中用作边,并且当我们选择第一个空单元时确定图。你可以在纸上画一些迷宫并亲自看看。
我还编写了随机Prim算法的python示例。尝试运行它。
import random
SIZE = 21
# Fill the maze with walls
maze = [['#' for j in range(0, SIZE)] for i in range(0, SIZE)]
# Create an empty wall list
wall_list = []
# Check if the given position is in the maze and not on the boundary
def in_maze(row, col):
return row > 0 and row < SIZE-1 and col > 0 and col < SIZE-1
# Add the neighboring walls of the cell (row, col) to the wall list
def add_walls(row, col):
global maze, wall_list
# It's a 4-connected grid maze
dir = ((0, 1), (1, 0), (0, -1), (-1, 0))
for k in range(0, len(dir)):
# Calculate the neighboring wall position and the cell position
wall_row = row + dir[k][0]
wall_col = col + dir[k][1]
cell_row = wall_row + dir[k][0]
cell_col = wall_col + dir[k][1]
# Make sure the wall grid is in the range of the maze
if not in_maze(wall_row, wall_col) or not in_maze(cell_row, cell_col):
continue
# Add the wall and the neighboring cell to the list
wall_list.append(((wall_row, wall_col), (cell_row, cell_col)))
# Pick a random grid first
cell_row = random.randint(1, SIZE-2)
cell_col = random.randint(1, SIZE-2)
maze[cell_row][cell_col] = '.'
add_walls(cell_row, cell_col)
while len(wall_list) > 0:
# Pick a random wall
id = random.randint(0, len(wall_list)-1)
wall_row, wall_col = wall_list[id][0]
cell_row, cell_col = wall_list[id][1]
wall_list.pop(id)
# Skip if it is no longer a wall
if maze[wall_row][wall_col] != '#':
continue
# Skip if the two cells that the wall divides are visited
if maze[cell_row][cell_col] == '.':
continue
# Make the two grid as passages
maze[wall_row][wall_col] = '.'
maze[cell_row][cell_col] = '.'
# Add the neighboring walls
add_walls(cell_row, cell_col)
# Print the maze
for row in maze:
print(''.join(row))
你应该得到这样的东西
#####################
#.#.....#.#.#.......#
#.###.###.#.###.#.###
#.#.....#...#.#.#.#.#
#.###.#.###.#.###.#.#
#...#.#...#...#.....#
#.#.###.#####.#.#####
#.#.#.........#...#.#
###.#########.###.#.#
#.#...........#...#.#
#.#########.#.###.#.#
#.........#.#...#...#
#####.###.###.#####.#
#...#.#.#...........#
###.###.#####.###.###
#.......#.....#.....#
#.#.###.#####.#####.#
#.#.#...#...#.#.....#
#####.#.###.#####.###
#.....#.............#
#####################
答案 1 :(得分:1)
要产生“阻挡”迷宫,有更好的方法。为什么不尝试像Kruskal这样的生成树算法呢?请查看以下链接。
https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal.27s_algorithm