import java.util.Random;
import java.util.Scanner;


public class YahtzeeStudentP1 {

    // Default value when a category has not been used.
    final static int SCORE_NO_VALUE = -1;
    final static int YAHTZEE_SCORE = 50;
    final static int YAHTZEE_BONUS_SCORE = 100;
    final static String BORDER_CHAR = "*";
    final static String INVALID_INPUT_MESSAGE = "*** Invalid input ***";
    static int aces = SCORE_NO_VALUE;
    static int twos = SCORE_NO_VALUE;
    static int threes = SCORE_NO_VALUE;
    static int fours = SCORE_NO_VALUE;
    static int fives = SCORE_NO_VALUE;
    static int sixes = SCORE_NO_VALUE;
    static int threeKind = SCORE_NO_VALUE;
    static int fourKind = SCORE_NO_VALUE;
    static int fullHouse = SCORE_NO_VALUE;
    static int smallStraight = SCORE_NO_VALUE;
    static int largeStraight = SCORE_NO_VALUE;
    static int yahtzee = SCORE_NO_VALUE;
    static int yahtzeeBonusCount = SCORE_NO_VALUE;
    static int chance = SCORE_NO_VALUE;
    // Used to store the value of each die.
    static int die1;
    static int die2;
    static int die3;
    static int die4;
    static int die5;

    // Declare and initialize the trackers for number of turns and number of rolls per turn.
    static int turnCount = 0;
    static int numberOfRolls = 0;



