简体   繁体   中英

Issue with do-while loop

Please note that I while I am comfortable with Java, I am not exceptionally gifted nor do I know all the jargon, so please explain your answers with very little coder jargon and as much normal English, or explain what the jargon means after you use it. Also, this is my first time with Stackoverflow, so let me know if this was a decent question and give me some pointers.

I am taking an AP Computer Science class at my high school. We use Java. We were recently taught do-while loops and I just completed the "lab" that uses do-while loops, however, there is an issue.

Firstly, let me explain the lab. The program generates a random integer between 1-10 which the user must guess (guess is stored as an int using a scanner), there are a few integer values which track number of guesses, how many guesses were greater than the computer integer, and how many were too low. When you look at my code, you will notice that I have a System.out.println(compGen);//compGen is the computer generated int . The purpose was to test the code.

The issue is in the if-statement that compares userGen (user guess) and compGen.

if(userGen==compGen)
{
//do a lot of stuff
}

In this if-statement, it is not printing the correct SOPs that I have written IF the user guesses more than once. HOWEVER, I did not write this into the program, it seems to do it on its own. I used the SOP I mentioned early where the compGen int is printed, and I typed that in as my first guess and it worked perfectly. Everything in the if-statement block executed perfectly and printed everything correctly. However, when I did it as my second guess, third guess, or any guess that was not the first one, NOTHING was printed. See code below and run it. I don't believe this should make a difference, but the IDE that I use is Eclipse, hence the package statement. Please help.

    package Chapter_3.Lab03_Chapter3;
    import java.util.*;

public class Guess 
{
    public static void main(String[] args) 
    {   
    Scanner userInput = new Scanner(System.in);//Scanner
    int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
    System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
    int guessTrack = 0;//tracks number of guesses
    int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
    int tooLowTrack = 0;
    System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT 
    System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
    int userGen = userInput.nextInt();//USER GUESS  

    do
    {
        guessTrack++;//Increase guess value
        if(userGen > compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too high!");//inform user of bad guess
            userGen = userInput.nextInt();//new guess
            tooHighTrack++;//if guess is too high, this int tracker increases
        }
        else if(userGen < compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too low!");//inform user of guess
            userGen = userInput.nextInt();//new guess
            tooLowTrack++;//increases if user guess is too low
        }
        else if(userGen==compGen)//if both values are equivalent, execute THIS IS THE PROBLEM STATEMENT!!
        {
            System.out.println("Great job! You guessed the right number!");//congratulate
            if(guessTrack>1)
            {
                System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
            }
            else
            {
                System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
            }               
            System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
            System.out.println("HELLO"); //Used to verify failure of code
            userInput.close();//close scanner object
        }
    }
    while (userGen != compGen);//condition to be ultimately checked         
}
}

I haven't been able to figure out what is wrong. At one point I deleted the entire if-statement and re-typed it (I knew it wouldn't do anything, but I had to try). This issue makes no sense to me. There are no errors or anything that pop up, nothing pops up on the console which scares me a little. Thanks in advance.

First off, a lot of text you put here. Maybe try to minimize the problem next time as a suggestion ;) Otherwise everything is fine

To your problem. Let me minimize your code and then explain to you, what happens.

1. The Code

int val = scanner.nextInt();
do {
    if (val < 5) {
        // too low
        val = scanner.nextInt();
    } else if (val > 5) {
        // too high
        val = scanner.nextInt();
    } else {
        // correct
        // THIS CODE DOESN'T RUN?!
    }
} while (val != 5);

2. What does your code do?

You read your first number before your loop. That's fine. Then, you enter an if-elseif-else statement. Note, that once inside one of those blocks, the other blocks won't get executed. Now the problem is, that you read your next user inputs inside of the if-elseif! The program reads the next value and leaves the whole if-elseif-else. Your code does not execute, because the loop then ends before the next iteration, therefore the correct user input is not going through the if-elseif-else at all.

3. The solution

Remove all nextInt() reads and just have one as the first thing inside the loop:

int val;
do {
    val = scanner.nextInt();
    if (val < 5) {
        // too low
    } else if (val > 5) {
        // too high
    } else {
        // correct
        // THIS CODE RUNS NOW!
    }
} while (val != 5);

Such things, structures that need to do something at least once before checking the loop condition, are usually done with do while loops rather than while loops

