【问题标题】:Drawing and representing maze with walls in array绘制和表示具有阵列墙壁的迷宫
【发布时间】:2015-08-25 07:51:03
【问题描述】:

我正在尝试使用深度优先搜索创建一个迷宫,并且该算法运行良好,但我在控制台中实际绘制迷宫并通常表示迷宫时遇到问题。我之前的尝试包括表示网格的每个位置在一个 3x3 块中,对于每个位置,如果有一个墙,我会画一堵墙,但这会为左/右、上/下的每个方向提供 2 个墙。我的第二次尝试是尝试将迷宫放入一个维度为 + (dimension - 1) 的二维数组中,并将墙壁视为如下所示的线条:

这是我的尝试:

    int dimTemp             =   dim + (dim - 1);
    String[][] mazeDrawn    =   new String[dimTemp][dimTemp];

    int posRow, posCol;
    int nodeRow = 0;
    int nodeCol;

    for(int wallRow = 1; wallRow <= dimTemp; wallRow += 2)
    {
        if(wallRow >= dimTemp)
        {
            wallRow--;
            posRow =   wallRow;
        }   

        else posRow =   wallRow - 1;
        nodeCol =   0;

        for(int wallCol = 1; wallCol <= dimTemp; wallCol += 2)
        {
            if(wallCol >= dimTemp) 
            {
                wallCol--;
                posCol          =   wallCol;
            }

            else posCol = wallCol - 1;

            Node current    =   maze[nodeRow][nodeCol];
            mazeDrawn[posRow][posCol] =   current.getPosValue();

            if(current.right) mazeDrawn[posRow][wallCol] = "#";
            else mazeDrawn[posRow][wallCol] = " ";

            mazeDrawn[wallRow][wallCol] = "#";
            if(current.down) mazeDrawn[wallRow][posCol] = "#";
            else mazeDrawn[wallRow][posCol] = " ";

            nodeCol++;
        }

        nodeRow++;
    }


    for(int row = 0; row < mazeDrawn.length; row++)
    {
        for(int col = 0; col < mazeDrawn.length; col++)
        {
            System.out.print(mazeDrawn[row][col]);
        }
        System.out.println();
    }

这是一个 10x10 迷宫的输出,在我运行 DFS 之前,每个位置之间都有一堵墙,# 是“墙”和 .是职位

.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#*#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
.#.#.#.#.#.#.#.#.##
###################
###################

底部和右侧边缘存在问题,应遵循它们之前的模式。我不确定这是否是表示迷宫的好方法。 还要澄清一下,我只是想打印到控制台。

【问题讨论】:

  • 你的目标是用 # 和 . 代表迷宫吗?或者为迷宫实现一些算法。
  • 因为如果您的主要目标是实现一些算法,那么我们总是使用 1 和 0 来表示迷宫,其中 1 表示没有墙,0 表示有墙,并且二维数组本身的尺寸会处理边界。
  • 这就是我所做的,除了 char '#' 是一堵墙,我有一个更大的数组,这样边缘/墙就有自己的索引
  • 所以主要是你有一个 1 和 0 的迷宫,然后你想打印一个 #(wall) 和 .(position) 的迷宫是你想要的吗?

标签: java algorithm graph


【解决方案1】:

你可以很容易地用每个单元格一个字节(实际上是四位)来表示一个迷宫。为每个单元格壁分配一个位。例如:

   0
   _
3 |_| 1

   2

因此,具有所有四个墙壁的单元格将表示为二进制 1111,或 15。如果仅存在顶部和右侧墙壁,则值为 0011,或 3。没有墙壁的单元格的值为 0。

你也可以做得更好。如果您推断迷宫顶部和左侧边缘上的所有单元格都存在顶部和左侧壁,那么每个单元格只需要两个位。如果您从左上角到右下角绘制迷宫,那么对于每个单元格,您只需要弄清楚是否存在底部或右侧墙壁。没有理由检查左侧或顶部,因为它们会被前一列或前行绘制。

当然,如果您在第 5 行第 3 列(即单元格 [5, 3]),并且您想知道上面是否有墙,则必须检查单元格 [4, 3] 才能看到如果单元格底部的墙存在。这需要更多的计算,但可以节省 50% 的空间。

【讨论】:

  • 我的第一个想法是为迷宫取正确的 unicode 字符...看看 '\u2500' 中的那些字符
  • @MartinFrank:让我想起了在 IBM PC 上使用这些字符绘制方框。我没有那么雄心勃勃。 ASCII 艺术 FTW!
  • 尽管我看起来更年轻,但这是一种非常好的工作方式——使用 ascii 字符创建 gui——我想念那个......
【解决方案2】:

可以使用 3x3 矩阵来表示你的迷宫,您只需将其绘制为 2x2 矩阵

看看这张图,你有

  • 黄色 3x3 网格
  • 红色 3x3 网格
  • 蓝色 3x3 网格

当您绘制每个 3x3 网格时,您重叠每个网格有点...

这只有在你的迷宫被正确创建的情况下才有效:

  • 如果 cell@x/y 在西边有一堵墙 (/door),那么 cell@x-1/y 在东边有一堵墙 (/door) -> 你不必绘制cell@x-1/y的东部

  • 如果 cell@x/y 在北面有墙(/door),那么 cellx/y-1 在南面有墙(/door) -> 你不必绘制cellx/y-1的南部

让我们说代码:

for (int dy = 0; dy < maze.width; dy ++){

    String upperLine = ""; //first line of row
    String lowerLine = ""; //second line of row

    for (int dx = 0; dx < maze.width; dx ++){ 
         //first symbol always is #
         upperLine = upperline + "#"; //always there

         //second symbol depends on wall?#:.
         if(cell[dx][dy].hasWall[Direction.N]){
             upperline = upperline+"#";
         }else{
             upperline = upperline+".";
         }

         //thats all for the upper line right now

         //now comes lower line
          if(cell[dx][dy].hasWall[Direction.W]){
             lowerLine = lowerLine +"#";
         }else{
             lowerLine = lowerLine +".";
         }

         //center is always '.'
         lowerLine = lowerLine + ".";
    }

    System.out.println(upperLine);
    System.out.println(lowerLine);
}

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    相关资源
    最近更新 更多