Monica and Chandler at the craps table.

In this lab, you will build a version of the dice game "craps"!

The rand() Function

Quite often in programming you need random numbers. How this is done is a science in and of itself, but the standard library cstdlib contains a function rand() that you can use.
    
#include <cstdlib>
It returns a random int in the range 0,....,RAND_MAX, where RAND_MAX is usually 231 - 1, defined in cstdlib.

#include <cstdlib>
#include <iostream>
using namespace std;

int main()
{
  // Print out random numbers 
  for(int i = 0; i < 5; i++)
    cout << rand() << " ";
  cout << endl;
  
  return 0;
}

The program will output 5 random numbers. If I run this, I get:

1804289383 846930886 1681692777 1714636915 1957747793

The function rand() is not purely random!

Q: Run your program three times in succession. What do you note about the output?

Answer: The output is always the same.

In a sense, there is a fixed sequence and rand() will pull up a number in the sequence one by one. To reiterate, each individual number from rand() looks random, but the random-looking sequence itself is fixed.

The srand() Function

Seeding rand(): choose a random-looking sequence

To combat this, you can call srand(), which seeds rand(). Essentially, when you give srand a seed, it uses the seed to pick a sequence.

#include <cstdlib>
#include <iostream>
using namespace std;

int main()
{
  // seeding rand()
  int seed;
  cout << "seed: ";
  cin >> seed;
  srand(seed);


  // Print out random numbers 
  for(int i = 0; i < 5; i++)
    cout << rand() << " ";
  cout << endl;
  
  return 0;
}
Here are sample runs:
$ ./a.out
seed: 1
1804289383 846930886 1681692777 1714636915 1957747793
$ ./a.out
seed: 1
1804289383 846930886 1681692777 1714636915 1957747793
$ ./a.out
seed: 3
1205554746 483147985 844158168 953350440 612121425
$ ./a.out
seed: 3
1205554746 483147985 844158168 953350440 612121425
$ ./a.out
seed: 100
677741240 611911301 516687479 1039653884 807009856

srand(): only one time in the beginning of main()

In general, if you want to use random number in your program, you can do the following:

Part 1 : "Let's Roll"

Write a code p1.cpp that simulates the following: The program should output the results of 5 rolls of the two die in the following format:
Player rolled 6 + 1 = 7
Player rolled 3 + 1 = 4
Player rolled 2 + 4 = 6
Player rolled 1 + 5 = 6
Player rolled 2 + 3 = 5
Requirement

Why rand()%8 and retry?

What about simply using rand()%6? It will give one of the six numbers and we don't need to use a loop.

That will actually work. However, it turns out that what rand() gives us a random number between 0 and 231 - 1, and rand()%6 is slightly more likely to become 0 or 1 than other numbers.

On the other hand, rand()%8 wil give a random number from (0, 1, ..., 7) equaliy likely, but then to get a number between 1 and 6, we may need to try again.

Quick check:

  1. How many times do you call srand() in your program?
     Answer (drag a mouse): only once
  2. How may times do you call rand() in your program?
     Answer (drag a mouse): many times (i.e., every time you need to choose a random number) 
  3. When do you have to call srand() in your program?
     Answer (drag a mouse): in the beginning of your program 

Adding srand()

Add the following code snippet to your p1.cpp in the beginning of the main() function.


int seed;
cout << "Enter seed value: ";
cin >> seed;
srand(seed);

Sample runs

Your program should work exactly as follows:
~/$ ./p1
Enter seed value: 7
Player rolled 5 + 3 = 8
Player rolled 3 + 5 = 8
Player rolled 3 + 2 = 5
Player rolled 1 + 1 = 2
Player rolled 3 + 1 = 4
~/$ ./p1
Enter seed value: 20
Player rolled 2 + 1 = 3
Player rolled 5 + 6 = 11
Player rolled 1 + 1 = 2
Player rolled 6 + 4 = 10
Player rolled 1 + 1 = 2

Submission

~/bin/submit -c=IC210 -p=lab06 p1.cpp