You are setting user input during the loop, and it is then checked afterwards. Try moving the body of the else if(userGen==compGen) block to after the loop like this:

public static void main(String[] args) 
    {   
    Scanner userInput = new Scanner(System.in);//Scanner
    int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
    System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
    int guessTrack = 0;//tracks number of guesses
    int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
    int tooLowTrack = 0;
    System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT 
    System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
    int userGen = userInput.nextInt();//USER GUESS  

    do
    {
        guessTrack++;//Increase guess value
        if(userGen > compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too high!");//inform user of bad guess
            userGen = userInput.nextInt();//new guess
            tooHighTrack++;//if guess is too high, this int tracker increases
        }
        else if(userGen < compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too low!");//inform user of guess
            userGen = userInput.nextInt();//new guess
            tooLowTrack++;//increases if user guess is too low
        }
    }
    while (userGen != compGen);//condition to be ultimately checked

    //The numbers have matched since it exited the loop.
    System.out.println("Great job! You guessed the right number!");//congratulate
    if(guessTrack>1)
    {
        System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
    }
    else
    {
        System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
    }               
    System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
    System.out.println("HELLO"); //Used to verify failure of code
    userInput.close();//close scanner object
}

The while condition is checked as soon as the program reaches the end of the code inside the loop. So suppose they enter the wrong number; the program says it's too low or too high, and then asks for another number:

userGen = userInput.nextInt();//new guess

Now suppose this new number is the correct one. The program finishes your if statement, then gets to the end of the loop. Then, at that point, userGen is equal to compGen . So the while condition fails, and the program exits the loop immediately, without ever getting to the code that prints the results.

One way to solve it would be to move the logic for userGen == compGen , that prints the results, outside the loop--that is, after the end of the loop. That way, it will be executed whenever the loop is exited. Note that when you exit the loop, we know that userGen == compGen , because if it weren't, the loop would go back.

Let's say the computer generated number was 3, and you guess 5. 5>3, so the if(userGen > compGen) statement executes:

        System.out.println("Try again! Your guess was too high!");//inform user of bad guess
        userGen = userInput.nextInt();//new guess
        tooHighTrack++;//if guess is too high, this int tracker increases

you print the message, get a new guess, then increment your counter... but when you get the new guess, say it was the correct answer 3, userGen is now equal to CompGen (both are 3) and now the while condition is evaluated:

while (userGen != compGen)

this is now false because userGen == compGen (both are 3). Your code never gets a chance to print the correct message because the loop exits before it can happen. hope that helps

Your userGen is not being checked after every user input. The problem is that you have your check inside an else-if block, which will check the end of the while statement before it loops back through again.

If you change

else if(userGen==compGen)

to

if(userGen==compGen)

then because it is not apart of the if-else block, it will be checked after every input (before the while condition is checked)

Alternatively you could move your user-input to the start of the do-while block like so:

package Chapter_3.Lab03_Chapter3;
import java.util.*;

public class Guess 
{
    public static void main(String[] args) 
    {   
    Scanner userInput = new Scanner(System.in);//Scanner
    int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
    System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
    int guessTrack = 0;//tracks number of guesses
    int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
    int tooLowTrack = 0;
    System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT 
    System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
    int userGen = -1;//USER GUESS  

    do
    {
        userGen = userInput.nextInt();
        guessTrack++;//Increase guess value
        if(userGen > compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too high!");//inform user of bad guess
            userGen = userInput.nextInt();//new guess
            tooHighTrack++;//if guess is too high, this int tracker increases
        }
        else if(userGen < compGen)//checks user value in relation to computer generated int
        {
            System.out.println("Try again! Your guess was too low!");//inform user of guess
            userGen = userInput.nextInt();//new guess
            tooLowTrack++;//increases if user guess is too low
        }
        else if(userGen==compGen)//if both values are equivalent, execute THIS IS THE PROBLEM STATEMENT!!
        {
            System.out.println("Great job! You guessed the right number!");//congratulate
            if(guessTrack>1)
            {
                System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
            }
            else
            {
                System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
            }               
            System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
            System.out.println("HELLO"); //Used to verify failure of code
            userInput.close();//close scanner object
        }
    }
    while (userGen != compGen);//condition to be ultimately checked         
}
}

This will cause your if-else block to be checked everytime a user inputs data before the conditions for the do-while are checked.

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