Как получить ввод сканера, чтобы не запускать третий метод?

#java

#java

Вопрос:

Я работаю над заданием, и я в основном его закончил, но у меня возникла проблема с последним методом. Я пытаюсь написать continueGame() метод, который спросит пользователя, хотят ли они продолжать играть, и примет «y» или «n». Если ответ «y», программа запускается снова. Если ответить «n», программа останавливается и отображается сообщение. Проблема в том, что мне нужно, чтобы он запускал continueGame() метод только тогда, когда userChoice == answer . Это игра в угадывание чисел с объектно-ориентированным подходом.

Я пытался вызвать continueGame() метод внутри моего else if(userChoice == answer) оператора, но, похоже, он не работает. Даже когда запускаются другие мои if/else if операторы, он продолжает continueGame() метод.

Вот основной драйвер для игры

 import java.util.Scanner;

public class NumberGame
{
   public static void main(String[] args)
   {
      Scanner input = new Scanner (System.in);
      GameOptions opt = new GameOptions(); // Your created class
      int userChoice = -1234;
      int answer = -1234;
      boolean keepPlaying = true;

      System.out.println("Guess the Number Gamen");

      while (keepPlaying == true) {
         answer = (int) (Math.random() * 10) 1;

         //Create a getChoice method in your class and make sure it accepts a Scanner argument 
         userChoice = opt.getChoice(input);

         //Create a checkAnswer method in your class. Make sure it accepts two integer arguments and a Scanner argument
         opt.checkAnswer(userChoice, answer, input);

         // Create a continueGame method in  your class and make sure it accepts a Scanner argument
         keepPlaying = opt.continueGame(input);    
      } 
      System.out.println("Thanks for playing.");
   }
}
 

Вот класс, над которым я работаю для методов. Обратите внимание, что я не могу вносить какие-либо изменения в основной файл драйвера.

 import java.util.InputMismatchException;
import java.util.Scanner;
import java.lang.NumberFormatException;

public class GameOptions {
    int count = 0;
    boolean cont = true;
    //getChoice Method for NumberGame
    public int getChoice(Scanner scnr) {

        System.out.println("Please choose a number between 1 and 10: ");
        int userGuess = 0;
        String input = scnr.next();
        try {
            userGuess = Integer.parseInt(input);
            if (userGuess < 1 || userGuess > 10) {
                throw new IllegalArgumentException("Invalid value. Please enter a number between 1 and 10: ");
            }
        }
        catch(NumberFormatException e) {
            System.out.println("Error - Enter Numerical Values Only");
            return userGuess;
        }
        catch (IllegalArgumentException ex) {
            System.out.println(ex.getMessage());
        }
        return Integer.parseInt(input);
    }

    public void checkAnswer(int userChoice, int answer, Scanner scnr) {
        if (userChoice > answer amp;amp; userChoice < 11) {
            System.out.println("Too high. Try again.");
            count  ;
        } else if (userChoice < answer amp;amp; userChoice > 0) {
            System.out.println("Too low. Try again.");
            count  ;
        } else if (userChoice == answer) {
            System.out.println("You got it! Number of tries: "   count);
            System.out.println("Would you like to play again? (y/n)");
        }
    }

    public static boolean continueGame(Scanner scnr) {

        String input = scnr.nextLine();
        if (input.toLowerCase().equals("y")){
            return true;
        } else if (input.toLowerCase().equals("n")){
            return false;
        } else {
            System.out.println("Invalid entry. Please enter either y or n: ");
            return continueGame(scnr);
        }
    }
}
 

Таким образом, я должен иметь возможность ввести число, и если оно меньше ответа, оно скажет мне, что я слишком низкий, если оно выше ответа, оно скажет мне, что оно слишком высокое, если оно равно, оно скажет мне, что я выиграл, и предложит мне нажать «y» или «n» если я захочу продолжить. Еще одна проблема, с которой я сталкиваюсь, заключается в том, что я получаю: «Не хотели бы вы снова поиграть? (y / n)» независимо от того, угадываю я правильное число или нет, и мой единственный вариант — нажать «y» или «n».

Ответ №1:

Класс драйвера вызывается continueGame() внутри цикла while. Если вам не разрешено изменять этот класс, то, по-видимому, запрос на каждой итерации является предполагаемым поведением.

Вы должны перейти System.out.println("Would you like to play again? (y/n)"); в continueGame() метод, чтобы он запрашивал только при вызове этого метода.

Комментарии:

