/** The ZeroOne game is a game played by two players.
 *  The players decide how many turns will be played in the
 *  game, and the maximum number of dice throws that can be
 *  made in a turn.
 *  For each turn, each player will throw the die until:
 *  either they throw a 1, or they choose to stop, or they have
 *  reached the maximum number of die throws that can be made in
 *  a turn ... whichever comes first.
 * 
 *  As long as they do not throw a 1, the number displayed on the 
 *  die will be added to the points total for that player's turn.  
 *  If they throw a 1, then they lose their turn, and they get 
 *  zero points (all of their accrued points for that turn are wiped
 *  out) for that turn.
 * 
 *  Design approach:
 *  Our design approach was top-down.  
 *  1) We determined all of the steps that would be required to play the game.
 *  2) We broke each logical step into a separate method.  In some cases, we didn't
 *     really need a method - but put one in for illustrative purposes.  Essentially
 *     methods should be created wherever duplicate code would be required, or
 *     for clarification purposes.
 *  3) We then put the steps in our main method. For each step we invoke a method, 
 *     and define the skeletons or stubs of our methods.  By the skeletons of 
 *     our methods, I mean we created the method header consisting of the return 
 *     type, the method name, and the parameters, as well as the return statement
 *     and, a return variable (initialized to zero or some other value).
 *  4) We then compiled our program.  What we now have is the basic structure or 
 *     framework for our program. 
 *  5) One by one, we then add the code for all of the methods that we have
 *     declared - compiling and testing it incrementally as we go.  We may have
 *     to change a few things, but our overall structure is fairly well defined.
 */
class ZeroOneGame {
  
  /** play the zero one game. */
  public static void main(String [] args) {
    // get player names
    String player1Name = getName(1); // name of first player
    String player2Name = getName(2); // name of second player
    // set game limits
    int maxTurns = getTurns(); // maximum number of turns per game
    int maxThrows = getThrows(); // maximum number of throws per turn
    boolean playAgain = true;
    // play as many games as they want
    do {
      int turnCount = 0, // declare and initialize turn count,
        player1Points = 0, // total number of points for the first player, and
        player2Points = 0; // total number of points 
      // now play out the turns for the game for each player.
      while (turnCount < maxTurns) {
        player1Points += takeTurn(player1Name, maxThrows);
        System.out.println(player1Name + ", you now have a total of " 
                             + player1Points
                             + " points");
        player2Points += takeTurn(player2Name, maxThrows);
        System.out.println(player2Name + ", you now have a total of " 
                             + player2Points 
                             + " points");
        turnCount++; // don't forget to increment or you will stay in a loop forever
      }
      // display the winner information
      declareWinner(player1Points, player2Points, player1Name, player2Name );
      System.out.print("Would you like to play again? (y = yes n = no)" );
    } while (isYes()); // note that we use a boolean return value as the value in our
                       // while condition
  }
  
  /** Get player's name.
   * @param pNum the player number - either 1 or 2.
   * @return the name of player pNum
   */
  public static String getName(int pNum) {
    System.out.print("Player " + pNum + ", what is your name? ");
    return In.getString();
    
  }
  
  /** Get the maximum throws per turn.
   *  @return the maxumum number of throws per turn 
   */
  public static int getThrows() {
    System.out.print("How many throws per turn?");
    return In.getInt();
  }
  /** Get the maximum number of turns per game.
   *  @return the maximum number of turns per game
   */
  public static int getTurns() {
    System.out.print("How many turns per game?");
    return In.getInt();
    
  }
  
  /** Take a turn. If the maximum number of rolls has not 
   *  been thrown, the user n is asked whether they wish
   *  to roll the die.  If they say yes, the die is rolled.
   *  If a one is rolled, then all points accrued in the 
   *  current turn are wiped out, and the points earned in
   *  in the turn are zero and the turn is ended.  
   *  If a value greater than one is thrown, then it is added
   *  to the points total for that turn, they may roll again, 
   *  and are prompted to do so.  The turn ends when either
   *  the player declines to roll again (in which case the
   *  points accrued are returned), or the maximum number of
   *  rolls has been reached (return accrued points) or a one 
   *  has been thrown (return zero points) ... whichever comes
   *  first.
   * @param n the name of the player
   * @param t the maximum number of throws per turn
   * @return the total points accrued for that turn as an int.
   */
  public static int takeTurn(String n, int t) {
    int points = 0;
    boolean keepGoing = true;
    int turns = 0;
    System.out.println("\nNow it's " + n + "'s turn!");
    while (turns < t && keepGoing) {
      int rollVal = roll(n);
      switch (rollVal) // this is a good application for a switch so I modified it
      {
        case 1: points = 0;
                System.out.println("Sorry ... you now have zero points and have lost your turn");
                // note that we want it to execute the next code so we omitted a break statement.
        case 0: keepGoing = false;
                break;
        default: points += rollVal;
                 turns++;
                 System.out.println("You have rolled " + points + " so far this turn");
                 break; 
      }

    }
     return points;
  }
  
  /** Ask the user if they want to roll the die, roll it if they do, and announce
   *  the value of each roll.  Note: pips are the little dots on a die.
   * @param name the name of the person who is rolling
   * @return the number of pips that are facing up for the roll of the die or zero if they
   *  do not roll the die.
   */
  public static int roll(String name) {
    int pipCount = 0;
    System.out.print("Would you like to roll now, " + name + " - you feeling lucky? (Y or N)");
    if  (isYes()){
      pipCount = (int)(Math.random() * 6) + 1;
      System.out.println("You have rolled a " + pipCount);
    }
    return pipCount;
  }    
  /** Display the results of the game.  First show the scores for each
   *  player, then announce the winner and congratulate them.
   *  Do we want to prompt to ask them if they want to play again here?
   * @param s1 the total points accrued for player 1
   * @param s2 the total points accrued for player 2
   * @param n1 the name of player 1
   * @param n2 the name of player 2
   */
  public static void declareWinner(int s1, int s2, String n1, String n2) {
    System.out.println("Points rolled this game ");
    System.out.println(n1 + ": " + s1);
    System.out.println(n2 + ": " + s2);
    if (s1 == s2) {
      System.out.println("It's a tie!");
    } else {
      String winner = "";
      if (s1 > s2) {
        winner = n1;
      } else {
        winner = n2;
      }
      System.out.println("Congratulations " + winner + "!!");
    }
    
  }
  /** get 'y' or 'n' from the user.  If the response is 'y' or 'Y', return
   *  true, otherwise, return false.
   *  @return if the user entered y or Y as a boolean.
   */
  public static boolean isYes() {
    char resp = In.getChar();
    return resp == 'y' || resp == 'Y';
  }  
}
