Hangman

Let's make a game Hangman! Toward this goal, we will need to implement some functions.

Part 1: Warmup -- define printSpaced

Create a program (call it lab07.cpp) with main

int main() {
  cout << "["; printSpaced("wash"); cout << "]" << endl;
  cout << "["; printSpaced("HelloWorld!"); cout << "]" << endl;
  cout << "["; printSpaced("I am"); cout << "]" << endl;
  return 0;
}
... which means you'll have to define the printSpaced function.

Hint: the prototype should be

void printSpaced(string);
The output should be exactly:
[w a s h]
[H e l l o W o r l d !]
[I   a m]
In other words, printSpaced prints a string with a space inserted in between consecutive characters. Thus, "wash" gets printed as if it were "w a s h".

Submit as:

~/bin/submit -c=SI204 -p=Lab07 lab07.cpp

Part 2: define mkShadowString

Add the following code to lab07.cpp's main
string s1 = "food";
string s2 = mkShadowString(s1);
cout << "original: " << s1 << endl;
cout << "  shadow: " << s2 << endl;

string s3 = "require";
string s4 = mkShadowString(s3);
cout << "original: " << s3 << endl;
cout << "  shadow: " << s4 << endl;
... and define a function mkShadowString so that the program produces the output below:
original: food
  shadow: ____
original: require
  shadow: _______
In other words, mkShadowString takes a string as input, and returns a string of the same length, but consisting solely of underscores (_'s).

Note: add this on to the previous part. That means keep the functions you already have.

Submit as:

~/bin/submit -c=SI204 -p=Lab07 lab07.cpp

Part 3: define crossOut

Now we want a function that creates a new string based on a modification of the given string, and it returns the new string. I want you to define a function crossOut that works by crossing out a desired letter. Add the following code to lab07.cpp's main:
string t1 = "Go get good food!";
cout << t1 << endl;
t1 = crossOut('o',t1);
cout << t1 << endl;
t1 = crossOut('g',t1);
cout << t1 << endl;
... and define a function crossOut so that the program produces the output below:
Go get good food!
G* get g**d f**d!
G* *et ***d f**d!
You'll want to use this prototype:
string crossOut(char c, string s);

Submit as:

~/bin/submit -c=SI204 -p=Lab07 lab07.cpp

Part 4: define uncover

Add the following code to lab07.cpp's main:
string full = "housepet";
string partial = "________";
cout << partial << endl << endl;

string newPartial = uncover(full,partial,'e');
cout << full << endl;
cout << newPartial << " there " << (partial!=newPartial ? "were " : "were not ") << "e's!"  << endl << endl;
partial = newPartial;                      

newPartial = uncover(full,partial,'q');
cout << full << endl;
cout << partial << " there " << (partial==newPartial ? "were " : "were not ") << "q's!"  << endl << endl;
... and define a function uncover so that the program produces the output below.
________

housepet
____e_e_ there were e's!

housepet
____e_e_ there were not q's!
In other words, all occurrences of the given character within the first string, are copied into the second string at the positions at which they were found. You may assume the string arguments have the same length.

Submit as:

~/bin/submit -c=SI204 -p=Lab07 lab07.cpp

Part 5: define fixFirstDisagreement

Add the following code to lab07.cpp's main:
string w1 = "id card!";
string w2 = "it bard!";
do {
  cout << w2 << endl;
} while( fixFirstDisagreement(w1,w2) );
... and define a function fixFirstDisagreement so that the program produces the output below.
it bard!
id bard!
id card!
// original w2
// due to fixFirstDisagrement(w1, w2):  w2[1]: t --> d  
// due to fixFirstDisagrement(w1, w2):  w2[3]: b --> c
In other words, fixFirstDisagreement works as follows:
  1. Look for the first (from left to right) position at which the two strings disagree.

Submit as:

~/bin/submit -c=SI204 -p=Lab07 lab07.cpp

Part 6: Going further, Hangman

You'll make a game Hangman! Before you start, download words07.txt containing a list of words of 7 characters. If you want, you can use words09.txt too.

Below is an example run:

~/$ ./hangman
What file do you want a word from? words07.txt

6 wrong guesses left. Enter a guess: e
_______ there were no e's! 

5 wrong guesses left. Enter a guess: r
_______ there were no r's!

4 wrong guesses left. Enter a guess: a
_a___a_ there were a's!

4 wrong guesses left. Enter a guess: s
_a___a_ there were no s's!

3 wrong guesses left. Enter a guess: g
_a_g_a_ there were g's!

3 wrong guesses left. Enter a guess: n
_ang_an there were n's! 

3 wrong guesses left. Enter a guess: f
_ang_an there were no f's! 

2 wrong guesses left. Enter a guess: k
_ang_an there were no k's! 

1 wrong guesses left. Enter a guess: h
hang_an there were h's! 

1 wrong guesses left. Enter a guess: b
hang_an there were no b's! 

You lose...  The word was hangman.

Of course, if I fill in the entire word before I run out of guesses, I win, instead.

It is necessary that your first user input be a filename to draw a random word from, and the remainder of user inputs be letters guessed. Each turn, you should display the blanked-out word, and the number of wrong guesses remaining. At the end of the game, you should display if the player won.

To help you write this program, write the following methods in a file called hangman.cpp:

Extra challenge

The only thing we haven't done is to draw the little man. Rather than having a countdown with the number of guesses remaining, draw the man! To get you started, here are strings that will help you:

// use the code to draw the hanging man:

    string fh = "  ____ \n"
                "  |   |\n"
                " _O_  |\n"
                "  |   |\n"
                " / \\  |\n"
                "______|_\n";

    string ch = "  ____ \n"
                "  |   |\n"
                "      |\n"
                "      |\n"
                "      |\n"
                "______|_\n";

    cout << fh << endl;
    cout << ch << endl;
Note: If you get a nice working game, please demo it to your instructor.