// CS 202, Fall 2007
// Assignment #1, Problem 2
// MGR - 09/12/06
//
// Fig. 6.11: fig06_11.cpp
// Craps simulation.
#include <iostream>
using std::cout;
using std::endl;
#include <cstdlib> // contains prototypes for functions srand and rand
using std::rand;
using std::srand;
#include <ctime> // contains prototype for function time
using std::time;
#include <iomanip>
using std::setw;

int rollDice(); // rolls dice, calculates amd displays sum

int craps()  // formerly main(); return number of rolls > 0 for win
{
   // enumeration with constants that represent the game status
   enum Status { CONTINUE, WON, LOST };
   int rolls=0;
   int myPoint; // point if no win or loss on first roll
   Status gameStatus; // can contain CONTINUE, WON or LOST

   int sumOfDice = rollDice(); // first roll of the dice
   rolls++;
   // determine game status and point (if needed) based on first roll
   switch ( sumOfDice ) 
   {
      case 7: // win with 7 on first roll
      case 11: // win with 11 on first roll           
         gameStatus = WON;
         break;
      case 2: // lose with 2 on first roll
      case 3: // lose with 3 on first roll
      case 12: // lose with 12 on first roll             
         gameStatus = LOST;
         break;
      default: // did not win or lose, so remember point
         gameStatus = CONTINUE; // game is not over
         myPoint = sumOfDice; // remember the point
      // cout << "Point is " << myPoint << endl;
         break; // optional at end of switch  
   } // end switch 

   // while game is not complete
   while ( gameStatus == CONTINUE ) // not WON or LOST
   { 
      sumOfDice = rollDice(); // roll dice again
      rolls++;
      // determine game status
      if ( sumOfDice == myPoint ) // win by making point
         gameStatus = WON;
      else
         if ( sumOfDice == 7 ) // lose by rolling 7 before point
            gameStatus = LOST;
   } // end while 

   // display won or lost message
   if ( gameStatus == WON )
   //   cout << "Player wins" << endl;
      return rolls;  // indicates win
   else
   //   cout << "Player loses" << endl;
      return -rolls; // indicates loss
} // end main

// roll dice, calculate sum and display results
int rollDice()
{
   // pick random die values
   int die1 = 1 + rand() % 6; // first die roll
   int die2 = 1 + rand() % 6; // second die roll
   
   int sum = die1 + die2; // compute sum of die values

   // display results of this roll
   // cout << "Player rolled " << die1 << " + " << die2
   //      << " = " << sum << endl;
   return sum; // return sum of dice
} // end function rollDice


/**************************************************************************
 * (C) Copyright 1992-2005 by Deitel & Associates, Inc. and               *
 * Pearson Education, Inc. All Rights Reserved.                           *
 *                                                                        *
 * DISCLAIMER: The authors and publisher of this book have used their     *
 * best efforts in preparing the book. These efforts include the          *
 * development, research, and testing of the theories and programs        *
 * to determine their effectiveness. The authors and publisher make       *
 * no warranty of any kind, expressed or implied, with regard to these    *
 * programs or to the documentation contained in these books. The authors *
 * and publisher shall not be liable in any event for incidental or       *
 * consequential damages in connection with, or arising out of, the       *
 * furnishing, performance, or use of these programs.                     *
 **************************************************************************/

int main()
{ 
// play 1000 games and accumulate results
   const int totalGames=1000;
   int i, rolls, totalWins=0, wins[21]={0}, losses[21]={0};
// randomize random number generator using current time
   srand( time( 0 ) ); 
   for (i=0; i<totalGames; i++)
   { if ((rolls=craps()) > 0) // player wins
       if (rolls >= 20) wins[20]++;
       else wins[rolls]++;
     else // player loses
     { rolls=-rolls; 
       if (rolls >= 20) losses[20]++;
       else losses[rolls]++;
     }
   }
   cout << "Rolls  Wins  Losses   Ratio" << endl;
   for (i=1; i<21; i++)
   { cout << setw(5) << i << setw(6) << wins[i] << setw(8) 
          << losses[i] << "  ";
     if (wins[i]+losses[i] > 0)  
       cout << setw(6) << ((float) wins[i])/(wins[i]+losses[i]);
     cout << endl;
     totalWins += wins[i];
   }
   cout << "Total wins = " << totalWins << ", Total games = " << totalGames
        << ", ratio = " << ((float) totalWins)/totalGames << endl;
}
/*
Mitchs-PBG412:~/CS/CS202/HWfall06/HW1 MGR$ g++ hw1_2.cpp
Mitchs-PBG412:~/CS/CS202/HWfall06/HW1 MGR$ ./a.out
Rolls  Wins  Losses   Ratio
    1   239     135  0.639037
    2    61      98  0.383648
    3    60      77  0.437956
    4    46      54    0.46
    5    20      46  0.30303
    6    14      29  0.325581
    7    13      19  0.40625
    8     5      10  0.333333
    9     6      13  0.315789
   10     8       8     0.5
   11     0      11       0
   12     1       6  0.142857
   13     2       3     0.4
   14     2       3     0.4
   15     0       3       0
   16     0       3       0
   17     0       0  
   18     1       3    0.25
   19     0       0  
   20     0       1       0
Total wins = 478, Total games = 1000, ratio = 0.478
Mitchs-PBG412:~/CS/CS202/HWfall06/HW1 MGR$ 
*/
