CS 124, Fall 2017
Labs 13: Hangman Continued

For the final two labs of the semester, you will continue working on the Hangman game that was begun in Lab 12 (or on your alternative project, if that's what you decided to do). This week, you will implement the actual game logic. Before the final lab next week, you should have a completed, working game. The program is due by 3:00 PM on the last day of class, Friday, December 8, the day after the next lab.

Word List

You should already have the GUI for your program pretty much ready to go. The next part of the project is to implement the game logic. That is, you should make it possible for the user to play the game.

First of all, you will need a list of possible words for the game. Your program should read the list of words from a file named "wordlist.txt". The file /classes/cs124/wordlist.txt is a list of 438 words. They were chosen more or less at random from a much longer list (/classes/cs124/wordlist-full.txt, which has 68,676 words). The words are all between 4 and 12 characters long. You can use my list of words, or your own list.

The list of words should be part of the program. A file that is actually part of a program is called a resource file. To include the word list as a resource file, just add the file wordlist.txt to the src folder of your project. However, you will still need a way to read the data from the file. There is a not-very-pretty API for reading resources. (See Section 13.1.3 if you are interested.) Here is a method that you can use in your program to read the file:

/**
 * Reads a list of words from a file.
 * @param filename the name of the resource file
 * @return an ArrayList containing the list of words read.
 */
private ArrayList readWordList(String filename) {
    try {
        ArrayList words;
        Scanner in;
        in = new Scanner(getClass().getClassLoader()
                            .getResource(filename).openStream());
        words = new ArrayList();
        while (in.hasNext()) {
            words.add(in.next());
        }
        in.close();
        return words;
    }
    catch (Exception e) {
        throw new IllegalArgumentException("Can't read " + filename);
    }
}

Call readWordList("wordlist.txt") to read the file and get the list of words for the program in an ArrayList. When starting a game, select a random word from the list. Note that the words from my list are lower-case. You might want to convert to upper-case. I suggest making an array of type char[] of the same length as the word and copying all the characters from the word into the array. (Actually, a String already has an instance method for making such an array; use it if you can find it.) You will also need an array of the same length to hold the letters guessed so far, with some character, such as an underscore, to hold the places of letters that have not yet been guessed. The list of words and the two arrays will all have to be global variables.

Game Logic

Since this is a GUI program, the game is driven by events. In this case, the events are ActionEvents generated when the user clicks a button or selects a command from a menu. You need to code responses to those events.

You probably want to start the first game automatically when the program start up. (An alternative is to display a welcome message and make the user click "New Game" to start the first game.) When a game is begun, the "New Game" command should be disabled. When the game ends, the "New Game" command should be re-enabled so the user can start the next game.

Once the game starts, it is driven by the user clicking on the letter buttons. When the user clicks a letter button, you should disable that button (hint: If evt is an ActionEvent generated by a button click, then evt.getSource() is the button that was clicked, except that you have to type-cast it to type JButton: clickedButton = (JButton)evt.getSource();). Check whether the letter is in the word, and update the state of the game appropriately. Make sure to update the variables that need to change when the user picks a letter, and don't forget to call display.repaint() to update the drawing in the display panel. If the game has ended, don't forget to re-enable all the letter buttons, as well as the "New Game" command.