CSCI 161 Homework Assignment 5 - Hangman

Due Wed Oct 10 at 11:59pm

Introduction

For this assignment, you will be making a simple version of the word game Hangman. This will give you a chance to continue practicing with loops and our new data structure, arrays. It'll also be good practice writing helper methods that we can use to make easily testable and understandable programs.

The Assignment

You will be making a single-player version of Hangman, playable in BlueJ's terminal window. In this game, the computer picks a random word from a pre-supplied list. The player then guesses a letter that they think may appear in the word. The computer checks whether the letter appears in the word and either reveals all instances of it (if it exists) or takes away one point from the player's lives. The computer then displays (somehow) the progress that the player has made towards guessing the word. The game continues until either all of the letters have been guessed (and the player wins) or all of the player's lives are used up (and the player loses). In either case, the computer should announce this event and the game should end.

An example exchange is below:

Computer: _ _ _ _ _
Player guesses 'a'
Computer: _ _ a _ _
Player guesses 'e'
Computer: I'm sorry, the word has no 'e'. You have 4 lives left.
Computer: _ _ a _ _
Player guesses 's'
Computer: _ _ a s s
Player guesses 'L'
Computer: _ l a s s
Player guesses 'l'
Computer: You already guessed 'l'. Pick another letter.
Player guesses 'c'
Computer: Congratulations, the word is 'class'! You figured out the word in 5 guesses, and had 4 lives left.
If the player looses, they should see (as an example):
Computer: No more lives remaining. The word was 'class'.

As always, be sure to download and unzip a copy of the the Homework 5 project. so that you can submit your project once completed. This project also contains some extra classes you can use in programming your game.

As you read through these instructions, try thinking about what parts of your class you'll need to make. What functionality are we going to need? What methods will we have to create? What are the signatures of those methods? What state variables will we need to keep track of?

  1. Create a HangmanGame class (capital H, capital G) to represent the game. This is the class that will be submitted in the end.
  2. Start by creating the constructor and fields for the game. Remember to declare your fields, then define them in the constructor! What instance variables and information are you going to need to keep track of?
    • One thing you'll need to do in the constructor is load the list of words to pick from. Luckily, we've included a class to help you with this. The WordList class represents a list of words (1500 by default)--you can create a new WordList object in your constructor and use its .getWords() method to fetch an ArrayList<String> object that contains a list of words to pick from. You should pick a random word from the list (the same way you picked a random color in the last assignment).
    • For this assignment, you should create two constructors. The first uses the WordList class to get an ArrayList of words. This is your default constructor. The second will act as our "debug" constructor--it should take a single word as a paramter and use only that word as the word list. You can use this second constructor to more easily test the code (since you'll know what the word that you're guessing is!)
  3. With the fields, you'll need to keep track of both the target word that the player is guessing, as well as what "word" the player has reconstructed so far (where some letters may be blanks: e.g., "cl_ss"). Normally we'd use a String to keep track of a word. However, for this program we're interested in the individual characters of a word. While we could use methods like word.substring(0,1) (to fetch the first letter of the String for example), this becomes awkward when we want to change a single character in the String, like convert a '_' to an 'a' [consider how you might be able to accomplish this!]
    • Instead, you should represent both the target word and the current guess as arrays of chars, char[]. This gives each letter a separate index that we can easily use to reference and change them. You can convert a String into a char[] using the toCharArray() method of the String object. You can then turn a char[] back into a String (such as for printing) by using one of String's constructors that takes the char[] as a parameter.
  4. After you've created your constructors and fields, you can start making methods. The documentation below includes a number of helper methods--that is, methods that pull out some code or functionality into a separate method to make it easier to find (similar to the isTouching() method from your Ball class).
    • For example, the documentation includes a setupGame() method that initializes all the variables for the game (such as resetting the random word, the number of lives lost, etc), so that we can easily play multiple games. These helper method should be called by other methods--so the playGame() method that starts the game would call the setupGame() method at the beginning.
    • Each helper method is described in the documentation. I recommend making each helper method, one at a time, testing as you go. So you might make sure the getGuess() method prompts the user for a character, etc.
      • Bonus hint: For the getGuess() method, you should use a JOptionPane to prompt the user to input a character. However, this will return a String. You'll need to figure out how to get a single char out of that String. Try looking at the String class documentation for an appropriate method that returns a char.
    • Once you've created helper methods, you can then use them in your playGame method, which is what will be used to play a game of Hangman! Do not force the user to call your helper methods!
    • Make sure to read the documentation carefully (including the full text, not just the summary!) for further tips about what each method should due. Yes, you are being required to read class documentation to find out about assignment requirements.
  5. Once your helper methods are in place, you can write the playGame() method. This should basically be a single loop that asks the user for a guess, then checks if the guess is in the word. If the guess is in the word, then check if the word is totally solved, and if so end the game. If the guess is not in the word, then lose a life. If the player runs out of lives, the game ends.
  6. Note that based on the above example, your program should treat all guessed letters as lower-case, and should keep track of what guesses have been made--whether or not the letter is actually in the word.
    • We can use an ArrayList to keep track of guesses. However, we can't make an ArrayList<char>, because char is not an Object type (it's what is called a primitive, like int or double). However, we can make an ArrayList<Character>, an ArrayList of Character objects (the Character class acts as a kind of "wrapper" for chars, letting us treat it as an object). If you create this kind of ArrayList, you will be able to add and get chars from it exactly like you would hope.
  7. In the end, I should be able to make a new HangmanGame object, then call playGame() multiple times (e.g., by right-clicking on the object using BlueJ) in order to play multiple complete games. You do not need to include a loop to play multiple games (though see the extension below).
    • Remember to test your code thoroughly! Run each method more than once to make sure you don't have lingering errors. Make sure you can produce output similar to that described above (e.g., using the debug constructor).
  8. Be sure to document all your code clearly using Javadoc comments and tags for each class. In addition, be sure to include some inline comments explaining how your code works--particularly if you have a complicated sequence of if statements. NOTE: Private methods will not show up in BlueJ's Javadoc window, but you should still include Javadoc style comments for these. After you are done testing, feel free to make any of your helper methods private instead of public (this is better design).

