Now that you are fortified with the knowledge of loops and functions, here's a chance to build a small game and play with it. Have fun!
Read this assignment carefully, and reread it before you submit your program for grading. Lots of careless errors can be prevented by reading the instructions again when you're almost done.
For this assignment, implement a computer program to allow the user to play a simple dice game.
The game is played with 5 dice. The basic idea is to roll the dice one at a time and try to get the sum of the numbers showing on the dice as close as possible to a target sum picked randomly by the computer. The closer you get to the target, the smaller (better) your score (full details below).
Each game consists of three independent rounds. A round is played as follows:
The program repeatedly reads commands and carries them out (an event loop). Besides commands to roll the dice, there are commands to stop the current round of the game and go on to the next one, start the game over from the beginning, quit, and get help in the form of a list of available commands.
As you play the game, the program computes your score, which is an integer value. This is a function of how close the sum of the numbers on the dice is to the target for the current round, the turn (roll number) in the current round, plus the score(s) from previous rounds of the game, if this is not the first of the three rounds. Lower scores are better. There are two rules for computing the score, depending on whether the sum of the dice is exactly equal to the target value. (Remember that the target is a random number between 5 and 30 picked by the computer at the beginning of the current round.)
Sum is not equal to target. In this case, the total score is calculated as follows:
score = absolute_value(sum-target) * turn + total_score_from_previous_round(s)
In other words, multiply the absolute difference between the target and the sum of the dice by the number of times you have rolled the dice (turns) during the current round. Add to this the total scores from the previous rounds, if any, to get the current score
Sum IS equal to target. If the sum of the numbers on the dice is exactly equal to the target for the round, the score is calculated differently:
score = 0.8 * turn + total_score_from_previous_round(s)
In other words, multiply the number of rolls of the dice on this round by 0.8 and add it to the total of the scores from previous rounds, if any. The result should be truncated to the nearest integer.
Winning and losing. At the end of the game, if the total score for all three rounds is less than 20, the player wins the game and the program prints a suitable congratulatory message. If the score is greater than or equal 20, a consoling message should be printed.
One final twist. At the beginning of a round, if you don't like the target chosen by the program for some reason, you can begin that round again. In that case, the program adds a penalty of 2 points to your total score, picks a new target, and continues.
The program is controlled by entering commands from the keyboard. The
commands are single letters (n
, r
, s
, h
,
and q
), written in either upper or lower case. In the case of
r
(roll), the letter is followed by a number from 1 to 5 specifying
the die to be rolled. Here is a summary of the commands.
For a game like this to be interesting, the target and dice numbers should be
different and unpredictable when the program is executed. The standard C
library includes a function rand
that generates sequences of
pseudo-random numbers. This function returns a different integer every
time you call it. For example, the following code will print 100
apparently random integers:
#include <stdlib.h> /* library containing rand() */ ... int k, n; ... for (k = 0; k < 100; k++) { n = rand(); printf("%d ", n); }
The sequence of numbers is called pseudo-random because rand
actually computes the next number in the sequence using a formula that involves
the previous one. So if the sequence starts with the same number,
you'll get the same sequence of "random" numbers in successive calls
to rand
.
To make the game interesting, we'd like to use a different sequence of random numbers each time it's played. The starter program for this assignment includes the following (magical) code to do this.
/* Initialize random number generator to produce a different */ /* sequence of numbers each time the program runs */ srand( (unsigned)time( NULL ) );
Don't worry what this code does, exactly. Basically, it uses some information from the system clock to initialize the sequence, which means different random numbers each time you run the program. It also means that you'll get different numbers when you run your program than you do when you run the sample program.
While lots of randomness can be great for game playing, it can be a pain when
you're trying to debug your code. It's sometimes hard to find and fix
subtle errors in a program that does different things each time you run it.
A technique that can be useful is to initialize the random number generator so
it produces the same "random" sequence each time the program
runs. You can do that by using an integer constant instead of the time
function when you call srand
. Example:
srand(777);
Different
integer constants will result in different sequences, but for any particular
constant, you should get the same sequence of numbers from rand
.
When you've finished debugging, you can change srand
back to the
original version to get different random sequences every time you play the game.
So what integer values can rand
return? This function returns non-negative integer values in the range 0 to RAND_MAX
,
where RAND_MAX
is a #define
constant that is also included in the stdlib.h
library (different versions of C may have different definitions of RAND_MAX
). You can use RAND_MAX
to scale the result of rand
however you like. However, it may be easier to just use the mod (%
)
operator to get numbers in a given range. For example, the expression rand()%8
will be a random number in the range 0 to 7.
As usual, how well your program is written is as important as whether it
works. Be sure to use good style, including appropriate use of functions, #define
for constants, appropriate comments for variable and function
declarations, and appropriate comments throughout the code.
The starter program for this assignment (see files, below) includes a skeleton for the main program, and outlines of two functions. In addition to any other functions you define (and you are encouraged to do this appropriately), you must implement and use the two functions that are specified in the starter code. These functions are
display_status
: given the current values of the dice, their
sum, target, current score, and turn number, print these values using an
appropriate format (i.e., the printf
that displays these
numbers after each turn is isolated in this function).currentScore
: given the current sum of the dice, the target,
and the turn number, calculate and return the score for the current round only
- not including the score(s) from previous rounds in the current game. See
the section on scoring for details of how to
calculate the score.Finally, the input and output information should appear in the same order as it is in the sample executable.
Start by downloading running the sample PC executable hw3.exe. One way to do that is to double-click on it from the Windows Explorer.
Try to get a feeling of how the program should behave! Play with it at least several times with different inputs until you feel you understand well the way it works. Check with the specification above to make sure it all makes sense to you - that you know what is computed, when and how. One suggestion to be sure you understand the calculations is to work some simple cases by hand (or with a pocket calculator or spreadsheet) and check that they match the output of the sample program.
The due date for this assignment is at the top of this page. Be especially aware of the web submission deadline, as submission times are tracked precisely and we cannot accept late submissions.
Turn in your homework using this web turnin form.
If any clarifications or changes need to be made for this homework, they will be posted to the cse142-announce email list and linked here.