打印棋盘格或方形图案

Printing a checkerboard or square pattern

我正在学习 Java,目前我正在尝试使用该程序制作一些 ASCII 艺术作品。我能够制作空心钻石,但我正在努力制作“棋盘”或方形图案。我正在尝试创建如下所示的内容:

***    ***    ***
***    ***    ***

出于某种原因,它一直这样出现:

***
***
   ***
***

我知道问题出在我的 for 循环上。由于我刚刚了解了嵌套循环,所以我仍在努力理解其中的逻辑。我的中间循环控制空格,无论我为 s(我的递增变量)设置什么值,它仍然使模式变得奇怪。

这是我的代码:

public class ASCII_Art {
    public static void squares() {
        System.out.println("***\n***   ");
    }

    public static void main(String[] args) {
        for (int i = 0; i <= 5; i++) {
            for (int y = 0; y < i - 4; y++) {
                squares();
                System.out.print("   ");
                squares();
            }
        }
    }
}

我做了一个方形方法,因为我读到方法使一切变得更清晰、更容易,因为你不必多次重写相同的代码。

这里有几个问题。

  1. 正如其他人指出的那样,\n 创建了一个新行,
    像这样。另一方面,\t 会创建一个缩进, 就像这样。对于您的目的,\t 就是您想要的。

  2. 在您的 squares 函数中,您只打印两个 ***。相反,打印 3.

  3. 因为 squares 已经打印了一行,你只需要一个 for 循环直到 2。传统的方法是 int i = 0; i < 2.

下面是完整的更正代码(我修正了缩进,重新加上括号,并添加了一个 main 方法):

public class ASCII_Art
{   
    public static void squares(){
        System.out.println("***\t***\t***");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            squares();
        }
    }
}

或者,由于您的 squares 方法实际上并没有提供太多价值,您可以改为这样做:

public class ASCII_Art
{   
    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            System.out.println("***\t***\t***");
        }
    }
}

如果你想进一步定制你的 ASCII 艺术,你可以制作一个函数接受 3 个参数:一个代表 *s 的数量,一个代表一行中星号块的数量,一个代表行中的星号块数量线。我会让你自己弄清楚...

所以这里的问题基本上是您的 square 方法打印出三个星号,然后换行。然后你就不能回到上一行,这就是为什么第一个方块看起来不错,但其他方块看起来不合适的原因。如果您查看输出,则会打印第一个方块。然后打印空白和另一个正方形。但是第二个方块并不是从第一行开始的。它从第二个开始,所以最终发生的是打印前三个星号,然后 \n 告诉它换行,然后打印其他三个星号,这就是它们看起来分开的原因。就像其他人建议的那样,使用 \t,而不是 \n。

您可以将 棋盘格 可视化为 Boolean[][] 矩阵 8x8,其中每个元素为:

m[i][j] = (i - j) % 2 != 0;

然后您可以将每个 Boolean 表示为填充或空心的 正方形 ,然后将这些正方形并排连接成一条 线,然后逐行输出。

    ****    ****    ****    ****
    ****    ****    ****    ****
****    ****    ****    ****    
****    ****    ****    ****    
    ****    ****    ****    ****
    ****    ****    ****    ****
****    ****    ****    ****    
****    ****    ****    ****    
    ****    ****    ****    ****
    ****    ****    ****    ****
****    ****    ****    ****    
****    ****    ****    ****    
    ****    ****    ****    ****
    ****    ****    ****    ****
****    ****    ****    ****    
****    ****    ****    ****    

Try it online!

三种方法:创建正方形个空格和星号,创建个正方形,输出一个字段行。

public static void main(String[] args) {
    // field size
    int n = 8;
    // square size
    int s = 2;
    // output a checkerboard
    IntStream.range(0, n)
            // i - height, j - width
            // prepare a row of booleans
            // Stream<Boolean[]>
            .mapToObj(i -> IntStream.range(0, n)
                    // filled or hollow - true or false
                    .mapToObj(j -> (i - j) % 2 != 0)
                    .toArray(Boolean[]::new))
            // prepare a line of squares for each row
            // Stream<String[]>
            .map(row -> line(row, s))
            // Stream<String>
            .flatMap(Arrays::stream)
            // output line by line
            .forEach(System.out::println);
}
public static String[] line(Boolean[] arr, int size) {
    return Arrays.stream(arr)
            // prepare a square for each element
            // Stream<String[]>
            .map(bool -> square(size, bool))
            // sequentially join squares side-by-side
            .reduce((arr1, arr2) -> IntStream.range(0, size)
                    .mapToObj(i -> arr1[i] + arr2[i])
                    .toArray(String[]::new))
            .orElse(null);
}
public static String[] square(int size, boolean filled) {
    return IntStream.range(0, size)
            // i - height, j - width
            .mapToObj(i -> IntStream.range(0, size * 2)
                    .mapToObj(j -> filled ? "*" : " ")
                    .collect(Collectors.joining()))
            .toArray(String[]::new);
}

另请参阅: