简体   繁体   中英

Java do while Guessing Game

So for an assignment I had to do last week I had to make a guessing game in Java using 4 do-while loops and if statements. I was unable to complete it successfully and the class has moved on providing me no help. I would appreciate it if someone could look at my code and tell me where I could improve it so the program works properly.

To give a brief description of the assignment, the assignment calls for 4 do-while loops:

  1. The primary do-while loop which contains most of the code and keeps the program running until the user wants to quit
  2. The game do-while loop which keeps the game running until the user guesses the correct number, at which point it will exit. (This part I could not figure out).
  3. A numeric input validation do-while loop inside of the game loop, which makes sure the user's guess is valid.
  4. A non-numeric input validation do-while loop which is after and outside of the game loop that asks the user if they want to play again, and checks for a valid 'Y' or 'N' response

Here is what I came up with:

package week4;

//Imports
import java.lang.Math;
import java.util.Scanner;


public class Lab4d {
    public static void main(String[] args) {

        //Set up scanners
        Scanner again = new Scanner(System.in);
        Scanner num1 = new Scanner(System.in);

        //Set up variables
        int userInput = 0;
        int guesses = 0;
        int min = 1;
        int max = 100;
        int range = max - min + 1;
        int randNum = (int)(Math.random() * range) + min;
        boolean valid = false;

        //Outside loop
        do{
            //Describe the game
            System.out.println("\nThis program is a guessing game.");
            System.out.println("\nThe computer will pick a random number "
                               + "between 1 and 100.");
            System.out.println("\nYou will try to guess it.");
            System.out.println("\nLet's play!");

            //Insert Game loop here
            do {
                System.out.println("\nI'm thinking of a number " +
                                   "between 1 and 100.");
                //Insert valid guess checker here
                do {
                    System.out.println("Please enter your guess: ");
                    if (num1.hasNextInt()){
                        userInput = num1.nextInt();
                        valid = true;
                    }
                    else {
                        System.out.println("Error: Please enter a whole number.\n");
                        num1.nextLine();
                    }
                }while(!valid);

                if (userInput > randNum) {
                    System.out.println("\nToo high!");
                    guesses++;
                }
                else if (userInput < randNum) {
                    System.out.println("\nToo Low!");
                    guesses++;
                }
                else if (userInput == randNum) {
                    System.out.println("You got it!");
                    System.out.println("It took you" + guesses + "tries");
                    valid = true;
                }
            }while(!valid);


            //Insert play again checker
            do {
                System.out.println("\nDo you want to play again?");
                System.out.println("\nEnter 'Y' if yes and 'N' if no.");
                String play = again.nextLine();
                if (play.equalsIgnoreCase("Y")) {
                    valid = true;
                }
                else if (play.equalsIgnoreCase("N")) {
                    valid = true;
                }

                else {
                    System.out.println("Error: Please answer with 'Y' or 'N'");
                }
            }while(!valid);

        }while(!valid);
    }
}

I appreciate the help!

Your problem is in this part of the program

//Insert Game loop here
        do {
            System.out.println("\nI'm thinking of a number " +
                    "between 1 and 100.");
            //Insert valid guess checker here
            do {
                System.out.println("Please enter your guess: ");
                if (num1.hasNextInt()){
                    userInput = num1.nextInt();
                    valid = true; //>>>>> HERE YOU SET VALID TO TRUE 
                }
                else {
                    System.out.println("Error: Please enter a whole number.\n");
                    num1.nextLine();

                }

            }while(!valid);
            if (userInput > randNum) {
                System.out.println("\nToo high!");
                guesses++;
            }
            else if (userInput < randNum) {
                System.out.println("\nToo Low!");
                guesses++;
            }
            else if (userInput == randNum) {
                System.out.println("You got it!");
                System.out.println("It took you" + guesses + "tries");
                valid = true;
            }

        }while(!valid); //>>>>> AND THIS !VALID CHECK USES THE SAME "valid" boolean

So just use two separate booleans like so

//Imports
import java.util.Scanner;