    public static void main(String[] args) {

        //***
        //*** What is the purpose of these next two constants? How are they used?
        //***
        //*** The variable MAX_NUMBER_ON_DIE stores the maximum value on a die is 6 and this value is unchanged.
        //    So the variable is declared as a constant, to random the score for each roll.
        //***The variable MAX_NUMBER_ON_DIE stores the constant = 3 because the player has 3 times to roll per turn.
        //    Use this variable to check the number of times per turn.
        //***
        final int MAX_NUMBER_ON_DIE = 6;
        final int MAX_NUMBER_ROLLS = 3;

        final String WELCOME_MESSAGE = "Welcome to YAHTZEE";

        final String PRESS_ENTER_MESSAGE = "Press the Enter key to continue: ";

        final String REROLL_MESSAGE_1 = "Enter: S for ScoreCard; D for Dice; X to Exit";
        final String REROLL_MESSAGE_2 = "Or: A series of numbers to re-roll dice as follows:";
        final String REROLL_MESSAGE_3 = "\t\tYou may re-roll any of the dice by entering the die #s without spaces.";
        final String REROLL_MESSAGE_4 = "\t\tFor example, to re-roll dice #1, #3 & #4, enter 134 or enter 0 for none.";
        final String REROLL_MESSAGE_5 = "You have %d roll(s) left this turn.";
        final String REROLL_MESSAGE_6 = "Which of the dice would you like to roll again? ";

        final String CATEGORY_MESSAGE_1 = "Enter: 1-14 for category; S for ScoreCard; D for Dice; X to Exit";
        final String CATEGORY_MESSAGE_2 = "Which category would you like to choose? ";

        //***
        //*** What is the purpose of these next three boolean variables? How are they used?
        //***
        //*** Set the status of the variables, which make the condition for
        //    checking when out of turn, exit game, or complete game.
        //***
        boolean turnOver = false;
        boolean gameExit = false;
        boolean gameComplete = false;

        //***
        //*** What is the purpose of these next two variables? How are they used?
        //***
        //*** dice2Reroll variable to store the dice the player chooses to roll
        //   when doing loop, the values of dice2Reroll assign that value to die2Reroll.
        //   Then check the variable die2Reroll to random the dice the player wants.
        //***
        String dice2Reroll;
        char die2Reroll;

        //***
        //*** What is the purpose of these next two variables? How are they used?
        //***
        //*** scoreOption variable to store the value the player selected for the category.
        //    scoreOptionInput allows players to enter the option they want to score.
        //***
        int scoreOption = 0;
        String scoreOptionInput;

        Scanner input = new Scanner(System.in);

        // Use the current time as a seed for the random number generator.
        long seed = (new java.util.Date()).getTime();
        Random generator = new Random(seed);

        System.out.println();
        System.out.println(WELCOME_MESSAGE);

        //***
        //*** What is the main purpose of this do-while loop?
        //***
        //*** This do-while loop to count the turn, roll the dice and display the values of the dice after rolling
        //    until exit or complete game.
        //***
        do {
            System.out.println();
            System.out.print(PRESS_ENTER_MESSAGE);

            // Pause for the enter key.
            input.nextLine();

            // Keep track of the number of turns the player uses.
            turnCount++;

            // Roll the dice the first time.
            die1 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
            die2 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
            die3 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
            die4 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
            die5 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;

            // Keep track of the number of rolls per turn.
            numberOfRolls = 1;

            // Display the values of the dice after rolling.
            displayDice();

            //***
            //*** What is the main purpose of this do-while loop?
            //***
            //*** This do-while loop is used to reroll the dice, maximum is 3 time, or until the player want to end turn
            //***
            do {
                // Give the user the menu commands and instructions.
                System.out.println();
                System.out.println(REROLL_MESSAGE_1);
                System.out.println();

                System.out.println(REROLL_MESSAGE_2);
                System.out.println(REROLL_MESSAGE_3);
                System.out.println(REROLL_MESSAGE_4);

                System.out.println();
                System.out.printf(REROLL_MESSAGE_5, (MAX_NUMBER_ROLLS - numberOfRolls));
                System.out.println();

                System.out.println();
                System.out.print(REROLL_MESSAGE_6);

                // Collect the user's input response of which command or which dice to reroll.
                dice2Reroll = input.nextLine().trim();

                //***
                //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
                //***
                //*** Write a switch statement on variable "dice2Reroll" using the "toUpperCase" method
                //*** The cases being "X", "S", "D", "0", and ""
                //***    when case "X", set variable "turnOver" to true and variable "gameExit" to true
                //***    when case "S", call method "displayScoreSheet" passing no arguments
                //***    when case "D", call method "displayDice" passing no arguments
                //***    when case "0", set variable "turnOver" to true
                //***    when case "", call method "displayErrorMessage" passing no arguments
                //***
                //*** Include a break statement for every case.
                //***

                //***
                //*** Your switch statement and case clauses go here.
                switch (dice2Reroll.toUpperCase()) {
                    case "X":
                        turnOver = true;
                        gameExit = true;
                        break;
                    case "S":
                        displayScoreSheet();
                        break;
                    case "D":
                        displayDice();
                        break;
                    case "0":
                        turnOver = true;
                    case "":
                        displayErrorMessage();
                        break;
                    default:
                        // Only allow numbers between 1-5 and no numbers can repeat
                        String checkDice2Reroll = dice2Reroll;
                        checkDice2Reroll = checkDice2Reroll.replaceFirst("1", " ");
                        checkDice2Reroll = checkDice2Reroll.replaceFirst("2", " ");
                        checkDice2Reroll = checkDice2Reroll.replaceFirst("3", " ");
                        checkDice2Reroll = checkDice2Reroll.replaceFirst("4", " ");
                        checkDice2Reroll = checkDice2Reroll.replaceFirst("5", " ");

                        if (checkDice2Reroll.isBlank()) {

                            //***
                            //*** What is the purpose of this for-loop?
                            //***
                            //*** This for-loop is used to loop the list of dice the player entered and reroll them.
                            //***
                            for (int i = 0; i < dice2Reroll.length(); i++) {
                                die2Reroll = dice2Reroll.charAt(i);

                                //***
                                //*** What is the purpose of this switch statement?
                                //***
                                //*** This switch statement to roll the dice which the player wants to reroll.
                                //***
                                switch (die2Reroll) {
                                    case '1':
                                        die1 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
                                        break;
                                    case '2':
                                        die2 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
                                        break;
                                    case '3':
                                        die3 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
                                        break;
                                    case '4':
                                        die4 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
                                        break;
                                    case '5':
                                        die5 = generator.nextInt(MAX_NUMBER_ON_DIE) + 1;
                                        break;
                                }
                            }


                            // This was a valid roll of the dice so count it.
                            numberOfRolls++;

                            // Display the values of the dice after rolling.
                            displayDice();

                            // If this roll of the dice reaches the max threshold for number of rolls
                            //     then end the player's turn so that they can choose which category
                            //     to use to score.
                            if (numberOfRolls == MAX_NUMBER_ROLLS){
                                turnOver = true;
                            }
                            // The user entered invalid input when prompted for which dice to reroll.
                            // So display an error message.
                            else {
                                displayErrorMessage();
                            }
                        }
                        //***

                        //***
                        //*** Uncomment the following default clause and attach to the switch statement that you write above.
                        //***


                        // When checkDice2Reroll is blank, the user entered valid dice to reroll.
                        // Conversely, when checkDice2Reroll is not blank, the user entered invalid dice to reroll.

                        //***
                        //*** Explain why these last two comments are true.
                        //*** In other words, what is variable "checkDice2Reroll", what does method "replaceFirst"
                        //***     above do and why is it being used? tim va thay the chuoi con dau tien trong chuoi ban dau
                        //*** What might be contained in variable "checkDice2Reroll" when the user input is invalid?
                        //***
                        //*** They are true because variable "checkDice2Reroll" to check the user entered invalid dice
                        //    to reroll. The method "replaceFirst" is used to replace numbers in
                        //    the string checkDice2Reroll to be blank
                        //    variable "checkDice2Reroll" might be contained a string which the user entered.

                        //***


                        //*** This is the closing curly brace for your switch statement.


                }
            } while (!turnOver);

            //***
            //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
            //***
            //*** Write an if-statement with the condition of ("not" gameExit).
            //***     Use the correct Java syntax for the "not" operator.
            //*** Code block for if-statement:
            //***     Set variable "turnOver" to false.
            //***     Call method "displayScoreSheet" passing no arguments.
            //***     Define three boolean variables named "isValidEntry", "categoryPicked" and "continuePrompting".
            //***     Write a do-while loop statement with the corresponding while clause having
            //***         the condition (continuePrompting). This do-while loop is nested inside the if-statement.
            //***     Code block for do-while loop:
            //***         Set variable "isValidEntry" to true.
            //***         Set variable "categoryPicked" to false.
            //***

            //***
            //*** Your if-statement, if-statement code block, do statement and do statement code block here.
            if (!gameExit) {
                turnOver = false;
                displayScoreSheet();
                boolean isValidEntry;
                boolean categoryPicked;
                boolean continuePrompting;
                do {
                    isValidEntry = true;
                    categoryPicked = false;
                    System.out.println();
                    System.out.println(CATEGORY_MESSAGE_1);
                    System.out.println();

                    System.out.print(CATEGORY_MESSAGE_2);
                    scoreOptionInput = input.nextLine().trim();
                    scoreOption = 0;
                    switch (scoreOptionInput.toUpperCase()) {
                        case "X":
                            isValidEntry = true;
                            gameExit = true;
                            break;
                        case "S":
                            isValidEntry = true;
                            displayScoreSheet();
                            break;
                        case "D":
                            isValidEntry = true;
                            displayDice();
                            break;
                        case "":
                            displayErrorMessage();
                            break;
                        default:

                            //***
                            //*** What is the purpose of this for-loop and if-statement?
                            //***
                            //*** It is used to check if the player enter is a digit or not.
                            //***
                            for (int x = 0; x < scoreOptionInput.length(); x++)
                                if (!(Character.isDigit(scoreOptionInput.charAt(x)))) {
                                    isValidEntry = false;
                                    displayErrorMessage();
                                }

                            //***
                            //*** What is the purpose of these two if-statements?
                            //***
                            //*** It is used to check isValidEntry variable.
                            //    Then, if it is true, it will check if the scoreOption between 1 and 14
                            //***
                            if (isValidEntry) {
                                scoreOption = Integer.parseInt(scoreOptionInput);
                                if (scoreOption < 1 || scoreOption > 14) {
                                    isValidEntry = false;
                                    displayErrorMessage();
                                }
                            }

                            // The user entered a valid category to score however the category
                            //     was already used by the player.
                            // Categories can only be used once
                            if (isValidEntry && isCategoryUsed(scoreOption)) {
                                isValidEntry = false;
                                displayErrorMessage();
                            }

                            // If the user's input passes all checks then calculate the new score
                            //     display the current score sheet and determine if the game is over.
                            if (isValidEntry) {
                                categoryPicked = true;
                                calculateTurnScore(scoreOption);
                                displayScoreSheet();
                                gameComplete = isGameOver();
                            }
                    }

                    //***
                    //*** What does it mean to "continuePrompting"?
                    //*** In other words, describe under what conditions that variable "continuePrompting"
                    //***     is true and false.
                    //***
                    //*** Your comments here -
                    //***
                    continuePrompting = !gameExit && (!isValidEntry || !categoryPicked);

                    //*** Your while clause with condition (continuePrompting) goes here.
                } while (continuePrompting);
            } //*** This is the closing curly brace for your if-statement.


            //***

            //***
            //*** Uncomment the following six lines of code and
            //***     insert this code after the code that sets variable "categoryPicked" which is
            //***     inside your do-while loop. done
            //***





            //***
            //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
            //***
            //*** Write a switch statement on variable "scoreOptionInput" using the "toUpperCase" method.
            //*** The cases being "X", "S", "D", "0", and ""
            //***     when case "X":
            //***         1) set variable "isValidEntry" to true
            //***         2) set variable "gameExit" to true
            //***     when case "S":
            //***         1) set variable "isValidEntry" to true
            //***         2) call method "displayScoreSheet" passing no arguments
            //***     when case "D":
            //***         1) set variable "isValidEntry" to true
            //***         2) call method "displayDice" passing no arguments
            //***     when case "":
            //***         1) call method "displayErrorMessage" passing no arguments
            //***
            //*** Include a break statement for every case.
            //***
            //*** This switch structure is nested inside your do-while loop.
            //***

            //***
            //*** Your switch statement and case clauses go here. done

            //***

            //***
            //*** Uncomment the following default clause and attach to the switch statement that you write above.
            //***


        } while (!gameExit && !gameComplete);
        // Display the current score sheet.
        displayScoreSheet();
    }


