How to invert the output in Nim Game?

Viewed 115

So I have the NIM Game Program. Basically, there are four piles and the two players have to keep taking stones from the piles until one of them lose. Right now my piles look like this in the output.

Board: [1, 2, 3, 4]

XXX|XXX represents one stone and one column of them represent a pile but I need to modify it so it will look like this

                        XXX|XXX
                XXX|XXX XXX|XXX
        XXX|XXX XXX|XXX XXX|XXX
XXX|XXX XXX|XXX XXX|XXX XXX|XXX

This is my code

System.out.print("");
for(int i = 0; i < 4; i++) {
    //System.out.println(i);
    for(int j = 0; j < numbers[i];j++) {
        //System.out.println(j);
        System.out.print(" XXX|XXX ");
    }
    System.out.println(" ");
}

it prints this

XXX|XXX

XXX|XXX XXX|XXX

XXX|XXX XXX|XXX XXX|XXX

XXX|XXX XXX|XXX XXX|XXX XXX|XXX

suggestons?

2 Answers

First, imagine your output as a virtual 2D String array, as hinted by @gmdev in his answer:

String[][] output = {
    {"       ", "       ", "       ", "XXX|XXX"},
    {"       ", "       ", "XXX|XXX", "XXX|XXX"},
    {"       ", "XXX|XXX", "XXX|XXX", "XXX|XXX"},
    {"XXX|XXX", "XXX|XXX", "XXX|XXX", "XXX|XXX"}
};

Next, you need to somehow find out how tall your highest pile is. Here's one way to do so in Java 8 or later:

int tallestPileLevel = Arrays.stream(numbers).max().getAsInt();

Then you render your virtual 2D array one line at a time.

The outer loop descends down your pile levels and the inner loop prints:

  • air (" ") --> if the i-th pile doesn't reach the current level
  • stone ("XXX|XXX") --> otherwise

Here's a working example:

import java.util.*;
public class PrintNim {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4};
        int tallestPileLevel = Arrays.stream(numbers).max().getAsInt();
        
        String stone = " XXX|XXX ";
        String air   = "         ";
        
        for (int level = tallestPileLevel; level > 0; level--) {
            for(int i = 0; i < numbers.length; i++) {
                if (numbers[i] < level) {
                    System.out.print(air);
                }
                else {
                    System.out.print(stone);
                }
            }
            System.out.println();
        }
    }
}

Use another for loop to set however many spaces you need to stack the stones. I made a string that is the same length as 1 stone. The for loop repeats this string 3 times, then twice, etc.

I added code comments to try to help with the explanation.

public static void main(String[] args) {
    System.out.print("");
    int[] numbers = {1, 2, 3, 4};
    int[] spaceNum = {3, 2, 1, 0}; //to stack the x's you need 3 spaces, then 2, etc.
    String spaces = "         "; //length of 1 stone, i.e " XXX|XXX "
    
    for(int i = 0; i < 4; i++) {
        //this loop uses sapceNum to decide how far to indent before the next loop writes the stones
        for(int k = spaceNum[i]; k > 0; k--) {
            System.out.print(spaces);
        }
        for(int j = 0; j < numbers[i]; j++) {
            System.out.print(" XXX|XXX ");
        }
        System.out.println(" ");
    }
}

output:

                            XXX|XXX  
                   XXX|XXX  XXX|XXX  
          XXX|XXX  XXX|XXX  XXX|XXX  
 XXX|XXX  XXX|XXX  XXX|XXX  XXX|XXX  
Related