CSc 220 Assignment 5

Just Hanging Around

Assigned
Due

Nov 10
80 pts
Nov 27

You are to create a class that will complete a program to play Hangman. You are given the main program and are to write a supporting class with the interface described below. The finished program provides an interactive hangman program using the text interface.

Class hangman

Create a class called hangman which performs the record-keeping for a hangman game. It keeps track of a word being guessed, which letters in that word have been successfully guessed, and which incorrect letters (letters not in the word) have been guessed. An attempt to guess a word is a round, and the round ends successfully if the word is guessed. It ends unsuccessfully after six incorrect letter guesses.

The object must keep track of the letters guessed within each round, and which were correct. It must also keep track of the total numbers of successful and unsuccessful rounds.

As the game progresses, the hangman object h will pass through several states. The methods change the object's state, and are effected by it. When created, but before the first call to set_word, the object is in the initial state. In this state, there is no word to guess, so the guess method should not be called, and will return an error if so. All get methods which return integers return zero, and those which return strings return the empty string. When set_word is called, that specifies a word to guess and starts a round. The object then enters the guessing state. It stays there until the the round ends (successfully or otherwise), when it enters the complete state, and will stay there until the next call to set_word, when it reenters the guessing state.

Interface

These are the required public methods for your class. You may also provide any private methods you wish. Except for the constructor, each method is shown as called on some object of type hangman denoted h, with appropriate parameters, so it looks more like a call than a declaration.

hangman()
The constructor sets up the object. The newly-constructed object is in the initial state, therefore mostly useless until the set_word method is called. All counts are set to zero.
h.set_word(word)

This method sets the word to be guessed to the string word and starts a new round. Each letter in word is marked un-guessed, and there are no incorrect letter guesses. Any non-alphabetic characters in word are removed, and any upper-case characters changed to lower case. The object h will be in the guessing state after this call. If it was already in the guessing state when set_word is called, count that as an unsuccessful round, since it never reached completion.

The word should be non-empty after removing non-alphabetic characters. If it isn't, the call should be ignored, and have no effect at all.

h.get_word()
This returns the word being guessed. It is the argument last sent to set_word, with non-alpha characters discarded, and others set to lower case. In the initial state, return the empty string.
h.guess(ch)
This tells the object h that the user has guessed the character ch. The object h should be in the guessing state. If not, or if ch has been guessed previously in this round, simply return an error (see below). Otherwise, any un-guessed letters in the current word which match ch are marked as guessed. If ch does not appear in the word, this counts as an incorrect guess against the limit of six. The method returns an integer, which has one of the values: FOUND, MISSED, DUP, WIN, LOSE, BADCHR or ERROR. These names must be defined in the class as public static const int fields. You may choose any values you like, so long as they are all different. Return values as follows:
ReturnWhen
WINch was the last un-guessed character in the word.
LOSEch was the sixth incorrect letter guess.
FOUNDch was an un-guessed character in the word, but some remain.
MISSEDch was an incorrect guess, but not the sixth.
DUPch has already been guessed.
BADCHRch is not a letter.
ERRORThe object is not in the guessing state.
If the function returns WIN or LOSE, the round ends and object changes state to complete. Otherwise, the object retains its state. If the round ends, increment the appropriate count of successful or unsuccessful rounds.
h.is_found(n)
This returns type bool. The argument is a legal subscript of the string returned by get_word, and the return value tells if that character has been marked guessed.
h.num_words_guessed()
h.num_words_correct()
h.num_words_incorrect()
These all return integers, giving, respectively, the number of completed rounds, the number of successfully completed rounds, and the number of unsuccessful rounds, since the object was created.
h.num_remaining_blanks()
Return number of characters in the current word which are marked un-guessed. This count restarts each new round.
h.num_letters_guessed()
h.num_letters_correct()
h.num_letters_incorrect()
Returns, respectively, the total number letters guessed, the numbers of letters correctly guessed, and the number of letters incorrectly guessed during this round. If a guess is repeated, it just counts once. Of course, these counts restart whenever a new round starts.

Files

You are to create your class hangman in a file named hang.h, since this is the name the given main program expects. You should also create a file hang.cpp which contains the bodies of the larger methods. Make sure your .h file follows the #ifndef/#define/#endif pattern discussed in class.

When creating a class in a .h file, it is usual practice to place the bodies of larger methods into an associated .cpp file. Larger usually means more that two or three lines of code. It is my requirement for this project that you put any body larger than thee lines into a .cpp file, and at least one in any case.

Running

The basic commands to compile this two-part program would be

c++ -c game.cpp c++ -c hang.cpp c++ -o game game.o hang.o
But you can do it on one command, as
c++ -o game game.cpp hang.cpp
For Codeblocks, you will want to create a project. Choose File/New/Project/Console application/C++. The project will appear in the panel on the left. Open or create each file, and right click on its tab to choose “add to current project”. If you find that Codeblocks has helped you out by adding a extra main program that you don't need, right click and remove from the project. Once you have the files in the project, build will figure out the right steps to compile them.

Some Hints

You may keep track of the needed values any way which works well for you. Of course, you will probably want to use a string for the current word, and integers for the various counts. I used a set to keep track of which characters had been guessed during a round, and a vector of bool to keep track of which characters in the current word have been marked guessed.

You might start by creating a simple class which just returns constants for each operation, and getting that to compile. Then start implementing the methods correctly.

Submission

When your program works, is well-commented, and nicely indented, submit over the web here.