Print out an ASCII line of boxes

3k Views Asked by At

I need to write a program to output an ASCII art pattern. The size of the pattern should change dynamically based on class constants.

It should look like this:

Number of boxes: 4
Width of boxes: 6
Height of boxes: 3
+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+

public class testing {
    public static void main(String[] args) {
        for (int height = 1; height <= 2; height++) {
            System.out.println("");
            for (int box = 1; box <= 4; box++) {
                System.out.print("+");
                // System.out.print("|");

                for (int width = 1; width <= 6; width++) {
                    System.out.print("_");
                }
            }
        }
    }
}
3

There are 3 best solutions below

0
On BEST ANSWER

You are going to need to check if your loop is on the "edge" of a box and add different characters accordingly.

public static void main(String args[]) {
    int height = 3;
    int width = 6;
    int numberOfBoxes = 4;
    String output = "";
    // height + 2 for the extra row of characters on the top and bottom
    for (int h = 0; h < height + 2; h++) {
        for (int box = 0; box < numberOfBoxes; box++) {
            // If on the outer edge, when h = 0 or h = height + 1
            if (h % (height + 1) == 0) {
                output += "+";
                for (int w = 1; w <= width; w++) {
                    output += "-";
                }
                // Otherwise only draw the vertical lines.
            } else {
                output += "|";
                for (int w = 1; w <= width; w++) {
                    output += " ";
                }
            }
        }
        // Add the last line of characters
        if (h % (height + 1) == 0) {
            output += "+";
        } else {
            output += "|";
        }
        // Add new line character
        output += "\n";
    }
    System.out.println(output);
}

However, above I added a lot of smaller string to the end of an output. Instead it would make more sense to use StringBuilder(). Adding Strings together is pretty inefficient and creates a lot of objects to only be used once and tossed. Instead (using StringBuilder()):

public static void main(String args[]) {
    int height = 3;
    int width = 6;
    int numberOfBoxes = 4;
    StringBuilder output = new StringBuilder();
    // height + 2 for the extra row of characters on the top and bottom
    for (int h = 0; h < height + 2; h++) {
        for (int box = 0; box < numberOfBoxes; box++) {
            // If on the outer edge, when h = 0 or h = height + 1
            if (h % (height + 1) == 0) {
                output.append("+");
                for (int w = 1; w <= width; w++) {
                    output.append("-");
                }
                // Otherwise only draw the vertical lines.
            } else {
                output.append("|");
                for (int w = 1; w <= width; w++) {
                    output.append(" ");
                }
            }
        }
        // Add the last line of characters
        if (h % (height + 1) == 0) {
            output.append("+");
        } else {
            output.append("|");
        }
        // Add new line character
        output.append("\n");
    }
    System.out.println(output.toString());
}
0
On

Here's a working code in case it helps you :) Tried to separate it into functions to make it a bit more clear. Note that the code given to you above is WAY more efficient than this one, but this one might be a little easier to understand.

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
    static int numBoxes = 4; //Change this to your liking.
    static int height = 3; //Just how many | will it have.
    static int width = 6; //

    public static void main(String[] args) throws java.lang.Exception {
        topBot();
        printHeight();
        topBot();
    }

    public static void topBot() {
        for (int i = 0; i <= numBoxes * width; i++) {
            if (i % width == 0)
                //When this happens we're in a new box.
                System.out.print("+");
            else
                System.out.print("-");
        }
        System.out.println(); //Move to next line.
    }

    public static void printHeight() {
        for (int j = 0; j < height; j++) {
            for (int i = 0; i <= numBoxes * width; i++) {
                if (i % width == 0)
                    //Whenever this happens we're in a new box.
                    System.out.print("|");
                else
                    System.out.print(" ");
            }
            System.out.println(); //Move to next line.
        }
    }
}

Output:

+-----+-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
|     |     |     |     |
+-----+-----+-----+-----+
0
On

You can represent each box as an almost square String[] array:

+------
|      
|      
|      
+------

Then you can concatenate these arrays line-by-line, and add a right border:

+------+------+------+------+------+
|      |      |      |      |      |
|      |      |      |      |      |
|      |      |      |      |      |
+------+------+------+------+------+

This code works in Java 11:

Try it online!

// number of boxes
int n = 5;
// width of boxes
int width = 6;
// height of boxes
int height = 3;
System.out.println("Number of boxes: " + n);
System.out.println("Width of boxes: " + width);
System.out.println("Height of boxes: " + height);
String[] boxes = IntStream.range(0, n)
        // Stream<String>
        .mapToObj(i -> Stream.of(
                // upper border row
                Stream.of("+" + "-".repeat(width)
                        // add a right border to the last box
                        + (i < n - 1 ? "" : "+")),
                // inner part with a left border
                IntStream.range(0, height)
                        .mapToObj(row -> "|" + " ".repeat(width)
                                // add a right border to the last box
                                + (i < n - 1 ? "" : "|")),
                // lower border row
                Stream.of("+" + "-".repeat(width)
                        // add a right border to the last box
                        + (i < n - 1 ? "" : "+")))
                .flatMap(Function.identity())
                .toArray(String[]::new))
        // reduce Stream<String[]> to a single array String[]
        .reduce((box1, box2) -> IntStream.range(0, height + 2)
                .mapToObj(i -> box1[i] + box2[i])
                .toArray(String[]::new))
        .orElse(new String[0]);
// output
Arrays.stream(boxes).forEach(System.out::println);

Output:

Number of boxes: 5
Width of boxes: 6
Height of boxes: 3
+------+------+------+------+------+
|      |      |      |      |      |
|      |      |      |      |      |
|      |      |      |      |      |
+------+------+------+------+------+

See also: How to draw a staircase with Java?