doudao1282 2017-05-24 19:51
浏览 86
已采纳

php - 回溯迷宫生成(将所有内容转换为2d数组)

Here generating a maze by backtracking works correctly but the thing is that I am trying to implement this in a pixel game (Minecraft)... so the problem is in drawing the maze. In this game, the size of the wall blocks should be the exact same as the size of an empty block/space, so the only solution I thought of was a bonus 2d array called totalmaze. Its purpose is to store both empty spaces and wall blocks so I made its size (x*3, y*3) and tried outputting the walls but unfortunately this causes a lot of problems such as too much empty space / blocked paths. Note : X, Z because it is a 3d maze.

If this was JavaScript and a simple app, I would just draw the walls as lines but in Minecraft, the sizes should be the same so this is where things become troublesome even though the algorithm is correct. Please help.

This is how I am trying to fix it but perhaps is not the way : 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;
            }

        }
  • 写回答

2条回答 默认 最新

  • doukanxi4246 2017-05-25 14:28
    关注

    I think it's hard to explain the randomized Prim's algorithm in the comments. So I decided to post a new answer.

    The wall cells in randomized Prim's algorithm actually have "directions". Consider the maze below where # indicates a wall and . indicates an empty cell (the positions are 0-based).

    #####
    #...#
    ###.#
    #...#
    #####
    

    The wall positioned at (2, 1) links two cells (1, 1) and (3, 1), but not (2, 0) and (2, 2) (as both of them are walls). As soon as we pick our very first empty cell, the directions of all walls are determined. That is because the walls serve as edges in a graph, and the graph is determined when we choosw the first empty cell. You can draw some mazes on paper and see it yourself.

    I've also written a python example of the randomized Prim's algorithm. Try to run it.

    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))
    

    You should get something like this

    #####################
    #.#.....#.#.#.......#
    #.###.###.#.###.#.###
    #.#.....#...#.#.#.#.#
    #.###.#.###.#.###.#.#
    #...#.#...#...#.....#
    #.#.###.#####.#.#####
    #.#.#.........#...#.#
    ###.#########.###.#.#
    #.#...........#...#.#
    #.#########.#.###.#.#
    #.........#.#...#...#
    #####.###.###.#####.#
    #...#.#.#...........#
    ###.###.#####.###.###
    #.......#.....#.....#
    #.#.###.#####.#####.#
    #.#.#...#...#.#.....#
    #####.#.###.#####.###
    #.....#.............#
    #####################
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决