Part 2 : Craps

Now we will write a program that simulates a dice game Craps played by two parties: the player and the house. The rules for your game of Craps are as follows:

Sample runs are shown below:

~/$ ./p2
Enter seed value: 1
Player rolled 6 + 1 = 7 Player wins!

~/$ ./p2
Enter seed value: 12
Player rolled 2 + 2 = 4 roll again
Player rolled 3 + 5 = 8 roll again
Player rolled 1 + 1 = 2 House wins!
~/$ ./p2
Enter seed value: 10
Player rolled 6 + 5 = 11 Player wins!

~/$ ./p2
Enter seed value: 2018
Player rolled 1 + 5 = 6 roll again
Player rolled 4 + 2 = 6 roll again
Player rolled 6 + 5 = 11 Player wins!
Requirement

Using the function throwdice(), your program will simulate craps up until either the player or the house wins.
Note 1: You're going to have to give some thought to which function is responsible for printing what.
Note 2: Your output format must match the examples exactly!

Submission

~/bin/submit -c=IC210 -p=lab06 p1.cpp p2.cpp

Part 3: "You're Fired!"

The owner of the casino, runs analysis on your craps program and sees the odds are stacked in favor of the player. He orders you to implement a version that favors the house. After showing your game to a math professor, the following rules are added to your game.
  1. On the first roll, you win on 7 or 11, and you lose with 2, 3, or 12. Game over.
  2. If the first roll is 4, 5, 6, 8, 9, or 10, then the number rolled becomes your setpoint. You then repeatedly roll the die until:
    • You either roll your setpoint for a win, or
    • you roll a 7 or 12 for a loss (7 is a loser for the player unless rolled on the first try).
Besides these rule changes, you should also let the player keep playing as long as they want. After each game ends, ask the player to enter y or n if they want to play another game or not.

Hint: think about adding a parameter setpoint to your throwdice() function. This would allow you to deal with throws after the first. Of course you still have to deal with the first throw. You might make different functions to distinguish the first from the following throws. Or you might use arguments to throwdice() to determine which case you're in. Or you might do something altogether different.

Below are some sample outputs.
~/$ ./p3
Enter seed value: 107
Player rolled 5 + 5 = 10 setpoint is 10!
Player rolled 4 + 4 = 8 roll again
Player rolled 5 + 3 = 8 roll again
Player rolled 6 + 2 = 8 roll again
Player rolled 6 + 1 = 7 House wins!
Play again? y
Player rolled 5 + 4 = 9 setpoint is 9!
Player rolled 3 + 1 = 4 roll again
Player rolled 2 + 2 = 4 roll again
Player rolled 2 + 3 = 5 roll again
Player rolled 2 + 4 = 6 roll again
Player rolled 1 + 2 = 3 roll again
Player rolled 1 + 1 = 2 roll again
Player rolled 5 + 6 = 11 roll again
Player rolled 3 + 2 = 5 roll again
Player rolled 2 + 3 = 5 roll again
Player rolled 1 + 2 = 3 roll again
Player rolled 5 + 1 = 6 roll again
Player rolled 6 + 2 = 8 roll again
Player rolled 2 + 5 = 7 House wins!
Play again? y
Player rolled 5 + 3 = 8 setpoint is 8!
Player rolled 1 + 1 = 2 roll again
Player rolled 2 + 1 = 3 roll again
Player rolled 1 + 5 = 6 roll again
Player rolled 2 + 3 = 5 roll again
Player rolled 2 + 2 = 4 roll again
Player rolled 4 + 1 = 5 roll again
Player rolled 1 + 3 = 4 roll again
Player rolled 3 + 3 = 6 roll again
Player rolled 4 + 6 = 10 roll again
Player rolled 6 + 1 = 7 House wins!
Play again? y
Player rolled 2 + 1 = 3 House wins!
Play again? y
Player rolled 1 + 2 = 3 House wins!
Play again? n

Submission

~/bin/submit -c=IC210 -p=lab06 p1.cpp p2.cpp p3.cpp