public class Lab4d{
public static void main(String[] args) {

    // Set up scanners
    Scanner again = new Scanner(System.in);
    Scanner num1 = new Scanner(System.in);

    // Set up variables
    int userInput = 0;
    int guesses = 0;
    int min = 1;
    int max = 100;
    int range = max - min + 1;
    int randNum = (int) (Math.random() * range) + min;
    boolean valid = false;

    // Outside loop
    do {
        // Describe the game
        System.out.println("\nThis program is a guessing game.");
        System.out.println("\nThe computer will pick a random number " + "between 1 and 100.");
        System.out.println("\nYou will try to guess it.");
        System.out.println("\nLet's play!");

        // Insert Game loop here
        do {
            System.out.println("\nI'm thinking of a number " + "between 1 and 100.");
            // Insert valid guess checker here

            boolean userInputValid = false;
            do {
                System.out.println("Please enter your guess: ");
                if (num1.hasNextInt()) {
                    userInput = num1.nextInt();
                    userInputValid = true;
                } else {
                    System.out.println("Error: Please enter a whole number.\n");
                    num1.nextLine();
                }
            } while (!userInputValid);

            if (userInput > randNum) {
                System.out.println("\nToo high!");
                guesses++;
            } else if (userInput < randNum) {
                System.out.println("\nToo Low!");
                guesses++;
            } else if (userInput == randNum) {
                System.out.println("You got it!");
                System.out.println("It took you" + guesses + "tries");
                valid = true;
            }

        } while (!valid);

        // Insert play again checker
        do {
            System.out.println("\nDo you want to play again?");
            System.out.println("\nEnter 'Y' if yes and 'N' if no.");
            String play = again.nextLine();
            if (play.equalsIgnoreCase("Y")) {

                valid = true;
            }

            else if (play.equalsIgnoreCase("N")) {

                valid = true;
            }

            else {
                System.out.println("Error: Please answer with 'Y' or 'N'");
            }

        } while (!valid);

    } while (!valid);
}

}

Just as an info (not directly related to your question), be careful comparing Integers with "==", it only works for values from -128 up to 127. (but you can use == for primitive type "int")

https://wiki.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

You don't need two Scanner objects. You can do the entire application with a single Scanner object:

Scanner input = new Scanner(System.in);

Your variables guesses , randNum , and valid should be initialized within the main game loop. This way, when a new game starts, a new random value ( randNum ) is acquired, valid is reset to boolean false, and guesses is reset to 0 .

The valid = true; located within the if (num1.hasNextInt()){ ... } IF code block of the Please enter your guess: prompt loop should be removed (deleted). This is to soon to say the input is valid and allows the prompt loop to exit. This flag should only fall true if a correct value which matches the generated randNum value is supplied by the User.

Your IF statements for checking User input should be contained within the Please enter your guess: prompt loop. This allows the indicators Too High or Too Low to be displayed and the Please enter your guess: prompt to be re-displayed for another guess.

The guesses variable is keeping an incorrect count (not enough). You only need one guesses++; and it should be placed directly after the User entry validity check IF/ELSE blocks.

You should set valid to false before entering the Do you want to play again? prompt loop.

In your Do you want to play again? prompt loop you set valid to true if either Y or N is supplied. So the main game loop is never passed through again. Because you are using the valid boolean variable as a condition for all your loops you will want to ensure that if Y (yes) is supplied then valid meets the condition required to re-loop the main game loop (which happens to be boolean false) or use a different boolean flag for this main game loop (perhaps: boolean playAgain = false; ). Currently, if Y is supplied then valid should equal false and a break; ought to be issued so as to exit the prompt loop. Because valid is false the main game loop iterates again for a new game. If N is supplied then simply exit the game at this point. There is no need to just exit the prompt loop:

 else if (play.equalsIgnoreCase("N")) {
    System.out.println("Thanks for playing...Bye Bye");
    System.exit(0);
 }

Placing the:

System.out.println("\nI'm thinking of a number "
                 + "between 1 and 100.");

