CS16, Summer 2012

Selection structures, random numbers,
and playing a guessing game with the user

Goals for this lab

By the time you have completed this lab, you should be able to

Step by Step Instructions

Step 0: Get together with your assigned lab partner

Carefully choose the first pilot. Let the person who has been the pilot the least amount of time so far be the pilot first this time. As usual, switch roles after awhile - you don't have to wait for us to tell you!

If your assigned partner is more than 5 minutes late, ask the TA to pair you with someone else for this week.

Step 1: Create a directory for this lab in the pilot's account

This lab's pilot should log in. You will (both) work in this account for the rest of the lab.

Create a ~/cs16/lab03 directory and make it your current directory:

-bash-4.2$ mkdir ~/cs16/lab03
-bash-4.2$ cd ~/cs16/lab03

Step 2: Use ch (awkwardly) to learn about if and if/else

Start ch (notice how kyledewey simplified the ch prompt):

-bash-4.2$ ch
                Professional edition, version
              (C) Copyright 2001-2009 SoftIntegration, Inc.
/cs/student/kyledewey/cs16/lab03> _prompt = "ch> "

Then accomplish the following steps in order at the ch prompt:

  1. Declare an int (variable) named target, and initialize it to 3.
  2. Declare an int named guess, and initialize it to 3 also.
  3. Verify that target is equal to guess by typing the expression, guess == target at the prompt:
    ch> guess == target
    Remember that 1 signifies true, so that means guess is equal to target in this case.
  4. Just to be complete, try entering guess != target and verify that 0 results, because 0 signifies false in C.
  5. Then type the following compound statement all on one line and verify success:
    ch> if (guess == target) printf("success\n");
    And type it again with the condition falsified (remember you can repeat commands with the up arrow, and use arrow keys to edit), and verify that nothing prints:
    ch> if (guess != target) printf("success\n");
  6. Normally, we would type the preceding compound statement on two lines like this:
    ch> if (guess != target)
    ch>    printf("success\n");
    Ooops, but that's not right! The problem is that ch considers that to be two separate statements, not one compound if statement. This is a problem at the ch command prompt only. We can take advantage of the C "continuation character" to get around it. In C, a backslash character ('\') can always be used at the end of a line to indicate that it continues on the next line. So let's try again with the continuation character this time:
    ch> if (guess != target)\
    ch>     printf("success");
    Okay! It's awkward, but it works.
  7. We will need the continuation character to neatly write an if/else structure that will execute at the ch prompt. Write one now that will print "success" if guess equals target, or "fail" if guess does not equal target:
    ch> if (guess == target)\
    ch>     printf("success\n");\
    ch> else\
    ch>     printf("fail\n");
  8. Finally, use the up arrow to repeat that if/else structure, but edit the first line to falsify the condition. Verify "fail" is the printed response.

Step 3: Use ch to learn about the functions rand() and srand()

The rand function is defined in the <stdlib.h> library. It is readily available in ch, but you must include the library to use it in a Standard C program. This function returns a pseudorandom integer between 0 and RAND_MAX (which is also defined in <stdlib.h>, but apparently is not automatically available to ch). You can find out the "default" first pseudorandom value by typing the following at the ch prompt:

ch> rand()

Type it again and again to get the next two values in the default sequence:

ch> rand()
ch> rand()

Two reasons they are called "pseudorandom" numbers: (1) eventually the sequence will repeat; and (2) the sequence is determined by a numerical seed value. By default, this seed equals 1. So that means if you don't set the seed to something else, then the same sequence will occur every time you run the program; and it also means if you reset the seed to its original value, then this sequence will repeat.

Pass an unsigned integer to the function srand to set the seed. For example, notice how passing the value 1 will restart the default sequence:

ch> srand(1)
ch> rand()

Of course, using a different value as the seed will result in a different sequence:

ch> srand(25)
ch> rand()

