Part 1: Debugging with the Debugger
-
Make a lab07 directory.
-
Download the file
part1.cpp and save
it in the lab07 directory.
-
Compile like this
g++ -g part1.cpp -o part1
... and run once from the command-line. If you do an ls
command, you'll see a bunch of new files have been created.
Before starting the lab proper, I want to introduce you to "the
debugger". Literally, the debugger is a program called gdb.
For us, we're going to run the debugger via emacs, so it'll
appear like the debugger is an emacs feature. It's not though,
we're just using emacs as an interface to the debugger. I'm
going to have you use the debugger to observe a function as it
executes. In the future, I hope you'll use it to observe the
execution of programs that don't run the way you expect.
- In order to effectively use gdb, you need to have
compiled your code with the -g option, as shown above.
- To run your program is the debugger through emacs:
press esc, then x, then type gdb, then hit enter, then make
sure the line at the bottom of the window looks like
gdb -i=mi part1
In particular, make sure the last chunk is the name of the
executable file you want to debug.
-
At this point, the debugger will be running in your emacs
window. You should see a new menu Gud, which is
gdb-specific stuff. If your
emacs window is not split into five or six separate panes,
choose menu Gud/GDB-UI/Display Other Windows.
-
Stop and follow along on a walk-through with your
instructor.
Part 2: define printSpaced
Create a program 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".
Part 3: define mkShadowString
Add the following code to 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.
Part 4: define crossOut
Often you want a function to modify an existing string, rather
than return a new string. I want you to define a function
crossOut that works this way. Add the following code to main:
string t1 = "Go get good food!";
cout << t1 << endl;
crossOut('o',t1);
cout << t1 << endl;
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!
Since we want to modify the string that's passed to crossOut,
we need to pass it by reference. Therefore, you'll want to use
this prototype:
void crossOut(char c, string &s);
Part 5: define uncover
Add the following code to main:
string u1 = "housepet";
string u2 = "________";
cout << u2 << endl << endl;
bool t;
t = uncover(u1,u2,'e');
cout << u1 << endl;
cout << u2 << " there " << (t ? "were " : "were not ") << "e's!" << endl;
cout << endl;
t = uncover(u1,u2,'q');
cout << u1 << endl;
cout << u2 << " there " << (t ? "were " : "were not ") << "q's!" << 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 occences of the given character within the
first string, are copied into the second string at the
positions at which they were found. True is returned if
occurences were found, false is returned otherwise. You may
assume the string arguments have
the same length.
Part 6: define fixFirstDisagreement
Add the following code to 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!
In other words, fixFirstDisagreement looks for the first (from
let to right) position at which the two strings disagree, and
modifies the second string to match the first string at that position.
It returns true if the second string has been modified, and
false if no changes were made to the second string.
Part 7: Going further, Hangman
Add the following code to your main, compile and run.
{
string fh = " ____\n | |\n _O_ |\n | |\n / \\ |\n______|_\n";
string ch = " ____\n | |\n |\n |\n |\n______|_\n";
do {
cout << ch << endl;
cout << "press <enter>" << endl;
} while(cin.get() == '\n' && fixFirstDisagreement(fh, ch));
}
If you ran this program, this should put you very much in mind
of a game ... hangman! As a challange to you, use the functions
you implemented in the earlier parts of this lab to implement the
hangman game. A few notes for you:
- if you want to see an implementation of this game in
action, try this:
pushd ~wcbrown/bin; ./hangman; popd
- if you ran the program from Part 1, you'll find a whole
slew of files got created as a result. They're word lists.
I recommend that you use
words09.txt, which
contains 909 common 9-letter words, one per line. You can
generate a random number from 1-909, and use that to
choose a random word from the file words09.txt.
That way, each time you play the game you get a different
word.
-
I like a "command" style for games like this. I.e. the user
types commands at each step. I chose
"letter <char>",
"solve <string>" and "quit" as my three commands.
-
remember: get a small part of the functionality
working, then compile-test-debug. Get a litte more of the
functionality working, then compile-test-debug.
Keep doing this until you're finished.