    public static void displayDice() {

        final String DIE_1_LABEL = "Die #1 = ";
        final String DIE_2_LABEL = "Die #2 = ";
        final String DIE_3_LABEL = "Die #3 = ";
        final String DIE_4_LABEL = "Die #4 = ";
        final String DIE_5_LABEL = "Die #5 = ";

        System.out.println();

        System.out.print(DIE_1_LABEL);
        System.out.println(" (" + (die1) + ")");

        System.out.print(DIE_2_LABEL);
        System.out.println(" (" + (die2) + ")");

        System.out.print(DIE_3_LABEL);
        System.out.println(" (" + (die3) + ")");

        System.out.print(DIE_4_LABEL);
        System.out.println(" (" + (die4) + ")");

        System.out.print(DIE_5_LABEL);
        System.out.println(" (" + (die5) + ")");

        System.out.println();
    }

    public static void displayScoreSheet() {

        final String ACES_LABEL = "Aces";
        final String TWOS_LABEL = "Twos";
        final String THREES_LABEL = "Threes";
        final String FOURS_LABEL = "Fours";
        final String FIVES_LABEL = "Fives";
        final String SIXES_LABEL = "Sixes";

        final String THREE_KIND_LABEL = "3 of a kind";
        final String FOUR_KIND_LABEL = "4 of a kind";
        final String FULL_HOUSE_LABEL = "Full House";
        final String SMALL_STRAIGHT_LABEL = "Sm. Straight";
        final String LARGE_STRAIGHT_LABEL = "Lg. Straight";
        final String YAHTZEE_LABEL = "YAHTZEE";
        final String CHANCE_LABEL = "Chance";
        final String YAHTZEE_BONUS_LABEL = "YAHTZEE BONUS";

        final int BONUS_THRESHOLD = 63;
        final int BONUS_SCORE = 35;

        final String UPPER_SECTION_LABEL = "UPPER SECTION";
        final String LOWER_SECTION_LABEL = "LOWER SECTION";
        final String UPPER_SECTION_SUBTOTAL_LABEL = "TOTAL SCORE";
        final String UPPER_SECTION_BONUS_LABEL = "BONUS if >= 63";
        final String UPPER_SECTION_TOTAL_LABEL = "TOTAL of Upper Section";
        final String LOWER_SECTION_TOTAL_LABEL = "TOTAL of Lower Section";
        final String GRAND_TOTAL_LABEL = "GRAND TOTAL";

        final String OPTION_SUFFIX_ONE_DIGIT = ")  ";
        final String OPTION_SUFFIX_TWO_DIGIT = ") ";

        final String FIRST_OPTION_LABEL = "1";
        final String SECOND_OPTION_LABEL = "2";
        final String THIRD_OPTION_LABEL = "3";
        final String FOURTH_OPTION_LABEL = "4";
        final String FIFTH_OPTION_LABEL = "5";
        final String SIXTH_OPTION_LABEL = "6";
        final String SEVENTH_OPTION_LABEL = "7";
        final String EIGHTH_OPTION_LABEL = "8";
        final String NINTH_OPTION_LABEL = "9";
        final String TENTH_OPTION_LABEL = "10";
        final String ELEVENTH_OPTION_LABEL = "11";
        final String TWELFTH_OPTION_LABEL = "12";
        final String THIRTEENTH_OPTION_LABEL = "13";
        final String FOURTEENTH_OPTION_LABEL = "14";

        final String EQUALS_LABEL = " = ";


        //***
        //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
        //***
        //*** Declare an int variable named "upperScoreTotal".
        //***     Call method "calculateUpperScore" passing no arguments and assign to "upperScoreTotal"
        //*** Declare an int variable named "lowerScoreTotal"
        //***     Call method "calculateLowerScore" passing no arguments and assign to "lowerScoreTotal"
        //***

        //***
        //*** Your code goes here.
        int upperScoreTotal;
        upperScoreTotal = calculateUpperScore();
        int lowerScoreTotal;
        lowerScoreTotal = calculateLowerScore();
        //***

        System.out.println();
        System.out.println(UPPER_SECTION_LABEL);

        // Option 1 = Aces
        if (aces == SCORE_NO_VALUE)
            System.out.println(FIRST_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + ACES_LABEL);
        else
            System.out.println(FIRST_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + ACES_LABEL + EQUALS_LABEL + aces);

        //***
        //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
        //***
        //*** Following the form of the if-statement-block for option Aces, write five (5) if-statement-blocks
        //***     that checks the following variables:
        //***         "twos", "threes", "fours", "fives" and "sixes"
        //***     for "equality to" SCORE_NO_VALUE.
        //***     Use the correct Java syntax for the "equality" operator.
        //***
        //*** Don't forget to use the different OPTION_LABEL constants.
        //*** Comment your code following the comment given for Aces. Include the option number and option name.
        //***

        //***
        //*** Your code goes here.
        //***
        if (twos == SCORE_NO_VALUE)
            System.out.println(SECOND_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + TWOS_LABEL);
        else
            System.out.println(SECOND_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + TWOS_LABEL + EQUALS_LABEL + twos);
        if (threes == SCORE_NO_VALUE)
            System.out.println(THIRD_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + THREES_LABEL);
        else
            System.out.println(THIRD_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + THREES_LABEL + EQUALS_LABEL + threes);
        if (fours == SCORE_NO_VALUE)
            System.out.println(FOURTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FOURS_LABEL);
        else
            System.out.println(FOURTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FOURS_LABEL + EQUALS_LABEL + fours);
        if (fives == SCORE_NO_VALUE)
            System.out.println(FIFTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FIVES_LABEL);
        else
            System.out.println(FIFTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FIVES_LABEL + EQUALS_LABEL + fives);
        if (sixes == SCORE_NO_VALUE)
            System.out.println(SIXTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + SIXES_LABEL);
        else
            System.out.println(SIXTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + SIXES_LABEL + EQUALS_LABEL + sixes);
        // Upper section score subtotal
        if (upperScoreTotal > 0)
            System.out.println(UPPER_SECTION_SUBTOTAL_LABEL + EQUALS_LABEL + upperScoreTotal);
        else
            System.out.println(UPPER_SECTION_SUBTOTAL_LABEL);

        // Upper section score bonus
        if (upperScoreTotal >= BONUS_THRESHOLD)
            System.out.println(UPPER_SECTION_BONUS_LABEL + EQUALS_LABEL + BONUS_SCORE);
        else
            System.out.println(UPPER_SECTION_BONUS_LABEL);

        // Upper section score total
        if (upperScoreTotal > 0)
            if (upperScoreTotal >= BONUS_THRESHOLD)
                System.out.println(UPPER_SECTION_TOTAL_LABEL + EQUALS_LABEL + (upperScoreTotal + BONUS_SCORE));
            else
                System.out.println(UPPER_SECTION_TOTAL_LABEL + EQUALS_LABEL + upperScoreTotal);
        else
            System.out.println(UPPER_SECTION_TOTAL_LABEL);

        System.out.println();
        System.out.println(LOWER_SECTION_LABEL);

        //***
        //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
        //***
        //*** Following the form of the if-statement-block for option Aces, write eight (8) if-statement-blocks
        //***     that checks the following variables:
        //***         "threeKind", "fourKind", "fullHouse", "smallStraight", "largeStraight", "yahtzee", "chance" and
        //***         "yahtzeeBonusCount"
        //***     for "equality to" SCORE_NO_VALUE.
        //***     Use the correct Java syntax for the "equality" operator.
        //***
        //*** Don't forget to use the different OPTION_LABEL constants.
        //*** Starting with the tenth option, use OPTION_SUFFIX_TWO_DIGIT for good text alignment.
        //*** When displaying the scoring amount for yahtzee bonuses, use the following calculation:
        //***     (yahtzeeBonusCount * YAHTZEE_BONUS_SCORE)
        //*** Comment your code following the comment given for Aces, including the option number and option name.
        //***

        //***
        //*** Your code goes here.
        if (threeKind == SCORE_NO_VALUE)
            System.out.println(SEVENTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + THREE_KIND_LABEL);
        else
            System.out.println(SEVENTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + THREE_KIND_LABEL + EQUALS_LABEL + threeKind);
        if (fourKind == SCORE_NO_VALUE)
            System.out.println(EIGHTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FOUR_KIND_LABEL);
        else
            System.out.println(EIGHTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FOUR_KIND_LABEL + EQUALS_LABEL + fourKind);
        if (fullHouse == SCORE_NO_VALUE)
            System.out.println(NINTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FULL_HOUSE_LABEL);
        else
            System.out.println(NINTH_OPTION_LABEL + OPTION_SUFFIX_ONE_DIGIT + FULL_HOUSE_LABEL + EQUALS_LABEL + fullHouse);
        if (smallStraight == SCORE_NO_VALUE)
            System.out.println(TENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + SMALL_STRAIGHT_LABEL);
        else
            System.out.println(TENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + SMALL_STRAIGHT_LABEL + EQUALS_LABEL + smallStraight);
        if (largeStraight == SCORE_NO_VALUE)
            System.out.println(ELEVENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + LARGE_STRAIGHT_LABEL);
        else
            System.out.println(ELEVENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + LARGE_STRAIGHT_LABEL + EQUALS_LABEL + largeStraight);
        if (yahtzee == SCORE_NO_VALUE)
            System.out.println(TWELFTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + YAHTZEE_LABEL);
        else
            System.out.println(TWELFTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + YAHTZEE_LABEL + EQUALS_LABEL + yahtzee);
        if (chance == SCORE_NO_VALUE)
            System.out.println(THIRTEENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + CHANCE_LABEL);
        else
            System.out.println(THIRTEENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + CHANCE_LABEL + EQUALS_LABEL + chance);
        if (yahtzeeBonusCount == SCORE_NO_VALUE)
            System.out.println(FOURTEENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + YAHTZEE_BONUS_LABEL);
        else
            System.out.println(FOURTEENTH_OPTION_LABEL + OPTION_SUFFIX_TWO_DIGIT + YAHTZEE_BONUS_LABEL + EQUALS_LABEL + yahtzeeBonusCount);
        //***

        // Lower section score total
        if (lowerScoreTotal > 0)
            System.out.println(LOWER_SECTION_TOTAL_LABEL + EQUALS_LABEL + lowerScoreTotal);
        else
            System.out.println(LOWER_SECTION_TOTAL_LABEL);

        // Upper section score total
        if (upperScoreTotal > 0)
            if (upperScoreTotal >= BONUS_THRESHOLD)
                System.out.println(UPPER_SECTION_TOTAL_LABEL + EQUALS_LABEL + (upperScoreTotal + BONUS_SCORE));
            else
                System.out.println(UPPER_SECTION_TOTAL_LABEL + EQUALS_LABEL + upperScoreTotal);
        else
            System.out.println(UPPER_SECTION_TOTAL_LABEL);

        // Grand total
        if (upperScoreTotal + lowerScoreTotal > 0)
            System.out.println(GRAND_TOTAL_LABEL + EQUALS_LABEL + (upperScoreTotal + lowerScoreTotal));
        else
            System.out.println(GRAND_TOTAL_LABEL);

        System.out.println();
    }

