Introduction: Programming an Animated Hourglass Display in Java

About: Student with way too many hobbies! I enjoy painting, baking, CAD modeling, drawing, programming, sewing, and much more <3

Introductory Java programming project that uses the basic skills I have been learning in my AP Computer Science A class recently! Skills/control structures used:

  1. Static methods
  2. For loops
  3. While loops
  4. Screen clearing command
  5. “Wait” x seconds function

If you are new to Java, learn with me as I build this project!

Supplies

  1. Any sandbox/IDE capable of running Java (I use CodeHS because I am familiar with it, but websites like https://www.online-java.com are great too!)
  2. Only one file needed, but this is a stylistic choice

Step 1: Pseudo Code

Pseudocode is used to plan out the structure of what you want a program to look like. I include basic features like what I want to happen in a sequential order, different loop types with steps underneath them, declaration of variables, and where to put them (scope!)

TIPS:

  1. Your pseudocode doesn't have to be perfect. Get the general structure down (along with any questions and notes you have for your later self)
  2. This outline can turn into your documentation comments later!

Step 2: Create Your Hourglass Shape to Print

  1. Create the hourglass shape using forward and backwards slashes (\ /) for the walls,
  2. Use asterisks (*) to represent sand, only filling the top triangle completely

NOTE:

  1. It is important that you use exactly 30 asterisks for our program, since this is a 60 second timer, they will change at a rate of 1 * per 2 seconds!

Step 3: Animate Stars

  1. Create timer
  2. Establish the number of stars
  3. While loop that:
  4. Clears the screen
  5. Prints out updated timer
  6. Prints hourglass
  7. On every even time, removes one * from the top triangle and adds it to the bottom
  8. Updates timer and totalStar variables.
  9. Wait 1 second

Notes:

Use lines:

System.out.print("\033[H\033[2J");
System.out.flush();

to clear the screen, so the print statements don't stack on top of eachother 60 times.

Use line

Thread.sleep(1000);

to wait 1 second before moving on.

Step 4: Methods Called in the Above Step

  1. String removeStar(String line) --> Remove a * from the top of the hourglass
  2. String addStar(String line) --> Adds a * to the bottom of the hourglass
  3. boolean hasSpace(String line) --> checks for space inside the houglass before moving up/down a line

Step 5: Print Final Line

Created because the if statement breaks when time is 0, and the final frame still needs to be printed.

Step 6: Full Code to Play With!

public class HourglassFull {
public static void main(String[] args) throws InterruptedException {

// Top triangle
String t1 = " \\------------/";
String t2 = " \\**********/";
String t3 = " \\********/";
String t4 = " \\******/";
String t5 = " \\****/";
String t6 = " \\**/";
String t7 = " \\ |";

// Bottom triangle (empty at first!)
String b1 = " / \\";
String b2 = " / \\";
String b3 = " / \\";
String b4 = " / \\";
String b5 = " / \\";
String b6 = " /------------\\";

int totalStars = 30; //number o stars
int timer = 60; // countdown in seconds

while (timer > 0) {

// Clear the screen
System.out.print("\033[H\033[2J");
System.out.flush();

// Show timer
System.out.println("Time left: " + timer + " seconds\n");

// Print hourglass
System.out.println(t1);
System.out.println(t2);
System.out.println(t3);
System.out.println(t4);
System.out.println(t5);
System.out.println(t6);
System.out.println(t7);
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(b5);
System.out.println(b6);

// Drop a star every 2 seconds
if (timer % 2 == 0 && totalStars > 0) {

// Remove a star from the top triangle (line by line)
if (t2.contains("*")) t2 = removeStar(t2);
else if (t3.contains("*")) t3 = removeStar(t3);
else if (t4.contains("*")) t4 = removeStar(t4);
else if (t5.contains("*")) t5 = removeStar(t5);
else if (t6.contains("*")) t6 = removeStar(t6);

// Add a star to the bottom triangle (bottom-up)
if (hasSpace(b5)) b5 = addStar(b5);
else if (hasSpace(b4)) b4 = addStar(b4);
else if (hasSpace(b3)) b3 = addStar(b3);
else if (hasSpace(b2)) b2 = addStar(b2);
else if (hasSpace(b1)) b1 = addStar(b1);

totalStars--;
}


timer--;
Thread.sleep(1000); // wait 1 second
}

// Final frame
System.out.print("\033[H\033[2J");
//System.out.flush();
System.out.println("Time left: 0 seconds\n");

System.out.println(t1);
System.out.println(t2);
System.out.println(t3);
System.out.println(t4);
System.out.println(t5);
System.out.println(t6);
System.out.println(t7);

System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(b5);
System.out.println(b6);
}


// Remove one star from the left star in a line
public static String removeStar(String line) {
return line.replaceFirst("\\*", " ");
}

// Addss one star in the first empty space from right to left
public static String addStar(String line) {
int left = line.indexOf('/');
int right = line.lastIndexOf('\\');
for (int i = right - 1; i > left; i--) {
if (line.charAt(i) == ' ') {
return line.substring(0, i) + "*" + line.substring(i + 1);
}
}
return line;
}

// Check if there is space to add a star
public static boolean hasSpace(String line) {
int left = line.indexOf('/');
int right = line.lastIndexOf('\\');
for (int i = left + 1; i < right; i++) {
if (line.charAt(i) == ' ') return true;
}
return false;
}
}