Extensions

Some other functionality you might consider adding. They might be fun, and you can earn up to 5 points of extra credit for completing them. If you implement any of these, please include a note about that in the comment at the top of your class! Only start on these once you have finished the rest of the assignment and you are sure that works. Be sure to save a copy of your working code in case you don't finish these!

Submitting

As always, before submitting, test each of your methods and classes thoroughly. Make sure your game works exactly as expected! When you're convinced it's ready to go, submit the project through BlueJ just like you did in the previous Assignments (selecting Hwk5 of course).

Submitter will look for the HangmanGame.java file.

Grading

This assignment will be graded on the following criteria:

Documentation



Class HangmanGame

java.lang.Object
  HangmanGame

public class HangmanGame
extends java.lang.Object

A class to play a game of Hangman.


Constructor Summary
HangmanGame()
          Creates a new HangmanGame object--basicaly a wordlist that can be used to start a new game.
HangmanGame(String debugWord)
          Creates a new HangmanGame object, with the wordlist containing only the given debugWord.
 
Method Summary
 boolean checkGuess(char letter)
          A helper method (that could be private) that checks to see if a given letter is present in the target word.
 String currentGuessString()
          A helper method (that could be private) that returns a String representation of the current guess state.
 char getGuess()
          A helper method (that could be private) that prompts the user to provide a guessed letter.
 void playGame()
          A method that plays a complete game of Hangman.
 void setupGame()
          A helper method (that could be private) which re-initializes variables for the start of a new game.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

HangmanGame

public HangmanGame()
Creates a new HangmanGame object--basicaly a wordlist that can be used to start a new game.


HangmanGame

public HangmanGame(String debugWord)
Creates a new HangmanGame object, with the wordlist containing only the given debugWord. This enables testing of the game using a known word.

Parameters:
debugWord - The single word in the wordlist, used for testing and debugging
Method Detail

checkGuess

public boolean checkGuess(char letter)
A helper method (that could be private) that checks to see if a given letter is present in the target word. If so, all instances of that letter in the target word are revealed.

Parameters:
letter - the letter being guessed
Returns:
whether or not the letter was found in the word

currentGuessString

public String currentGuessString()
A helper method (that could be private) that returns a String representation of the current guess state. For example: "g _ e _ _" for the word "guess" if the letters 'g' and 'e' have been guessed.

Returns:
A String displaying the current guess of the word. Has the form "g _ e _ _ ".

getGuess

public char getGuess()
A helper method (that could be private) that prompts the user to provide a guessed letter. This method converts any guesses into a single, lower-case character.

Returns:
a single, lower-case char that the player guessed

playGame

public void playGame()
A method that plays a complete game of Hangman. Method ends when the game has been either won or lost.


setupGame

public void setupGame()
A helper method (that could be private) which re-initializes variables for the start of a new game. Resets the word to guess, the current letters guessed, the number of lives, etc.



Class WordList

java.lang.Object
  WordList

public class WordList
extends java.lang.Object

A wrapper class for dealing with wordlists (text files of words)

Version:
2012.09.28
Author:
Joel

Constructor Summary
WordList()
          Creates a new word list from the default file ("words1500.txt");
WordList(String filename)
          Creates a new word list from the given file
 
Method Summary
 ArrayList<String> getWords()
          Gets the words from the WordList
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

WordList

public WordList()
Creates a new word list from the default file ("words1500.txt");


WordList

public WordList(String filename)
Creates a new word list from the given file

Method Detail

getWords

public ArrayList<String> getWords()
Gets the words from the WordList

Returns:
an ArrayList of the words (each represented as a String)