    public static void calculateTurnScore(int scoreOption) {

        //***
        //*** INSTRUCTIONS FOR CODE FOR YOU TO WRITE
        //***
        //*** Write a switch statement on variable scoreOption
        //*** The cases being 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
        //***
        //*** In the code block for cases 1, 2, 3, 4, 5, and 6,
        //***     call method "calculateUpperSectionCategory" passing variable "scoreOption"
        //***     as an argument and assign the call to variable "aces".
        //***
        //*** In the code block for case 7, call method "calculateThreeOfKind"
        //***     passing no arguments and assign the call to variable "threeKind".
        //***
        //*** In the code block for case 8, call method "calculateFourOfKind"
        //***     passing no arguments and assign the call to variable "fourKind".
        //***
        //*** In the code block for case 9, call method "calculateFullHouse"
        //***     passing no arguments and assign the call to variable "fullHouse".
        //***
        //*** In the code block for case 10, call method "calculateSmallStraight"
        //***     passing no arguments and assign the call to variable "smallStraight".
        //***
        //*** In the code block for case 11, call method "calculateLargeStraight"
        //***     passing no arguments and assign the call to variable "largeStraight".
        //***
        //*** In the code block for case 12:
        //***     1) Call method "calculateYahtzee" passing no arguments and
        //***            assign the call to variable "yahtzee".
        //***     2) Write an if-statement with the condition (yahtzee "not equal to" YAHTZEE_SCORE)
        //***            Use the correct Java syntax for the "not equal to" operator.
        //***     3) Write a statement that assigns the value of zero to variable "yahtzeeBonusCount" if
        //***            the condition in step 2 evaluates to true.
        //***
        //*** In the code block for case 13, call method "calculateChance"
        //***     passing no arguments and assign the call to variable "chance".
        //***
        //*** In the code block for case 14,
        //***     1) Write an if-statement that checks the variable "yahtzee" for "equality to" SCORE_NO_VALUE.
        //***            Use the correct Java syntax for the "equality" operator.
        //***     2) Write a statement that calls method "calculateYahtzee" passing no arguments and assigns
        //***            the call to variable "yahtzee" if the condition in step 1 evaluates to true.
        //***     3) Write an if-statement that is nested in the if-statement from step 1 and checks the
        //***            condition (yahtzee "not equal to" YAHTZEE_SCORE).
        //***            Use the correct Java syntax for the "not equal to" operator.
        //***     4) Write a statement that assigns the value of zero to variable "yahtzeeBonusCount" if
        //***            the condition in step 3 evaluates to true.
        //***     5) Write an else-if-statement that is matched to the if-statement in step 1 that checks the
        //***            variable "yahtzee" for "equality to" YAHTZEE_SCORE.
        //***            Use the correct Java syntax for the "equality" operator.
        //***     6) Write a statement that increases the variable "yahtzeeBonusCount" by one if
        //***            the condition in step 5 evaluates to true.
        //***
        //*** Include a break statement for every case.
        //***

        //***
        //*** Your code goes here.
        switch (scoreOption) {
            case 1:
                aces = calculateUpperSectionCategory(scoreOption);
                break;
            case 2:
                twos = calculateUpperSectionCategory(scoreOption);
                break;
            case 3:
                threes = calculateUpperSectionCategory(scoreOption);
                break;
            case 4:
                fours = calculateUpperSectionCategory(scoreOption);
                break;
            case 5:
                fives = calculateUpperSectionCategory(scoreOption);
                break;
            case 6:
                sixes = calculateUpperSectionCategory(scoreOption);
                break;
            case 7:
                threeKind = calculateThreeOfKind();
                break;
            case 8:
                fourKind = calculateFourOfKind();
                break;
            case 9:
                fullHouse = calculateFullHouse();
                break;
            case 10:
                smallStraight = calculateSmallStraight();
                break;
            case 11:
                largeStraight = calculateLargeStraight();
                break;
            case 12:
                yahtzee = calculateYahtzee();
                if (yahtzee != YAHTZEE_SCORE) {
                    yahtzeeBonusCount = 0;
                }
                break;
            case 13:
                chance = calculateChance();
                break;
            case 14:
                if (yahtzee == SCORE_NO_VALUE) {
                    yahtzee = calculateYahtzee();
                    if (yahtzee != YAHTZEE_SCORE) {
                        yahtzeeBonusCount = 0;
                    }
                }
                if (yahtzee == YAHTZEE_SCORE) {
                    yahtzeeBonusCount += 1;
                }

                //***

        }
    }
    //***
    //*** Write a public static method named "calculateUpperSectionCategory" that
    //***    returns int and that receives an int parameter named "dieNumber".
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Write a println statement that displays the message "In method calculateUpperSectionCategory".
    //***    3) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateUpperSectionCategory(int dieNumber){
        int score = 0;
        System.out.println("In method calculateUpperSectionCategory");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateThreeOfKind" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isThreeKind" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateThreeOfKind".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateThreeOfKind() {
        int score = 0;
        boolean isThreeKind = false;
        System.out.println("In method calculateThreeOfKind");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateFourOfKind" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isFourKind" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateFourOfKind".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateFourOfKind() {
        int score = 0;
        boolean isFourKind = false;
        System.out.println("In method calculateFourOfKind");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateFullHouse" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isFullHouse" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateFullHouse".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateFullHouse() {
        int score = 0;
        boolean isFullHouse = false;
        System.out.println("In method calculateFullHouse");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateSmallStraight" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isSmallStraight" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateSmallStraight".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateSmallStraight() {
        int score = 0;
        boolean isSmallStraight = false;
        System.out.println("In method calculateSmallStraight");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateLargeStraight" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isLargeStraight" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateLargeStraight".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateLargeStraight() {
        int score = 0;
        boolean isLargeStraight = false;
        System.out.println("In method calculateLargeStraight");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateYahtzee" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Declare a boolean variable named "isYahtzee" and assign the value of false to it.
    //***    3) Write a println statement that displays the message "In method calculateYahtzee".
    //***    4) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateYahtzee() {
        int score = 0;
        boolean isYahtzee = false;
        System.out.println("In method calculateYahtzee");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateChance" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Write a println statement that displays the message "In method calculateChance".
    //***    2) Write a return statement that returns the value of zero. You can hard-code this zero.
    //***

