APS101: Assignment 3

Hangman Game

Purpose

This assignment will give you practice with arrays, graphical user interfaces (GUIs), main methods, reading from files and consoles, as well as the concepts from the first and second assignment. You will also develop a test suite.

Read this handout carefully so that you understand exactly what we are asking for. Do this before you start programming! Take notes as you read. What classes do we want? What are the method names?

If you notice parts that are unclear, please ask the Instructor or post a message on the discussion board. Any major changes/clarifications will be posted on the A3 FAQ page.

Introduction: Playing the game

If you are not already familiar with how to play Hangman, please see the following Wikipedia entry. The major differences between this description and the game you will design are as follows:

In this assignment, we ask you to make your own graphical Hangman game that you can play with on your own. See the following set of slides for a demonstration of what your game should look like and how it should be played.

Requirements

There are certain basic requirements that we will expect in your final design: sufficient testing, documentation of your code, and a good design approach to the assignment.

Testing

The product of this assignment is visual, but this doesn't mean that the testing portion of the assignment can be left out. On the contrary, most of the underlying logic of this assignment can be thoroughly tested with JUnit.

When testing, you do not have to worry about testing for malicious input (e.g. non-alphabetic characters, arrays whose dimensions don't match), but your code should be as versatile as possible. Also, make sure to cover both typical and boundary conditions in your tests, just like in the previous Assignment.

In order for your game to be as user-friendly as possible, you will need to consider various error conditions (see below), but they are specified explicitly.

Documentation

For this assignment, we expect you again to follow the style rules laid out in A2 Rules, plus JavaDoc comments.

We expect proper JavaDoc comments for:

A brief reminder: JavaDoc comments must begin with /** and end with */, and the following tags can be used to denote special roles within your comments:

We also expect non-JavaDoc comments throughout your code, especially in sections where the purpose of your code is not immediately clear.

General Design

The Hangman game is composed of three major parts:

  1. The "engine" for the game
  2. The driver for the game
  3. The window-based interface

For this assignment, we provide you with "starter code" that implements some of the HangmanGUI, HangmanListener, and PlayHangman classes. You must complete the parts missing from the provided classes, as well as write any new classes that are necessary. Assume that the code we have given you should be in the final product; this means that none of the method signatures that we have already specified should be changed in your final design.

When approaching this design, certain components are more important than others. Rather than programming the entire assignment at once, implement this assignment in stages, and make sure the current stage is working properly before moving on to the next.

The required parts are specified in the following sections.

Part 1:

The "Engine" Class

The Hangman class represents the basic functionality of the game. You will not be provided with starter code for this part of the assignment. That means you have to write this class from scratch, following good design principles: think about the variables and methods that are required to support the process of playing the Hangman game, as it was illustrated in the PDF slides (see above).

You must NOT have unnecessary or redundant components that do not contribute to the game's functionality!

Take a look at TicTacToe.java, which we wrote in class, for ideas about how to write your own "engine" class.

You MUST use arrays to represent information for this assignment! For example, to represent the word that the player needs to guess. Although you might be able to use String manipulation for this purpose, that would likely be more difficult and would defeat the purpose of this assignment. In other words, you must not use StringTokenizer anywhere, and you should minimize the usage of String's substring and indexOf methods.

The following are some suggestions for the operations that your class should perform:


Here are some IMPORTANT rules and restrictions for your class:


As always, you should make your code more efficient by using private helper methods (we will be looking for this during the marking!).

You should also build a tester for this class (HangmanTester.java), to make sure that it behaves the way you planned.

Part 2:

The Driver Class

This PlayHangman class is the driver for this game. This class contains a main method, so it can be invoked from the command prompt. The game can be played in three ways:

  1. java PlayHangman <pathToDictionary> <maxGuesses>
    where :

    <pathToDictionary> is the path and name of the file that contains the dictionary of words.
    <maxGuesses> is the maximum number of incorrect guesses a player is allowed to make.


  2. java PlayHangman <pathToDictionary>
    where :

    <pathToDictionary> is the path and name of the file that contains the dictionary of words. The value of the maximum mistakes allowed should be set to a default of 6.


  3. java PlayHangman
    In this case, the user should get to choose the dictionary file and enter the value of the maximum mistakes allowed (you decide what the best way to do this is!).


This class should allow the user to play the Hangman game using the other game components (Hangman, HangmanGUI, and HangmanListener).

Part 3:

The GUI Interface

The Graphical User Interface (GUI) is the window-based interface that will display the game to the user in a JFrame and allow the user to play the game by clicking on JButtons to select letters or to get a hint.

The HangmanGUI class

The HangmanGUI class inherits from the JFrame class and is for display purposes only. The window contains:

  1. A series of buttons for each letter of the English alphabet, so the player can make guesses.
  2. A hint button that reveals one letter of the hidden word at a time.
  3. A label that displays all the letters that the player guessed incorrectly ("Misses").
  4. A label that displays how many more incorrect guesses the player is allowed to make before they lose ("Guesses left").
  5. A series of labels that displays the hidden word, and the player's progress in guessing that word.

Its main functions are to initialize and display all the appropriate values when the game is started, and to update the values (ex. the hidden word) when a letter is selected or when the user presses the hint button. Even then, it relies on the HangmanListener class to determine when to update and what values to use.

The design of the HangmanGUI and its relation to the other classes is intentionally unspecified here, because this design component is left for you to decide. See the HangmanGUI starter code.

To understand fully what this class does, make sure you read the last paragraph of the next class, describing how you will attach a "listener" to the HangmanGUI.

The HangmanListener class

This class extends the MouseAdapter class, and its basic function is to listen for mouse events. When attached to a button or window, it knows when the mouse has interacted with that component in any way, and will execute the appropriate method. Five methods are available for such purposes, in the cases where the mouse enters the component, exits the component, is pressed, is released, or is clicked.

For this assignment, you only need to concern yourself with the click action. Most of the HangmanListener class is provided for you, and contains a method that can be used to attach the HangmanListener to the HangmanGUI, as well as the signature and the starting line for the mouseClicked method. This method is invoked every time somebody clicks the mouse on a component that the HangmanListener is "attached" to. You are required to fill in the remaining functionality for the mouseClicked method, making it respond to the click event by manipulating the HangmanGUI objects appropriately.

How do you attach a HangmanListener object to the graphic component whose clicks it is listening for? Easy: check out the code that you used in Week 10's Lab. There, a MouseAdapter class was attached to a JButton object by calling that object's addMouseListener() method. All graphic components (JFrames, JButtons) have such methods. To identify which listener it is attaching, your HangmanGUI class will have to take in a HangmanListener instance as a parameter in its constructor. To make sure you get this part right: read and understand the Week 10 Lab code; if necessary, build a few small JFrame/JButton classes and experiment with adding your Listener through the addMouseListener method until you're comfortable with it.

General GUI Operations

The combination of the Hangman, HangmanGUI and HangmanListener components produces the overall behavior of the game. When the game is first invoked from the command line, the following connections are formed:

  1. An instance of the Hangman object is created.
  2. An instance of the HangmanListener object is created.
  3. An instance of the HangmanGUI is created, using the reference to the HangmanListener object and the Hangman object.

Once the constructors are done, the connections between the objects produce the following behavior when a player clicks on a letter or the hint button in the HangmanGUI:

  1. The HangmanListener is invoked whenever a button is clicked in the HangmanGUI window.
  2. The HangmanListener tells the HangmanGUI object what selection was made.
  3. The HangmanGUI decides what to do with the selection and tells the Hangman object what to do.
  4. The Hangman object tells the HangmanGUI how to update itself.

If the player wins the game, a congratulatory message should pop up. If the player loses, the hidden word should be revealed AND a message should pop up to inform the player of their loss.

The user should also have the option of playing again, once the current game has ended (either in a win or a loss). If the user decides to play again, then a new game must be started - with a new word to guess (chosen randomly again from the dictionary) and the same value for the maximum mistakes allowed variable.

Other Information

The Dictionary File

The dictionary file contains a list of possible words for the player to guess. It has the following properties:

Error Conditions

Even though we assume a non-malicious player for this game, there are certain error conditions that you must anticipate:

Enhancements

WARNING: This section should only be considered if you have completed ALL of the other parts of this assignment, including testing and JavaDoc comments.

If you have completed the rest of the assignment, kudos will go out to students who add enhancements to their game, either in the form of extra features or more elaborate functionality. This is your chance to be creative, have fun and impress us with you imagination.

What to Hand In

The course website describes how you hand in your assignment. This section tells you what to hand in:

Remember that spelling, including case, count in Java: your files must be named exactly as above.

NOTE: Other than the signoff statement, only hand in the files that end with the .java suffix. Be careful about this, because in the same place as your .java files you may also have files with the extension .class (that is, they end with the .class suffix), but otherwise have the same name. Two particular pitfalls:

Since .class files cannot be read by TAs or run with our testing programs, submitting the wrong files might cause you to fail the assignment.

General Hints and Tips