import java.util.Scanner;

/**
 *  A probability experiment in which a bunch of dice are rolled over and over to
 *  see how likely each possible total is.
 */
public class DiceStats {

   public static void main(String[] args) {
   
      int numberOfDice;   // The number of dice that the user wants to roll.
      int numberOfRolls;  // The number of times that the dice will be rolled.
      int[] rollCounts;   // rollCounts[t] is the number of times that the dice total is t.
      int maxCount;       // the largest number in rollCounts, used to scale the bar graph.
      ListOfDice dice;    // An object that represents the dice that are being rolled.     
      Scanner in = new Scanner( System.in ); // Used to read the user's input.
      
      /* Get the number of dice and the number of rolls from the user. */
      
      System.out.println();
      System.out.println("   This program will roll a given number of dice repeatedly");
      System.out.println("and will report the number of times each possible total comes");
      System.out.println("up, along with the percentage of rolls in which that total");
      System.out.println("came up.  The program also draws a primitive bar graph to");
      System.out.println("illustrate the data.  The user inputs the nubmer of dice to");
      System.out.println("be rolled and the number of times that they will be rolled");
      System.out.println("");
      System.out.print("Enter the number of dice:  ");
      numberOfDice = in.nextInt();
      System.out.print("Enter the number of rolls: ");
      numberOfRolls = in.nextInt();
      
      /* Create the data structures, a ListOfDice object with the specified number of dice
       * and the array that will hold the counts of all the possible totals.  Note that the
       * maximum possible total on numberOfDice dice is numberOfDice*6, so we use an array
       * in which the index of the last position is numberOfDice*6 (and the length is one
       * more than that.  */
      
      dice = new ListOfDice(numberOfDice);
      rollCounts = new int[numberOfDice*6 + 1];
      
      /* Test the dice by printing out the values on the dice and their total. */
      
      System.out.println();
      System.out.println("Testing the dice...");
      System.out.print("The dice show: ");
      for (int i = 0; i < numberOfDice; i++)
         System.out.print(" " + dice.getDie(i));
      System.out.println();
      System.out.println("      for a total of " + dice.getTotal() + ".");
      System.out.println();
      
      /* Roll the dice. Each time, add 1 to the appropriate position in rollCounts. */
      
      System.out.println("Rolling " + numberOfDice + " dice " + numberOfRolls + " times...");
      
      for (int i = 0; i < numberOfRolls; i++) {
         dice.roll();
         int total = dice.getTotal();
         rollCounts[ total ] += 1;
      }
      
      /* Compute the largest number in the rollCounts array, to be used for scaling the graph. */
      
      maxCount = 0;
      for (int i = 0; i < rollCounts.length; i++) {
         if (rollCounts[i] > maxCount)
            maxCount = rollCounts[i];
      }
      
      /* Print statistics abou the rolls.  Note that the smallest possible total on N dice
       * is 6*N, so we start printing at the 6*numberOfDice-th position in the array.  The
       * bar graph is created by drawing a sequence of X's where the number of X's is
       * proportional to the value of rollCount[i].  The length of the longest sequence is 30. */
      
      System.out.println();
      System.out.println("Done.  The statistics:");
      System.out.println();
      System.out.println("Total    Count    Percentage  Bar Graph");
      System.out.println("-----  ---------  ----------  ------------------------------");
      for (int i = numberOfDice; i < rollCounts.length; i++) {
         double fraction = (double)rollCounts[i] / numberOfRolls;
         int barLength = (int)((double)rollCounts[i]/maxCount * 30 + 0.5);
         System.out.printf("%5d  %9d  %7.2f%%    ", i, rollCounts[i], fraction*100);
         for (int j = 0; j < barLength; j++)
            System.out.print("X");
         System.out.println();
      }
      System.out.println();
      
   }

}  // end class DiceStats

/*  Sample output from the program:

   Rolling 5 dice 10000000 times...

   Done.  The statistics:

   Total    Count    Percentage  Bar Graph
   -----  ---------  ----------  ------------------------------
       5       1204     0.01%    
       6       6513     0.07%    
       7      19158     0.19%    X
       8      44971     0.45%    X
       9      90225     0.90%    XXX
      10     162013     1.62%    XXXXX
      11     263362     2.63%    XXXXXXXX
      12     392061     3.92%    XXXXXXXXXXXX
      13     539533     5.40%    XXXXXXXXXXXXXXXX
      14     696118     6.96%    XXXXXXXXXXXXXXXXXXXXX
      15     835867     8.36%    XXXXXXXXXXXXXXXXXXXXXXXXX
      16     945367     9.45%    XXXXXXXXXXXXXXXXXXXXXXXXXXXX
      17    1002730    10.03%    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      18    1003265    10.03%    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      19     945815     9.46%    XXXXXXXXXXXXXXXXXXXXXXXXXXXX
      20     837393     8.37%    XXXXXXXXXXXXXXXXXXXXXXXXX
      21     693999     6.94%    XXXXXXXXXXXXXXXXXXXXX
      22     540741     5.41%    XXXXXXXXXXXXXXXX
      23     392490     3.92%    XXXXXXXXXXXX
      24     264114     2.64%    XXXXXXXX
      25     161579     1.62%    XXXXX
      26      89913     0.90%    XXX
      27      44825     0.45%    X
      28      19160     0.19%    X
      29       6302     0.06%    
      30       1282     0.01%    
*/

