Проблема с циклом do-while


Пожалуйста, обратите внимание, что я, хотя мне удобно с Java, я не исключительно одарен и не знаю всего жаргона, поэтому, пожалуйста, объясните свои ответы с очень небольшим количеством жаргона кодера и столько же нормального английского языка, или объясните, что означает этот жаргон после того, как вы его используете. Кроме того, это мой первый раз с Stackoverflow, так что дайте мне знать, если это был приличный вопрос и дайте мне несколько советов.

Я беру курс AP Computer Science в своей средней школе. Мы используем Java. Нас недавно научили делать-пока loops и я только что завершили "лабораторию", которая использует do-while loops, однако, есть проблема.

Во-первых, позвольте мне объяснить лабораторию. Программа генерирует случайное целое число между 1-10, которое пользователь должен угадать (догадка хранится как int с помощью сканера), есть несколько целочисленных значений, которые отслеживают количество догадок, сколько догадок было больше, чем компьютерное целое число, и сколько было слишком мало. Когда вы посмотрите на мой код, вы заметите, что у меня есть System.out.println(compGen);//compGen is the computer generated int. Цель состояла в том, чтобы проверить код.

Проблема заключается в операторе if, который сравнивает userGen (user guess) и compGen.

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

В этом if-операторе не печатаются правильные SOP, которые я написал, если пользователь угадывает более одного раза. Однако я не записал это в программу, она, кажется, делает это сама по себе. Я использовал SOP, о котором упоминал ранее, где печатается compGen int, и я ввел это как свою первую догадку, и это сработало идеально. Все в блоке if-statement выполнено идеально и напечатал все правильно. Однако, когда я сделал это как свою вторую догадку, третью догадку или любую другую догадку, которая не была первой, ничего не было напечатано. Смотрите код ниже и запустите его. Я не думаю, что это должно иметь значение, но IDE, которую я использую, - Eclipse, следовательно, оператор package. Пожалуйста помочь.

    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         
}
}
Я так и не смог понять, в чем дело. В какой-то момент я удалил весь if-оператор и перепечатал его (я знал, что он ничего не сделает, но я должен был попробовать). Этот вопрос делает для меня это не имеет смысла. Нет никаких ошибок или чего-то такого, что всплывает, ничего не всплывает на консоли, что меня немного пугает. Заранее спасибо.
5 3

5 ответов:

Во-первых, здесь много текста, который вы поместили. Может быть, попытаться минимизировать проблему в следующий раз в качестве предложения ;) в противном случае все в порядке

К вашей проблеме. Позвольте мне минимизировать ваш код, а затем объяснить вам, что происходит.

1. Код

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. Что делает ваш код?

Вы читаете свой первый номер перед циклом. Это прекрасно. Затем вы вводите оператор if-elseif-else. Обратите внимание, что, оказавшись внутри одного из этих блоков, другие блоки не будет казнен. теперь проблема в том, что Вы читаете ваши следующие пользовательские вводы внутри if-elseif! программа считывает следующее значение и оставляет целое if-elseif-else. Ваш код не выполняется, потому что цикл завершается до следующей итерации, поэтому правильный пользовательский ввод не проходит через if-elseif-else вообще.

3. Решение

Удалить все nextInt() чтения и просто иметь один в качестве первой вещи внутри петля:

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);
Такие вещи, структуры, которые должны сделать что-то хотя бы один раз перед проверкой состояния цикла, обычно выполняются с do while петлями, а не while петлями

Вы устанавливаете пользовательский ввод во время цикла, а затем он проверяется. Попробуйте переместить тело блока else if(userGen==compGen) после цикла следующим образом:

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
}

Условие while проверяется, как только программа достигает конца кода внутри цикла. Поэтому предположим, что они вводят неправильное число; программа говорит, что оно слишком низкое или слишком высокое, а затем просит другое число:

userGen = userInput.nextInt();//new guess
Теперь предположим, что это новое число является правильным. Программа завершает ваш оператор if, а затем переходит к концу цикла. Тогда в этой точке userGen равно compGen. Таким образом, условие while не выполняется, и программа немедленно выходит из цикла, без всегда добираюсь до кода, который печатает результаты. Один из способов решить эту проблему-переместить логику для userGen == compGen, которая выводит результаты, за пределы цикла, то есть после окончания цикла. Таким образом, он будет выполняться при каждом выходе из цикла. Обратите внимание, что когда вы выходите из цикла, мы знаем, что userGen == compGen, потому что если бы это было не так, цикл вернулся бы назад.

Предположим, что сгенерированное компьютером число было 3, а вы угадали 5. 5>3, поэтому оператор if(userGen > compGen) выполняет:

        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

Вы печатаете сообщение, получаете новое предположение, а затем увеличиваете счетчик... но когда вы получите новую догадку, скажите, что это был правильный ответ 3, userGen теперь равен CompGen (оба равны 3) , и теперь в то время как условие оценивается:

While (userGen != compGen)

Теперь это неверно, потому что userGen = = compGen (оба равны 3). Ваш код никогда получить шанс чтобы напечатать правильное сообщение, потому что цикл завершается до того, как это может произойти. надеюсь, что это поможет

Ваш userGen не проверяется после каждого пользовательского ввода. Проблема в том, что у вас есть проверка внутри блока else-if, который будет проверять конец оператора while, прежде чем он вернется обратно.

Если вы измените

else if(userGen==compGen)

К

if(userGen==compGen)

Тогда, поскольку он не отделен от блока if-else, он будет проверяться после каждого ввода (до проверки условия while)

В качестве альтернативы вы можете переместить пользовательский ввод в начало блока do-while вот так:

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         
}
}

Это приведет к тому, что ваш блок if-else будет проверяться каждый раз, когда пользователь вводит данные до проверки условий для do-while.