    //***
    //*** Your method code goes here.
    public static int calculateChance() {
        System.out.println("In method calculateChance");
        return 0;
    }
    //***


    //***
    //*** Write a public static method named "calculateUpperScore" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Write a println statement that displays the message "In method calculateUpperScore".
    //***    3) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateUpperScore() {
        int score = 0;
        System.out.println("In method calculateUpperScore");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "calculateLowerScore" that
    //***    returns int and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare an int variable named "score" and assign the value of zero to it.
    //***    2) Write a println statement that displays the message "In method calculateLowerScore".
    //***    3) Write a return statement that returns the variable "score".
    //***

    //***
    //*** Your method code goes here.
    public static int calculateLowerScore() {
        int score = 0;
        System.out.println("In method calculateLowerScore");
        return score;
    }
    //***


    //***
    //*** Write a public static method named "isCategoryUsed" that
    //***    returns boolean and receives an int parameter named "scoreOption".
    //***
    //*** Write the method body code as follows:
    //***    1) Declare a boolean variable named "used" and assign the value of false to it.
    //***    2) Write a println statement that displays the message "In method isCategoryUsed".
    //***    3) Write a return statement that returns the variable "used".
    //***

    //***
    //*** Your method code goes here.
    public static boolean isCategoryUsed(int scoreOption) {
        boolean used = false;
        System.out.println("In method isCategoryUsed");
        return used;
    }
    //***