1. Хм, я мог бы попробовать это. Единственное, что программа предназначена для работы, так это то, что она должна спрашивать вас, хотите ли вы снова играть, только один раз UserChoice == answer . Вот пример прогона того, как ДОЛЖНА выглядеть программа, если она правильно закодирована. Игра «Угадай число» Пожалуйста, выберите число от 1 до 10: 10 Слишком большое. Попробуйте еще раз. Пожалуйста, выберите число от 1 до 10: 5 Слишком низкое. Попробуйте еще раз. Пожалуйста, выберите число от 1 до 10: 8, вы его получили! Количество попыток: 3 Хотите поиграть еще раз? (Y / N): k недопустимая запись. Пожалуйста, введите Y или N: y

2. Единственный способ сделать это — добавить логическое значение в ваш GameOptions класс, которое устанавливается true , когда они получают ответ. Затем в вашем continueGame() методе проверьте, является ли это логическое значение true — если оно отображает продолжение воспроизведения, а если это не так, просто верните true.

3. @Matt … в вашем комментарии предлагается ввести состояние в класс, который должен быть без состояния.

4. @EdwardAung Нигде в вопросе не говорится, что класс GameOptions должен быть без состояния. На самом деле по определению у него есть состояние, потому что оно отслеживает количество. Откуда у вас эта идея?

5. @Matt count используется исключительно внутри функции (для цикла). Я мог бы догадаться о цели этого задания, потому что я помогал разрабатывать материалы курса программной инженерии 3000-го уровня в университете.

Ответ №2:

Способ написания драйвера (я думаю) исходит от вашего инструктора / лектора / профессора, верно?

С драйвером (как есть) вам не нужно вызывать метод continueGame из метода checkAnswer. Драйвер собирается вызвать его.

Просто запустите драйвер, и он будет работать. Если у вас есть правильная среда IDE (eclipse или Netbeans), проследите и посмотрите, какой принятый ввод (я думаю, что в принятом ответе есть перевод строки).

Попробуйте это (я только что изменил структуру цикла; ваш тоже действителен):

 public static boolean continueGame(Scanner scnr) { 
while (true) {
    String input = scnr.nextLine().trim(); // to remove white spaces and line-feed
    if (input.toLowerCase().equals("y")){
        return true;
    } else if (input.toLowerCase().equals("n")){
        return false;
    } else {
        System.out.println("Invalid entry. Please enter either y or n: ");
    }
}
}
 

Добавлено для метода checkAnswer, чтобы пользователь угадывал ответ, пока не получит правильный:

 public static checkAnswer(/*three arguments*/) {
    boolean correct = false;
    while (! correct) {
        // accept input
        if (answer.equals(input)) {
            correct = true;
            // print required correct/congrats messages here
        } else {
            // print required input/try again messages here
        }
    }
    // print would you like to play again with new answer y/n message here.
}
 

На мой взгляд, печать «воспроизвести снова с новым ответом y / n сообщением» должна перейти в метод continueGame (из последней части метода checkAnswer), чтобы придерживаться концепции инкапсуляции.

Комментарии:

1. Предполагается ли добавить этот цикл в метод checkAnswer? Или находится вне метода? Просто немного запутался, когда я попытался поместить это в метод checkAnswer, но это не сработает, потому что он не возвращает никаких значений.

2. Нет, драйвер вызывает checkAnswer … затем продолжайте использовать методы. Поместите цикл в метод continueGame. Я отредактировал ответ.

3. Мой плохой, я только что понял, что вы сказали. Это работает, но дает мне только одну попытку угадать число. Мне нужно, чтобы он возвращался к первоначальным вопросам «Пожалуйста, выберите число от 1 до 10: » после того, как я получу неправильный номер. Что он делает сейчас, так это то, что он попросит меня ввести число, если я получу слишком низкое число, оно отобразит «Слишком низкое. Попробуйте еще раз» но мне не будет предложено ввести другой номер, если я введу другой номер, он выдаст мне «Недопустимую запись. Пожалуйста, введите либо y, либо n «. таким образом, он переходит прямо к методу continueGame()

4. Мой плохой. Да, вам нужен цикл в методе checkAnswer. Я изменю свой ответ, чтобы отразить его.

5. Эй, Эдвард, я, кажется, подбираюсь очень близко, опубликованный вами код исправил некоторые из моих проблем, но теперь, если я ввожу число, которое выше ответа, оно, похоже, застряло на этом значении пользовательского выбора. Независимо от того, насколько низкое число я ввожу, я все равно получаю сообщение «Слишком высокое. Попробуйте еще раз. » Я предполагаю, что это связано с тем, что значение на самом деле не меняется?