CSc 220 Assignment 5

Just Hanging Around

Assigned
Due

Oct 28
90 pts
Nov 14

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

You are to create a class hangman which provides the record-keeping for a game of hangman. You should place the class 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 five lines into a .cpp file, and at least one in any case.

Note: C++ is quite happy to let you put the class inside the same file as main. For this assignment, that is not allowed. You are required to have you class in two separate files, hang.h and hang.cpp. It will build easily with one command
g++ -o hang game.cpp hang.cpp
Since you may be using the sort of build software that make small things simple and large things impossible, here are a few things I found, but not much:
  • If you have grasp running C++, I don't thing you need anything more that putting all the files in the same folder
  • For CodeBlocks
  • Haven't found anything for JScode.
Here is the makefile I'm using if that does you any good
CPPFLAGS=-g -std=c++11 game: hang.o game.o g++ ${CPPFLAGS} -o game $^ hang.o: hang.h game.o: hang.h
bennet@bennet:hman$ make g++ -g -std=c++11 -c -o hang.o hang.cpp g++ -g -std=c++11 -c -o game.o game.cpp g++ -g -std=c++11 -o game hang.o game.o

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.

As the game progresses, the hangman object h will pass through several states. The methods change the object's state, and are affected by it. When created, but before the first call to set_word, the object is in the initial state, where it is basically useless. In this state, the method guess 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. Call set_word to move the object into the guessing state, when letters may be guessed (and the object is generally good for something). The object does not return to the initial state. It stays in guessing until the player either wins or loses, that is, either the word is guessed or there are six wrong guesses. Then it enters the complete state, and will stay there until the next call to set_word, when it again enters the guessing state. When entering the guessing state for some word, all the letters of that word are marked un-gessed. As guess is called during the guessing state, some letters become marked guessed.

When a word is guessed correctly, that is a success, and when the sixth wrong letter is guessed, that is a failure. The object must count successes and failures.

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

This method sets the word to be guessed to word. Each letter in word is marked un-guessed, and no letters have been guessed. 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 was already in the guessing state when set_word is called (didn't change from initial or complete), then assume the user gave up on the previous word being guessed, and count it as a failure.

The word should not be empty (after removing non-alphabetic characters). If it is, the call should be ignored, and have no effect at all.

h.get_word()
This returns the word being guessed as a string. 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. Under each of the following conditions, your method should do nothing but return the listed code:
Return
ERRORThe object is not in the guessing state.
BADCHRch is not a letter (digit or special character).
DUPch has already been guessed (since the last set_word).
If none of these things are true, process the guess and report the result: any previously unguessed letters in the current word which match ch are become guessed. This is per the usual rules of the game, when you guess a letter that appears in multiple places, all appearances are guessed. If ch does not appear in the word, this counted as a wrong guess against the limit of six. Then, report the result by returning one of:
ReturnWhen, since the last set_word
WINch was the last unguessed character in the word.
LOSEch was the sixth wrong guess.
FOUNDch successfully guesses a letter, but there are more (game continues).
MISSEDch was a wrong guess, but not the sixth (game continues).
If the function returns WIN or LOSE, the object changes state to complete. Otherwise, the object retains its state.
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_letters_guessed()
h.num_letters_correct()
h.num_letters_incorrect()
Each returns an integer giving the numbers of letters guessed, correct, and incorrect since the last set_word. (The counts start over when set_word is called.)
h.num_words_attempted()
h.num_words_correct()
h.num_words_incorrect()
Return the integer counts of words attempted, words guessed correctly, and words not guessed correctly. A word is considered guessed once the first guess() call is made after the word is set. It is correct when the user guesses all the letters, and incorrect otherwise. These counts are over the whole life of the object, across all its games, and are not reset by set_word.
The values returned by guess need to be declared as public constant in the hangman class. You should be able to use enum, which have not talked about, or static const int, like this
static const int FOUND = 1; static const int MISSED = 2; static const int DUP = 3; ...

Here is a sample run. Please note: you are not responsible to code output. The downloaded main does all the printing and the stupid ASCII graphics. You should not be printing in you class.

Submission

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