    //***
    //*** Write a public static method named "isGameOver" that
    //***    returns boolean and receives no parameters.
    //***
    //*** Write the method body code as follows:
    //***    1) Declare a boolean variable named "gameOver" and assign the value of false to it.
    //***    2) Write an if-statement that checks the following thirteen (13) variables for "equality to" SCORE_NO_VALUE.
    //***           Use the correct Java syntax for the "equality" operator.
    //***           Join the thirteen (13) conditions together using the "OR" operator.
    //***           Use the correct Java syntax for the "OR" operator.
    //***    3) Write a statement that assigns the value of false to the variable "gameOver" if the condition
    //***           in step 2 evaluates to true
    //***    4) Write an else-statement that is matched to the if-statement in step 2 that
    //***           assigns the value of true to the variable "gameOver"
    //***    5) Write a return statement that returns the variable "gameOver".
    //***

    //***
    //*** Your method code goes here.
    public static boolean isGameOver() {
        boolean gameOver = false;
        if (aces == SCORE_NO_VALUE ||
                twos == SCORE_NO_VALUE ||
                threes == SCORE_NO_VALUE ||
                fours == SCORE_NO_VALUE ||
                fives == SCORE_NO_VALUE ||
                sixes == SCORE_NO_VALUE ||
                threeKind == SCORE_NO_VALUE ||
                fourKind == SCORE_NO_VALUE ||
                fullHouse == SCORE_NO_VALUE ||
                smallStraight == SCORE_NO_VALUE ||
                largeStraight == SCORE_NO_VALUE ||
                yahtzee == SCORE_NO_VALUE ||
                chance == SCORE_NO_VALUE) {
            gameOver = false;
        } else {
            gameOver = true;
        }

        return gameOver;
    }
    //***