Many programmers use the system time to seed the random number generator. In Standard C you must include the <time.h> library, but that is not necessary at the ch prompt. The following line prints the current system time (executed Monday, April 16 at 12:52:25 PDT 2012):

ch> time(NULL)

[Note: the constant NULL is defined in <stdlib.h> like rand and srand.] Here is how the system time can be used to seed the random generator, and start a new and seemingly unpredictable pseudorandom sequence:

ch> srand(time(NULL));
ch> rand();

The trick used to find a random value in a certain range involves the modulus operator. For example, rand()%10 produces a value in the range 0 to 9 (the remainder after dividing by 10). In general, to produce a random value in the range a to b, use the following formula:

a + rand() % (b-a+1)

Of course you can simplify the formula if a is 0 or 1. For example, you can use a simpler formula to find a random value between 1 and 3 inclusive. Do that now, and enter it several times until you are satisfied that your formula works - meaning that all of 1, 2 and 3 can occur, but never anything less than 1 or greater than 3.

Step 4: Complete a C program to let a user guess a random value

First: switch roles between pilot and navigator if you did not already do that.
Always stay logged into the original pilot's account.

Save a copy of this program skeleton as guess.c in the original pilot's lab03 directory. You can cp a copy from the instructor's account as follows:

cp ~kyledewey/cs16/lab03/guess.c ~/cs16/lab03/

The goal of this step is to modify guess.c so that it behaves like our solution, as demonstrated by the following runs (after guess.c was compiled):

-bash-4.2$ ./guess
Guess a number between 1 and 3: 1
-bash-4.2$ ./guess
Guess a number between 1 and 3: 1
Wrong. Target is 3.
-bash-4.2$ ./guess
Guess a number between 1 and 3: 1
-bash-4.2$ ./guess
Guess a number between 1 and 3: 1
Wrong. Target is 2.

Add the following features to guess.c using emacs (or another editor of your choice). Then save, and quit the editor.

  1. Replace "YOUR NAME(S)" at the top with your names, and generally follow any instructions highlighted by upper case letters in the file.
  2. Declare any variables you will need at the beginning of main.
  3. Find a random target value in two steps: (1) use srand to seed the random generator by the system clock time (as in Step 3 above); and (2) use rand and the formula you devised in Step 3 to select a random integer in the range 1 to MAX (which is currently defined as 3 in the program).
  4. Get a guess from the user in two steps: (1) use printf to prompt for input exactly like our solution does; and (2) use scanf to store the user's response - you might want to refer back to Lab02 if you don't remember how this is done.
  5. Use an if/else structure (just like the one in Step 2 above) to decide if the user's guess is equal to the target value. Print the proper response, just like the solution does.

Step 5: Run and test the program

You can use ch to test your program without starting a ch session. Here is a test of our solution that way:

-bash-4.2$ ch ./guess.c
Guess a number between 1 and 3: 1
Wrong. Target is 3.

If errors occur: (a) don't panic, and (b) don't immediately ask the TA for help! Read each error message. Look at the line number it refers to in your program, as that is likely where the problem is.

Try to fix it on your own before asking the TA for help.

When you are satisfied it works, make an executable version of it to run for the TA:

-bash-4.2$ make guess
cc     guess.c   -o guess

Step 6: Get credit for the lab

Submit the lab with the turnin program. You MUST have both your name and your partner's name in the file in order to receive credit. Remember that the original pilot needs to do this step, since that is whose account you have been using in Cooper Lab.

Bring up a terminal window on either CSIL or the Cooper lab, and cd into the original pilot's cs16 directory, and cd again into the lab03 directory. Then type the following:

turnin lab03@cs16 guess.c

Respond "yes" when the program asks if you want to turn in (be sure to read the list of files you are turning in), and then wait for the message indicating success.

Evaluation and Grading

Each student must accomplish the following to earn full credit for this lab:

Deadline for lab submission: Wednesday 7/18 (11:59pm)

Optional Extra Challenge

Adapted by Kyle Dewey from a lab prepared by Michael Costanzo.