within a do/while loop is pointless. Keep the output to console but remove the do { and } while(!valid); .

Alternative code might look something like:

Scanner input = new Scanner(System.in);

//Set up variables
int userInput = 0;
int guesses;
int min = 1;
int max = 100;
int range = max - min + 1;
int randNum;
boolean valid;
boolean playAgain = false;

//Outside loop
do {
    //Describe the game
    System.out.println("\nThis program is a guessing game.");
    System.out.println("\nThe computer will pick a random number "
            + "between 1 and 100.");
    System.out.println("\nYou will try to guess it.");
    System.out.println("\nLet's play!");

    randNum = (int) (Math.random() * range) + min;
    valid = false;
    guesses = 0;

    //Insert Game loop here
    System.out.println("\nI'm thinking of a number "
            + "between 1 and 100.");
    //Insert guess and validator here
    do {
        System.out.println("Please enter your guess: ");
        if (input.hasNextInt()) {
            userInput = input.nextInt();
        }
        else {
            System.out.println("Error: Please enter a whole number.\n");
            input.nextLine();
            continue;
        }
        guesses++;
        if (userInput > randNum) {
            System.out.println("\nToo high!");
        }
        else if (userInput < randNum) {
            System.out.println("\nToo Low!");
        }
        else if (userInput == randNum) {
            System.out.println("You got it!");
            System.out.println("It took you " + guesses + " tries");
            valid = true;
        }
    } while (!valid);

    //Insert play again checker
    valid = false;
    do {
        System.out.println("\nDo you want to play again?");
        System.out.println("\nEnter 'Y' if yes and 'N' if no.");
        String play = input.nextLine();
        if (play.equalsIgnoreCase("Y")) {
            playAgain = true;
            valid = playAgain;
        }
        else if (play.equalsIgnoreCase("N")) {
            playAgain = false;
            valid = true;
        }
        else {
            System.out.println("Error: Please answer with 'Y' or 'N'");
        }
    } while (!valid);
} while (playAgain);

System.out.println("Thanks for playing...Bye Bye");

To Do: Allow the User to Quit at any time.

This is a working code

Scanner scanner = new Scanner(System.in); //you only need one

int userInput = 0;
int guesses = 0;
int min = 1;
int max = 100;
int range = max - min + 1;
int randNum = (int)(Math.random() * range) + min;
boolean valid = false;
boolean playAgain = false;

do {
  System.out.println("\nThis program is a guessing game.");
  System.out.println("\nThe computer will pick a random number between 1 and 100.");
  System.out.println("\nYou will try to guess it.");
  System.out.println("\nLet's play!");

  do {
    System.out.println("\nI'm thinking of a number between 1 and 100.");
    do {
      System.out.println("Please enter your guess: ");
      if (scanner.hasNextInt()){
        userInput = scanner.nextInt();
        valid = true;
      }
      else {
        System.out.println("Error: Please enter a whole number.\n");
        scanner.nextLine();
        userInput = -1; //this is important
        valid = false;
      }
    } while(!valid);

    if (userInput == randNum) {
      System.out.println("You got it!");
      System.out.println("It took you " + guesses + " tries");
      valid = true;
    }
    else {
      valid = false; //this is important
      ++guesses;
      if (userInput > randNum) {
        System.out.println("\nToo high!");
      }
      else {
        System.out.println("\nToo Low!");
      }
    }
  } while(!valid);

  do {
    System.out.println("\nDo you want to play again?");
    System.out.println("\nEnter 'Y' if yes and 'N' if no.");
    String play = scanner.nextLine();

    if (play.equalsIgnoreCase("Y")) {
      valid = true;
      playAgain = true;
    }
    else if (play.equalsIgnoreCase("N")) {
      valid = true;
      playAgain= false;
    }
    else {
      valid = false;
      System.out.println("Error: Please answer with 'Y' or 'N'");
    }
  } while(!valid);
} while(playAgain);

scanner.close();

But, I suggest using more functions (especially for the inner for loops) to keep your code managable and more understandable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM