/**
 * Printing boxes of asterisks.
 * Demonstrates multiple ways to do this using for loops.
 *
 * @author Zach Tomaszewski
 * @version 10 Oct 2008
 */
public class PrintingBoxes {

  public static void main(String[] args) {

    //get user input
    java.util.Scanner keybd = new java.util.Scanner(System.in);
    System.out.print("Enter a size: ");
    int num = keybd.nextInt();
    //XXX: Demo code, so not bothering with catching exceptions

    /*
     * Print a row of num asterisks (*s).
     */
    System.out.println();
    System.out.println("A row of num asterisks:");

    for (int i = 1; i <= num; i++) {
      System.out.print("*");
    }
    System.out.println(); //end row


    /*
     * Print a square box of asterisks: num x num.
     */

    //We already know how to print a row of num *s from above.
    //We used a for loop to print one "*" num times.
    //Now we want to repeat all of that code--printing one row--num times.
    //This suggests just putting it all in another for loop:
    System.out.println();
    System.out.println("A box of asterisks: ");

    for (int row = 1; row <= num; row++) {
      for (int col = 1; col <= num; col++) {
        System.out.print("*");
      }
      System.out.println(); //end row
    }

    //
    // Above, I renamed my loop variables to make it clearer what I'm printing:
    //
    // col = 1234   (num == 4)
    //     1 ****
    //     2 ****
    //     3 ****
    //     4 ****
    //     ^
    //    row
    //
    // The inner loop prints each * (or column) on a row (the horizontal numbers).
    // The outer loop repeats the printing each line (or row) (the vertial numbers).
    // So, if we think of the box as a coordinate plane, we always know the
    // position of the current character we're printing, as given by (col, row).
    //

    //This is another way to do it with only one for loop rather than two.
    //Basically, we know we need num * num stars to make a box; we just need
    //to figure out where to put the line-breaks to get a box:

    System.out.println();
    System.out.println("A box of asterisks (again): ");
    for (int i = 1; i <= num * num; i++) {
      System.out.print("*");
      if (i % num == 0) {
        System.out.println();
      }
    }


    /*
     * Print a right triangle with num height and num base, with the
     * hypotenuse going from upper-left to lower-right.
     */

    //To do this, we can just stop printing each row a little earlier than if
    //we were printing a box.  Here's a triangle of size 6:
    //
    //          *s printed  row
    // *         1           1
    // **        2           2
    // ***       3           3
    // ****      4           4
    // *****     5           5
    // ******    6           6
    //
    // We can see that we're printing one more * on each row.  Furthermore,
    // the number of *s printed on each line is the exact same as the row number.
    // Therefore, we just need to print as long as col is <= to the length
    // of the row we're currently on:  col <= row.  Thus:

    System.out.println();
    System.out.println("A triangle aligned to the left: ");

    for (int row = 1; row <= num; row++) {
      for (int col = 1; col <= row; col++) {
        System.out.print("*");
      }
      System.out.println();
    }


    /*
     * Print a right triangle with num height and num base, with the
     * hypotenuse going from lower-left to upper-right.
     */

    // Again, lets look at the problem.  This time, we can't just stop
    // printing a row early, as we need to indent the *s we printed.
    // So, that means we'll end up printing a character in every position
    // in the box.  It's just that some characters will be spaces and others
    // will be *s.  So, our printing loops will be the same as for
    // printing a box; we just need to change which character is printed
    // at each position.
    //
    // But what is the relationship that determines whether the currently-
    // printed character should be a space or *?
    //
    //         spaces  *s  row  num
    //        *  5     1    1   6
    //       **  4     2    2   6
    //      ***  3     3    3   6
    //     ****  2     4    4   6
    //    *****  1     5    5   6
    //   ******  0     6    6   6
    //
    // For a triangle of size 6 (num == 6), we can see see that the number of
    // spaces and *s add up to num on each row.  So, if we're currently printing
    // a character that's in a col that's <= (num - row), then it should be a space;
    // otherwise is should be a *.

    System.out.println();
    System.out.println("A triangle aligned to the right: ");

    for (int row = 1; row <= num; row++) {
      for (int col = 1; col <= num; col++) {
        if (col <= num - row) {
          System.out.print(" ");
        }else {
          System.out.print("*");
        }
      }
      System.out.println();
    }


    // Here's another way to do this same problem.  The relationship
    // between whether we print a space or a * is the same.
    // But, for each row, we might want to print all the spaces we need,
    // and then print all the *s:
    System.out.println();
    System.out.println("A triangle aligned to the right (again): ");

    for (int row = 1; row <= num; row++) {
      //first print this row's spaces
      for (int space = 1; space <= num - row; space++) {
        System.out.print(" ");
      }
      //now print this row's *s
      for (int asterisk = 1; asterisk <= row; asterisk++) {
        System.out.print("*");
      }
      System.out.println();
    }


  }
}
