CS 124, Spring 2017
Lab 4: More Control

You will be using more control structures in this lab—for loops as well as if statements and while loops. You will write two programs. The first exercise should be fairly short. It requires you to use for loops. The second exercise is more complicated, and the main point is to come up with an algorithm to solve a fairly complex problem.

You will need a copy of the program ThirdGraphics.java for the first exercise and a copy of TextIO.java for the second. As usual, you can find copies in the directory /classes/cs124.

This lab is due at the start of next week's lab. You will submit two files, named ThirdGraphics.java and NotHangman.java. Turn them in using the Submit124 web page, as usual.

Part 1: Getting Started With for

In the previous lab, you used a while loop to make a random picture. In this lab, you will use for loop to make two more kinds of "random art."

Start with a copy of ThirdGraphics.java. This is actually the same as SecondGraphics.java, from Lab 2, except that the drawing code has been removed. That is, it has a paintComponent method that is called every five seconds, and you need to complete the program by filling in the paintComponent subroutine.

The paintComponent method should start by picking a random number. If the number is less than 0.5, the program should draw the first kind of random art; if not, it should draw the second kind.

For the first kind of art, you should simply draw a large number (say, 500) of random lines. You should choose a random color for each line. Use a for loop. Here is an example, scaled down to half size:

To draw a random line, you should generate two random points (x1,y1) and (x2,y2), and then call g.drawLine(x1,y1,x2,y2). Since the drawing area is 800 pixels wide and 600 pixels high, x1 and x2 should be random integers in the range 0 to 800, and y1 and y2 should be random integers in the range 0 to 600. Note that the x-values for the upper left corners of the squares are 0, 100, 200, 300, 400, 500, 600, and 700, while the y-values are 0, 100, 200, 300, 400, 500, and 600. Your for loops need to generate these values somehow.

For the second kind of art, you will need a pair of nested for loops. You should draw a grid of randomly colored squares. Each square should be 100-by-100 pixels, so there are 8 square across and 6 down in the grid. Furthermore, inside each square, you should some smaller figure such as a smaller square, a circle, or maybe a randomly selected letter. Here is an example using a randomly colored circle inside each square:

For my own program, I used random HSB colors instead of random RGB colors. An HSB color has three color components, representing "hue," "saturation," and "brightness." The hue is the basic color. The saturation tells how pure it is (for example, red is fully saturated, while pick has the same basic hue but is unsaturated). And the brightness is what it sounds like. The three components are specified as values of type float (not double) in the range 0.0 to 1.0. You don't really need to understand this. Here is how to use a bright, fully saturated random color:

g.setColor( Color.getHSBColor((float)Math.random(),1,1) );

and here is how to use a darker, but still saturated, random color:

g.setColor( Color.getHSBColor((float)Math.random(),1,0.5F) );

In my artwork, I used a dark color for the squares and a bright color for the circles. I also drew a black outline around each square, since I thought it looked better with the outlines.

(You can improve the look of your art by adding the following three mysterious lines to the beginning of your paintComponent method:

Graphics2D g2 = (Graphics2D)g;
g2.setStroke( new BasicStroke(2) );
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

You should not try to understand these lines, but the first one is a type-cast that gives access to some of Java's more advanced graphics capabilities. The second one makes the lines that you draw 2 pixels wide instead of one pixel, and the third one makes for smoother looking lines, ovals, and text.)

Part 2: Towards Hangman

In this exercise, you will write some programming that is needed in the well-known game, Hangman. For this exercise, you will work on just a part of the game. Later, we might extend this work to an implementation of the complete game.

The name of the program must be NotHangman. This is a more complicated program than the ones you have worked on previously, and you will have to spend some time developing an algorithm for it. Remember that you do not have to write the entire program all at once! Get something working, and then add features to it.

In Hangman, a player tries to guess a word by guessing letters that might be in the word. The player initially sees a blank space for each letter of the word. As the player guesses letters, the blank spaces are filled in, until the user has guessed all the letters that occur in the word. (In the real game, the user loses if they guess too many letters that don't occur in the word, but that is not part of this assignment.)

Your program should use some particular word, of your choice, as the word that the user has to guess. Let's say, for example, that the word is "hippopotamus". As you go through the program, you want to keep outputting the user the word, showing any letters that have been guessed by the user, but showing a blank space for any letter that the user has not yet guessed. Use an underscore character, '_', to represent a blank, unguessed letter. At the beginning, all the spaces are blank. As the user guesses letters, some of the blanks are changed to letters. Here is approximately what the process should look like:

            The word so far:  _ _ _ _ _ _ _ _ _ _ _ _  

            Choose a letter: t
            Yes, there is a t in the word.
        
            The word so far:  _ _ _ _ _ _ _ t _ _ _ _ 

            Choose a letter: e
            No, there is no e in the word.
        
            The word so far:  _ _ _ _ _ _ _ t _ _ _ _ 

            Choose a letter: i
            Yes, there is a i in the word.
        
            The word so far:  _ i _ _ _ _ _ t _ _ _ _ 

            Choose a letter: o
            Yes, there is a o in the word.
        
            The word so far:  _ i _ _ o _ o t _ _ _ _ 

            Choose a letter: n
            No, there is no n in the word.
        
            The word so far:  _ i _ _ o _ o t _ _ _ _ 

            Choose a letter: s
            Yes, there is a s in the word.
        
            The word so far:  _ i _ _ o _ o t _ _ _ s 
              . 
              .
              .
          
            The word so far:  h i _ _ o _ o t a m u s

            Choose a letter: p
            Yes there is a p in the word.
        
            The word so far:  h i p p o p o t a m u s

            You've done it!

To implement this, you need to be able to check whether a string contains a given letter. Fortunately, we have see a String function that makes it easy: Suppose word is a String and letter is a char. Then the function

            word.indexOf(letter)

checks whether letter occurs in word. This function returns an int. The value is -1 if letter does not occur in word. If letter does occur in word, then the value is greater than or equal to zero. (In fact, the value gives the position of the first occurrence of letter in word.) So, you can test whether a letter occurs in a word simply by saying

            if ( word.indexOf(letter) >= 0 ) { 

Your program will need a String to hold the word that the user is trying to guess. You will also need a String to hold the letters that the user has guessed so far. This second string starts out as the empty string, "". When the user inputs a character, add that character onto the string using a command such as

            guessedLetters = guessedLetters + userLetter;

The hardest part of the program is to output the word showing some letters and some blanks. Think carefully about how you are going to do that and how you are going to use the two strings to do it.

The program should continue until all the letters in the word have been guessed. Once the word is complete, you should end the program. (This part is also a bit difficult, and we might discuss it in class once you've had a chance to work on the program for a while.)