CS21 Homework 10
Due Sunday, November 23 by 11:30pm


Introduction

For this assignment you will extend the hangman program that you wrote last week. If you do not have a working program from last week, please contact me and I will provide you with my solution.

The first objective for this assignment is for you to practice using files by picking a random word for the hangman game from a file. For extra credit, you can use the program we wrote in class on Tuesday to create an encoded version of the file containing the words. Then your hangman program will have to decode the word after reading it in.

The second objective for this assignment is for you to learn how to use make to compile large programs that are separated into multiple files. You will convert your solution to Homework 5, which used graphics to draw the hangman scaffold and body parts, into a library to be used with your hangman game.

You may work with a partner for this assignment. Again, be sure to add a comment to the top of your programs with both partner's names. Only one partner needs to turn in the code.


Part A: Incorporating Files

Using emacs or vi, create a file called words.txt containing one hangman word per line as shown below. Once your program is working correctly, feel free to change these words and add more possibilities.

ORANGE
MEOW
TROUBLE

Our strategy for choosing a random word from this file will require two steps. First, we will open the file, count how many lines it contains, and close the file. Second, we will choose a random number between 1 and the number of lines, re-open the file, read lines until we reach the chosen word, and close the file.

  1. Write a function with the following prototype to return the number of lines contained in the given filename.
    int CountLines(char filename[]);
    
  2. Write a function to randomly choose one of the secret words from the given filename. Your function can either return the secret word as a character pointer, or it can pass in an array in which to store the secret word. Thus, your function should have one of the following prototypes:
    char *ChooseSecretWord(char filename[]);
    void ChooseSecretWord(char filename[], char secretWord[]);
    

    Your function should call the CountLines function to determine how many lines the file contains. You may use either fgets or fscanf to read one line at a time from the file.


Part B: Creating your own library

Before you try to incorporate the drawing program we did in Homework 5 into your hangman game, re-familiarize yourself with how it operates. Update your program as necessary to meet these requirements. Once your previous program is working correctly, we can now modify it to work as a library for our hangman program.
  1. Copy your original program to a new program called drawman.c. You can use the Unix cp command which has the syntax:
    cp source destination
  2. Edit the drawman.c program. Move all of the #define lines and prototypes from this file into a new file called drawman.h.
  3. Re-read the beginning of section 8.3 (pages 274-280) on how to save programming tools into a library.
  4. Modify the drawman.h file so that it can be used as a library. You'll need to wrap the constant definitions and the prototypes with the following special lines.
    #ifndef _drawman_h
    #define _drawman_h
    
    // constant definitions and prototypes go here
    
    #endif
    
  5. Edit the drawman.c program to remove main and add the following line to the top:
    #include "drawman.h"
    This file should now only contain the includes and a series of function definitions.
  6. Edit your hangman program to include the drawman.h library at the top. Next, you'll need to add calls to InitGraphics and DrawScaffold in your main program. Finally you'll need to determine where to put the call to DrawBodyPart so that a new body part will be drawn after each wrong guess.
  7. To compile your program do:
    gccx -o game drawman.c hangman.c
    

Part C: Using make files

It is inefficient to have to recompile all parts of a multi-file program when only one of the files has been modified. The make utility provides us with a way to declare the interdependencies between files so that we only recompile the pieces that are affected by a particular change.

Edit a file called makefile and insert the following lines. We will discuss how to use this file in class.

# makefile for the hangman program

game: drawman.o hangman.o
	gccx -o game drawman.o hangman.o

hangman.o: drawman.h hangman.c
	gccx -c hangman.c

drawman.o: drawman.h drawman.c
	gccx -c drawman.c

clean:
	rm -f *~ *.o game
Once you have created your make file, you need only type
make
and your program will be recompiled in the most efficient manner.

Make files can perform many useful actions in addition to compiling programs. For example, in the above file, I've included a clean action to remove several files, so that the next call to make will recompile everything from scratch. To execute this line, type:

make clean
.

Extra Credit: Decoding the words

Only attempt this part, if you have successfully completed all the previous parts. Use the program we wrote in class on Tuesday to encode your words.txt file. Then modify your ChooseSecretWord function so that it calls a new Decode function on the randomly selected word. The Decode function should undo the previous encoding.

Handing in your solution

Use cs21handin to turn in the following files: