
Homework 2 — User-defined Functions
Due:
Sunday, November 17, 2008, at 11:59pm
Use
functions to modify and enhance an existing program that plays the game of
Craps.
After
successfully completing this assignment, you should be able to:–
·
Understand and modify code written
by someone else
·
Design and implement functions for
a C program
·
Read mixed data (a mixture of
numeric and character data) into a program
·
Use enumerated types to make a
program more understandable
Download
and study the program that you will modify. This is called craps.c and can be found in the Code
Fragments folder of the Course Materials section
of the myWPI site for this course. Before attempting
to modify it for this assignment, compile and execute it multiple times to see
how it works.
Read
Chapter 4 of The C Programming Language, 2nd
edition, by Kernighan and Ritchie. Details about rand() and srand() can be found in Appendix B, §B5, by reading
the Linux man pages for those functions, and by reading the notes at the end of
this assignment.
Also
review enumerated types. These are introduced
on p. 39 of the textbook and defined in §A.8.4 (pp. 214-215).
Copy
the program craps.c to a
new file called hw2.c, and
modify hw2.c to contain the following enhancements:–
·
the user starts out with a bank
balance of $1000
·
the user is allowed to play
multiple games of craps
·
the user wagers money on each game
played
The
program should be modified so that the portion of the program that plays one
game of craps is packaged as a function. In addition, separate functions should
be defined and added to verify the wager, adjust the bank balance after a game
is played, and read in a yes or no answer. Here are the specifications for each
of the functions:
·
validWager: This function gets a wager
amount and checks to make sure it doesn’t exceed the player’s current bank balance.
If the wager is less than or equal to the current bank balance, the function
returns 1 (true),
otherwise it returns 0 (false).
·
playGame: plays a single game of craps,
rolling the dice as many times as necessary and printing the result. It returns
to the caller one of the enumerated constants WON
or LOST.
·
adjustBalance: This function either adds the
wager to or subtracts the wager from the player’s current balance, depending
upon whether the last game played was WON or LOST.
·
getYesOrNo: This function asks if the player
would like to play another game of craps. The function checks the response to
make sure it is either ‘y’ or ‘n’. The function should repeatedly ask for a y/n response until a valid response is entered. The
answer (either ‘y’ or ‘n’) is returned to the calling function.
For
each function, you should write pre- and post-conditions, design the function as a black box (you
don’t have to turn in the black box), define a prototype, write a stub, and,
once the program compiles successfully with each stub, fill in the function
definitions (one at a time).
·
stdio.h provides printf,
scanf, getchar
·
stdlib.h provides rand,
srand
·
time.h provides time,
which is used to “seed” the random number generator
The
main function should call getYesOrNo only
as long as the player’s balance is greater than 0 (once the player’s balance
goes to 0, the player is not allowed to continue).
Balance = $1000.00
Enter wager: 100
Player rolled 5 + 6 = 11
Player wins
Balance = $1100.00
Do you want to play another
game? (y or n): y
Enter wager: 1500
Your wager must not exceed
your current balance.
Enter a new wager: 900
Player rolled 3 + 1 = 4
Point is 4
Player rolled 4 + 5 = 9
Player rolled 5 + 5 = 10
Player rolled 5 + 6 = 11
Player rolled 3 + 3 = 6
Player rolled 3 + 5 = 8
Player rolled 6 + 2 = 8
Player rolled 1 + 5 = 6
Player rolled 3 + 5 = 8
Player rolled 5 + 6 = 11
Player rolled 3 + 1 = 4
Player wins
Balance = $2000.00
Do you want to play another
game? (y or n): q
You must answer y or n.
Do you want to play another
game? (y or n): y
Enter wager: 2000
Player rolled 6 + 5 = 11
Player wins
Balance = $4000.00
Do you want to play another
game? (y or n): n
Your final balance is
$4000.00
This
program requires a deeper understanding of how C does keyboard input. When
reading in single characters (like y
or n) it is usually easier to use the C function getchar() instead of using scanf().
getchar() returns the next single character from the
input stream. Look at the Sample Execution above. You would use a printf() statement to output the prompt, “Do you want
to play another game? (y or n): “. Now think of what the user types in response...not
the single character y, but two
characters, y and the ENTER key (i.e., the C constant ‘\n’).
You can read in the y with the
statement
ch = getchar();
That
still leaves the newline character in the input buffer. This becomes a problem
if the user had typed in an invalid response like q instead of y or n, because the next time you try to use getchar to read in a valid response it will read in
the newline, not the user’s new input value. Similar problems are encountered
if you use getchar after
reading in a numeric value; scanf reads in
the characters for the numeric value, and leaves the next character to be read
(the newline character) still in the input buffer. A quick way to fix this
problem is to follow each input statement with the loop:
while (getchar() != ‘\n’);
(Notice
the placement of the semi-colon. The loop body is empty.) This loop essentially
reads the rest of the characters on the line, and ignores them, until it
reaches the end of the line. The next time your program executes an input
statement (either scanf or getchar) it will get the input from the next line
typed by the user. You may find getYesOrNo the
most difficult function to write for this assignment. It is suggested that you
get everything else working in your program first, and then add the code that
relies on getYesOrNo.
You
should write a short text file (i.e., .txt
format) called README, to be
submitted with your program. Submit your implementation and README files using the following turnin
command:–
/cs/bin/turnin submit cs2301 hw2
hw2.c README
Be sure to put your name at the top of ALL files! You would be surprised at how many students forget
this.
Programs
submitted after 11:59pm on November 16 will be tagged as late, and will be
subject to the late homework policy.
This
assignment will be graded on the following areas: documentation (including pre- and post-conditions
for all functions, specified as comments in the code), proper choice of
parameters and local variables, proper choice of function return types,
adherence to specifications for each function, correctness, and robustness
(ability to recover from invalid input). Programs
must compile successfully in order to receive points for correctness.
Craps
is a game of chance in which a player rolls a pair of dice. After the two dice
have come to rest, the numbers of spots on the two upward faces are added
together. If the sum is 7 or 11, the player wins. If the sum is 2,
3, or 12,
the player loses and the “house” wins. If the sum is 4,
5, 6, 8, 9, or 10 on the first throw, then that sum becomes the player’s point, and the player rolls again. The player continues to
roll the dice until either he/she gets the point again (in
which case the player wins) or a 7 is rolled, in
which case the player loses.
Many
engineering and scientific problems require programs to use random numbers. For example, random numbers can be used to
simulate noise in an electronic circuit or arrival times of events in the
external world. For purpose like these, random number generators
are used. A random number generator is a function
that returns a seemingly random value each time it is called. A large body of
mathematical theory exists for random number generators, dealing with their behavior,
the quality of their randomness, and other factors.
Linux
provides several random number generators. In this assignment, the function
int rand(void);
returns
a new random number each time it is called. The random values are in the range
0
.. RAND_MAX,
where
RAND_MAX is as least as large as 215-1 (i.e., 32,767). If you want a random number
in the range, say, 0 .. 6, then you can
generate one with the expression
rand() % 6
However,
random numbers are particularly vexing when trying to debug a program, because
they produce a different value each time. Therefore, random number generators
are typically designed to accept a seed (i.e., a
starting value) and generate a sequence of random numbers from that seed. This
way, you can always get the same sequence while you are debugging your program.
Once your program is running correctly, you can then replace the seed with
something different — for example, the time of day — to generate more realistically
random values.
To
seed the Linux random number generator, the function
void srand (unsigned int seed);
may
be used. The default value for seed
is 1.
In
the craps.c file, you will
notice that srand is called with an argument time(NULL), which returns the time in
seconds since an arbitrary beginning used by all Unix and Linux systems. If you
have problems during your debugging, it is suggested that you temporarily
comment out the call to srand().