> ### Solution for
> Programming Exercise 4.4

> THIS PAGE DISCUSSES ONE POSSIBLE SOLUTION to the following exercise from this on-line Java textbook.

> Exercise 4.4: This exercise builds on Exercise 4.3. Every time you roll the dice repeatedly, trying to get a given total, the number of rolls it takes can be different. The question naturally arises, what's the average number of rolls? Write a function that performs the experiment of rolling to get a given total 10000 times. The desired total is a parameter to the subroutine. The average number of rolls is the return value. Each individual experiment should be done by calling the function you wrote for exercise 4.3. Now, write a main program that will call your function once for each of the possible totals (2, 3, ..., 12). It should make a table of the results, something like:

>             Total On Dice     Average Number of Rolls
>             -------------     -----------------------
>                    2               35.8382
>                    3               18.0607
>                    .                .
>                    .                .

> Discussion

> The solution uses the subroutine, `rollFor`, from the previous exercise.

> The `main()` program simply prints a heading for the output, then uses a `for` loop to compute and print the data for each of the possible rolls from 2 to 12. It is not difficult to write it, with a litte care to get the formatting right.

> The only thing left is to write a function to find the average number of rolls to get a given total on the dice. The average will be a real number, so the return type of the function is `double`. The subroutine has a parameter of type `int` that specifies the number we are rolling for. I'll call the parameter "`roll`". An algorithm for the subroutine is

>            Let totalRolls = 0
>            Repeat 10000 times:
>               Call rollFor(roll) to run the experiment once
>               Add the returned value to totalRolls
>            Compute the average by dividing totalRolls by 10000
>            Return the average

> In my program, I use a named constant, `NUMBER_OF_EXPERIMENTS`, to specify the number of experiments to be performed. This constant replaces the value 10000, making it easier to read the program and easier to change the number of experiments if I decide I want to do more experiments or fewer. This gives the subroutine:

>           static double getAverageRollCount( int roll ) {
>                    // Find the average number of times a pair of dice must
>                    // be rolled to get a total of "roll".  Roll MUST be
>                    // one of the numbers 2, 3, ..., 12.
>               int rollCountThisExperiment;  // Number of rolls in one experiment.
>               int rollTotal;  // Total number of rolls in all the experiments.
>               double averageRollCount;  // Average number of rolls per experiment.
>               rollTotal = 0;
>               for ( int i = 0;  i < NUMBER_OF_EXPERIMENTS;  i++ ) {
>                  rollCountThisExperiment = rollFor( roll );
>                  rollTotal += rollCountThisExperiment;
>               }
>               averageRollCount = ((double)rollTotal) / NUMBER_OF_EXPERIMENTS;
>               return averageRollCount;
>           }

> It is important that `roll` be in the range of possible totals on a pair of dice. If it is not, the program will enter an infinite loop in the `rollFor()` subroutine.

> Note that when the average is computed, a type-cast is used to convert `rollTotal` to type `double`. This is necessary since `rollCount` and `NUMBER_OF_EXPERIMENTS` are integers, and the computer would evaluate the quotient `rollCount / NUMBER_OF_EXPERIMENTS` as an integer.

> By the way, this subroutine could be substantially abbreviated at the expense of being somewhat less easy to understand:

>           static double getAverageRollCount( int roll ) {
>                    // Find the average number of times a pair of dice must
>                    // be rolled to get a total of "roll".  Roll MUST be
>                    // one of the numbers 2, 3, ..., 12.
>               int rollTotal = 0;  // Total number of rolls in all the experiments.
>               for ( int i = 0;  i < NUMBER_OF_EXPERIMENTS;  i++ )
>                  rollTotal += rollFor( roll );
>               return ((double)rollTotal) / NUMBER_OF_EXPERIMENTS;
>           }

> The Solution

>        public class DiceRollStats {

>            /*
>                This program preforms the following type of experiment:
>                Given a desired total roll, such as 7, roll a pair of
>                dice until the given total comes up, and count how many
>                rolls are necessary.  Now do the over and over, and
>                find the average number of rolls.  The number of times
>                the experiment is repeated is given by the constant,
>                NUMBER_OF_EXPERIMENTS.  The average is computed and
>                printed out for each possible roll = 2, 3, ..., 12.
>            */

>           static final int NUMBER_OF_EXPERIMENTS = 10000;

>           public static void main(String[] args) {
>                   // Find the average number of times a pair of dice has
>                   // to be rolled to get a given total.  Do this for
>                   // each possible total roll, 2 through 12, and print
>                   // the results.
>               double average;  // The average number of rolls to get a given total.
>               TextIO.putln("Total On Dice     Average Number of Rolls");
>               TextIO.putln("-------------     -----------------------");
>               for ( int dice = 2;  dice <= 12;  dice++ ) {
>                  average = getAverageRollCount( dice );
>                  TextIO.put(dice,10);
>                  TextIO.put("               ");
>                  TextIO.putln(average);
>               }
>           }

>           static double getAverageRollCount( int roll ) {
>                    // Find the average number of times a pair of dice must
>                    // be rolled to get a total of "roll".  Roll MUST be
>                    // one of the numbers 2, 3, ..., 12.
>               int rollCountThisExperiment;  // Number of rolls in one experiment.
>               int rollTotal;  // Total number of rolls in all the experiments.
>               double averageRollCount;  // Average number of rolls per experiment.
>               rollTotal = 0;
>               for ( int i = 0;  i < NUMBER_OF_EXPERIMENTS;  i++ ) {
>                  rollCountThisExperiment = rollFor( roll );
>                  rollTotal += rollCountThisExperiment;
>               }
>               averageRollCount = ((double)rollTotal) / NUMBER_OF_EXPERIMENTS;
>               return averageRollCount;
>           }

>          static int rollFor( int N ) {
>                    // Roll a pair of dice repeatedly until the total on the
>                    // two dice comes up to be N.  N MUST be one of the numbers
>                    // 2, 3, ..., 12.  (If not, this routine will go into an
>                    // infinite loop!).  The number of rolls is returned.
>               int die1, die2;  // Numbers between 1 and 6 representing the dice.
>               int roll;        // Total showing on dice.
>               int rollCt;      // Number of rolls made.
>               rollCt = 0;
>               do {
>                  die1 = (int)(Math.random()*6) + 1;
>                  die2 = (int)(Math.random()*6) + 1;
>                  roll = die1 + die2;
>                  rollCt++;
>               } while ( roll != N );
>               return rollCt;
>           }

>        }  // end DiceRollStats

> [ Exercises | Chapter Index | Main Index ]