    //***
    //*** What is the purpose of this method?
    //*** What is BORDER_CHAR? What is "repeat" doing with respect to BORDER_CHAR?
    //***
    //*** This method is used to display error message. BORDER_CHAR is " * ".
    // Repeats the number of asterisks corresponding to the length of the error message.
    // Example: error message: abc ouput: ***
    //***
    public static void displayErrorMessage() {
        System.out.println();
        System.out.println(BORDER_CHAR.repeat(INVALID_INPUT_MESSAGE.length()));
        System.out.println(INVALID_INPUT_MESSAGE);
        System.out.println(BORDER_CHAR.repeat(INVALID_INPUT_MESSAGE.length()));
    }
} 

Java online compiler

Write, Run & Share Java code online using OneCompiler's Java online compiler for free. It's one of the robust, feature-rich online compilers for Java language, running the Java LTS version 17. Getting started with the OneCompiler's Java editor is easy and fast. The editor shows sample boilerplate code when you choose language as Java and start coding.

Taking inputs (stdin)

OneCompiler's Java online editor supports stdin and users can give inputs to the programs using the STDIN textbox under the I/O tab. Using Scanner class in Java program, you can read the inputs. Following is a sample program that shows reading STDIN ( A string in this case ).

import java.util.Scanner;
class Input {
    public static void main(String[] args) {
    	Scanner input = new Scanner(System.in);
    	System.out.println("Enter your name: ");
    	String inp = input.next();
    	System.out.println("Hello, " + inp);
    }
}

