我该如何停止在我的ASCII迷宫中同时打印墙壁的两侧?

7
我写了一些代码来生成迷宫。迷宫由 (n x n) 个单元格组成,每个单元格都有一个布尔值来表示墙(北、南、东、西)。
它运行良好,我编写了下面的函数来打印迷宫:
public static void printMaze(Cell[][] maze)
    {
        for(int i = 0; i < maze.length; i++)
        {
            for(int j = 0; j < maze[i].length; j++)
            {
                System.out.print((maze[i][j].walls.get(Dir.NORTH)) ? "+--+" : "+  +"); 
            }
            System.out.println();
            for(int j = 0; j < maze[i].length; j++)
            {
                System.out.print((maze[i][j].walls.get(Dir.WEST)) ? "|" : " ");
                System.out.print("  ");
                System.out.print((maze[i][j].walls.get(Dir.EAST)) ? "|" : " ");
            }
            System.out.println();
            for(int j = 0; j < maze[i].length; j++)
            {
                System.out.print((maze[i][j].walls.get(Dir.SOUTH)) ? "+--+" : "+  +");
            }
            System.out.println();
        }
    }

然而,由于细胞共享墙壁,在我的打印函数中会产生一种双层墙廊的外观:
+--++--++--++--++--++--++--++--++--++--+
|      ||                  ||          |
+--++  ++--++--++  ++--++--++  ++  ++--+
+--++  ++--++--++  ++--++--++  ++  ++--+
|  ||          ||  ||          ||      |
+  ++--++--++  ++  ++  ++--++--++--++  +
+  ++--++--++  ++  ++  ++--++--++--++  +
|      ||      ||  ||  ||      ||  ||  |
+  ++  ++  ++--++  ++  ++  ++  ++  ++  +
+  ++  ++  ++--++  ++  ++  ++  ++  ++  +
|  ||  ||  ||  ||          ||      ||  |
+  ++  ++  ++  ++  ++--++--++--++--++  +
+  ++  ++  ++  ++  ++--++--++--++--++  +
|  ||      ||          ||          ||  |
+  ++--++--++--++--++--++  ++--++  ++  +
+  ++--++--++--++--++--++  ++--++  ++  +
|  ||          ||          ||      ||  |
+  ++--++  ++  ++  ++--++--++  ++--++  +
+  ++--++  ++  ++  ++--++--++  ++--++  +
|          ||  ||  ||      ||  ||      |
+--++--++--++  ++  ++  ++  ++  ++  ++  +
+--++--++--++  ++  ++  ++  ++  ++  ++  +
|          ||  ||  ||  ||  ||      ||  |
+  ++  ++--++  ++  ++  ++  ++--++--++  +
+  ++  ++--++  ++  ++  ++  ++--++--++  +
|  ||  ||      ||      ||  ||  ||      |
+  ++  ++  ++--++--++--++  ++  ++  ++--+
+  ++  ++  ++--++--++--++  ++  ++  ++--+
|  ||                      ||          |
+--++--++--++--++--++--++--++--++--++--+

我应该如何修改我的打印函数,使其看起来像这样:
+--+--+--+--+--+--+--+--+--+--+
|     |              |        |
+--+  +--+--+  +--+--+  +  +--+
|  |        |  |        |     |
+  +--+--+  +  +  +--+--+--+  +
|     |     |  |  |     |  |  |
+  +  +  +--+  +  +  +  +  +  +
|  |  |  |  |        |     |  |
+  +  +  +  +  +--+--+--+--+  +
|  |     |        |        |  |
+  +--+--+--+--+--+  +--+  +  +
|  |        |        |     |  |
+  +--+  +  +  +--+--+  +--+  +
|        |  |  |     |  |     |
+--+--+--+  +  +  +  +  +  +  +
|        |  |  |  |  |     |  |
+  +  +--+  +  +  +  +--+--+  +
|  |  |     |     |  |  |     |
+  +  +  +--+--+--+  +  +  +--+
|  |                 |        |
+--+--+--+--+--+--+--+--+--+--+

我担心当我最终开始使用实际图形而不是ascii来绘制我的迷宫时,我会遇到类似的问题。
如何修改我的printMaze方法,使其从第一个例子变为第二个例子?
如果有人感兴趣,生成这些的类的源代码在这里
3个回答

5

仅打印北墙和西墙。代码正在路上...

我将墙壁更改为EnumSet。

public Set<Dir> walls = EnumSet.allOf(Dir.class);

所以在构造函数中您不需要添加任何障碍物:
public Cell(final int x, final int y) {
    this.x = x;
    this.y = y;
    this.Visited = false;
}

如果您想要删除墙壁,请使用以下命令:

this.walls.remove(randDir);
randomNeighbor.walls.remove(randDir.opposite());

然后打印代码看起来像这样:

public static void printMaze(final Cell[][] maze) {
    for (int r = 0; r < maze.length; r++) {
        final Cell[] row = maze[r];
        printTop(row);
        printMiddle(row);
        if (r == maze.length - 1) {
            printBottom(row);
        }
    }
}

private static void printBottom(final Cell[] row) {
    for (final Cell cell : row) {
        System.out.print(cell.walls.contains(Dir.SOUTH) ? "+--" : "+  ");
    }
    System.out.println("+");
}

private static void printMiddle(final Cell[] row) {
    for (int c = 0; c < row.length; c++) {
        final Cell cell = row[c];
        System.out.print(cell.walls.contains(Dir.WEST) ? "|  " : "   ");
        if (c == row.length - 1) {
            System.out.println(cell.walls.contains(Dir.EAST) ? "|" : " ");
        }
    }
}

private static void printTop(final Cell[] row) {
    for (final Cell cell : row) {
        System.out.print(cell.walls.contains(Dir.NORTH) ? "+--" : "+  ");
    }
    System.out.println("+");
}

(注:从审美角度来看,我更喜欢Direction和randomDirection。但这只是我的个人偏好;-)

4
你需要做类似于“除非该单元格位于迷宫边缘,否则不要打印NORTH或WEST的墙壁”的操作。这样,如果该单元格的WEST应该有一堵墙,那么西侧的单元格将已经将其作为自己的EAST墙壁打印出来了。
如果入口在北侧或西侧墙上,你可能需要特别处理。

如果您使用此方法,应仅为每个单元格存储两堵墙(北墙和西墙);南墙和东墙只是相邻空间北墙和西墙的冗余副本,无论如何都将被忽略。迷宫的边界会自动围起来。 - RMorrisey

1
因为单元格共享墙壁,您可以忽略一半的值。如果您从最远的西北单元格开始,并仅测试南侧和东侧的墙壁,则可以绘制单面墙迷宫。当然,迷宫的北侧和西侧墙壁必须完全封闭。
免责声明:我没有真正考虑过这个问题,所以它可能根本行不通,但在我看来听起来很合理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接