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

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?