Adding dependencies

OneCompiler supports Gradle for dependency management. Users can add dependencies in the build.gradle file and use them in their programs. When you add the dependencies for the first time, the first run might be a little slow as we download the dependencies, but the subsequent runs will be faster. Following sample Gradle configuration shows how to add dependencies

apply plugin:'application'
mainClassName = 'HelloWorld'

run { standardInput = System.in }
sourceSets { main { java { srcDir './' } } }

repositories {
    jcenter()
}

dependencies {
    // add dependencies here as below
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
}

About Java

Java is a very popular general-purpose programming language, it is class-based and object-oriented. Java was developed by James Gosling at Sun Microsystems ( later acquired by Oracle) the initial release of Java was in 1995. Java 17 is the latest long-term supported version (LTS). As of today, Java is the world's number one server programming language with a 12 million developer community, 5 million students studying worldwide and it's #1 choice for the cloud development.

Syntax help

Variables

short x = 999; 			// -32768 to 32767
int   x = 99999; 		// -2147483648 to 2147483647
long  x = 99999999999L; // -9223372036854775808 to 9223372036854775807

float x = 1.2;
double x = 99.99d;

byte x = 99; // -128 to 127
char x = 'A';
boolean x = true;

Loops

1. If Else:

When ever you want to perform a set of operations based on a condition If-Else is used.

if(conditional-expression) {
  // code
} else {
  // code
}

Example:

int i = 10;
if(i % 2 == 0) {
  System.out.println("i is even number");
} else {
  System.out.println("i is odd number");
}

2. Switch:

Switch is an alternative to If-Else-If ladder and to select one among many blocks of code.

switch(<conditional-expression>) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 //code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition. Usually for loop is preferred when number of iterations is known in advance.

for(Initialization; Condition; Increment/decrement){  
    //code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(<condition>){  
 // code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (<condition>); 

Classes and Objects

Class is the blueprint of an object, which is also referred as user-defined data type with variables and functions. Object is a basic unit in OOP, and is an instance of the class.

How to create a Class:

class keyword is required to create a class.

Example:

class Mobile {
    public:    // access specifier which specifies that accessibility of class members 
    string name; // string variable (attribute)
    int price; // int variable (attribute)
};

How to create a Object:

Mobile m1 = new Mobile();

How to define methods in a class:

public class Greeting {
    static void hello() {
        System.out.println("Hello.. Happy learning!");
    }

    public static void main(String[] args) {
        hello();
    }
}

Collections

Collection is a group of objects which can be represented as a single unit. Collections are introduced to bring a unified common interface to all the objects.

Collection Framework was introduced since JDK 1.2 which is used to represent and manage Collections and it contains:

  1. Interfaces
  2. Classes
  3. Algorithms

This framework also defines map interfaces and several classes in addition to Collections.

Advantages:

  • High performance
  • Reduces developer's effort
  • Unified architecture which has common methods for all objects.
CollectionDescription
SetSet is a collection of elements which can not contain duplicate values. Set is implemented in HashSets, LinkedHashSets, TreeSet etc
ListList is a ordered collection of elements which can have duplicates. Lists are classified into ArrayList, LinkedList, Vectors
QueueFIFO approach, while instantiating Queue interface you can either choose LinkedList or PriorityQueue.
DequeDeque(Double Ended Queue) is used to add or remove elements from both the ends of the Queue(both head and tail)
MapMap contains key-values pairs which don't have any duplicates. Map is implemented in HashMap, TreeMap etc.