Как я могу исправить эту ошибку логического предложения без исключений? - PullRequest
1 голос
/ 05 мая 2019

Введение

Код, который я собираюсь представить сейчас, является частью цикла игры. У меня проблемы с обработкой ошибок (без исключений) .

Задача

Эта следующая функция принимает 4 переменные типа int (row_1, col_1, row_2, col_2), которые необходимо проверить, если они меньше (size-1).

Причина в том, что мы работаем с матрицей, а диапазон равен from 0 to (size-1).

Так, если пользователь вводит меньше 0 или больше (размер-1), он должен снова запросить ввод

Код

 public static void gameLoop()
{
    //While you still play (true) or if (false) -> end game
    showMatrix(gameMatrix);//Cheat
    while(play == true)
        {
            showMatrix(displayMatrix);
            System.out.println("--------------------");
            System.out.println("Input first row and col press enter between inputs");
            System.out.print("First row: ");
                row_1 = scan.nextInt();
            System.out.print("First column: ");
                col_1 = scan.nextInt();
            System.out.println("Input second row and col press enter between inputs");
            System.out.print("Second row: ");
                row_2 = scan.nextInt();
            System.out.print("Second column: ");
                col_2 = scan.nextInt();

                if (row_1 == row_2 && col_1 == col_2)
                {
                    System.out.println("I tested this!");
                    showMatrix(displayMatrix);
                    System.out.println("--------------------");
                    System.out.println("[ERROR] Input not valid! Try again");
                    System.out.println("Input first row and col press enter between inputs");
                    System.out.print("First row: ");
                        row_1 = scan.nextInt();
                    System.out.print("First column: ");
                        col_1 = scan.nextInt();
                    System.out.println("Input second row and col press enter between inputs");
                    System.out.print("Second row: ");
                        row_2 = scan.nextInt();
                    System.out.print("Second column: ");
                        col_2 = scan.nextInt();
                }
                else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0)))     
                {
                    System.out.println("I tested that!");
                    showMatrix(displayMatrix);
                    System.out.println("--------------------");
                    System.out.println("[ERROR] Input not valid! Try again");
                    System.out.println("Input first row and col press enter between inputs");
                    System.out.print("First row: ");
                        row_1 = scan.nextInt();
                    System.out.print("First column: ");
                        col_1 = scan.nextInt();
                    System.out.println("Input second row and col press enter between inputs");
                    System.out.print("Second row: ");
                        row_2 = scan.nextInt();
                    System.out.print("Second column: ");
                        col_2 = scan.nextInt();
                }


            Turn(row_1, col_1, row_2, col_2, gameMatrix);
            check = checkEndgame(gameMatrix, displayMatrix);

                if(check == false)
                {
                    System.out.println("Would you like to play again? Y/N");
                        game_option = scan.next();

                        if ("Y".equals(game_option) || "y".equals(game_option))
                        {
                            createGame();
                            gameLoop();
                        }     
                        else if ("N".equals(game_option) || "n".equals(game_option))
                        {
                            play = false;
                        }
                }


        }
}

Часть кода с проблемой

if (row_1 == row_2 && col_1 == col_2){}

else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0))){}

Вопрос

Я не понимаю, где я ошибся с этой логикой после тестирования чисел, которые должны ее вызвать.

Примечания

  • Не стесняйтесь судить код и помочь мне с дизайном или обработкой ошибок
  • Эти System.out.println("I tested that!"); && System.out.println("I tested this!"); являются стандартным отладочным.

Ответы [ 2 ]

1 голос
/ 06 мая 2019

Предложения:

Консольные приложения неумолимы, и если их не обрабатывать осторожно на этапе разработки, это может привести к тому, что приложение никто не захочет использовать из-за его неспособности обрабатывать ошибки ввода или простые ошибки ввода. Сколько раз вы готовы перезапустить приложение.

Люди допускают ошибки при входе, и чем более информативна ваша заявка, тем меньше ошибок совершит Пользователь. Например, если вы хотите, чтобы пользователи вводили только значение от 0 до, скажем, 10, то постоянно сообщайте им, каковы требования:

Please enter the numerical values for FIRST Row and Column:
First Row (0 to 10): 7
First Column (0 to 10): |

Вам всегда нужно будет проверять ввод, чтобы гарантировать, что то, что предоставлено, будет действительно обрабатываться без каких-либо ошибок. Как вы хорошо знаете, клавиатура представляет собой довольно большое устройство ввода с огромным количеством кнопок, и любая из них может быть случайно нажата во время ввода без ведома пользователя. В конце концов, каждый, кто владеет клавиатурой, автоматически мастер печатания и может выкачивать 400 слов в минуту, не глядя на экран. Ну ... так что, кажется, и если честно, я ни в коем случае не исключение.

Разрешить пользователю выполнить повторную запись в случае возникновения ошибки. Не бойтесь использовать для этого , в то время как , даже вложенные. При правильном обращении с ними проблем не будет.

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

По возможности используйте Методы или Классы, чтобы уменьшить или устранить дублирование кода. Иногда легче читать код, когда он длинный и вытянутый с большим количеством дубликатов, но в большинстве случаев это не займет много времени, чтобы надоесть смотреть на него. Это может вызвать у вас головокружение через некоторое время. Старое оправдание: «Я просто делаю это, чтобы заставить это работать, а затем убираю это», на самом деле не имеет смысла, по большей части. Если вы можете устранить дублирование кода сразу, вам не придется кодировать свое приложение дважды ... или трижды ... или, может быть, больше. Да, мы все делаем это в той или иной форме, и опять же, я не исключение.

Удалив большую часть кода и добавив небольшой метод или два, ваш конкретный сегмент кода может выглядеть примерно так:

Scanner scan = new Scanner(System.in);      // Declare Scanner (here for sake of this demo)
String LS = System.lineSeparator();         // System line Separator. 
boolean play = true;                        // Play flag
int size = 8;                               // 8 is used for sake of this demo
String range = "(0 to " + (size - 1) + ")"; // Range so we don't have to keep typing it.
String[] rowCol;                            // Array to hold Row and Column string numerical values
String border1 = String.join("", Collections.nCopies(72, "-")); // Text Border 1 (-)
String border2 = String.join("", Collections.nCopies(42, "=")); // Text Border 2 (=)

while (play) {
    String input = "";  // Input from scanner goes in this variable
    rowCol = new String[4]; // Initialize Array
    // Declare & init int variables to hold input integer values (if desired)
    // Un-comment the below line if you want this...
    // int row_1 = -1, col_1 = -1, row_2 = -1, col_2 = -1; 

    // Inform of what is required...
    System.out.println(border1);
    System.out.println("Please enter the numerical values for FIRST and "
            + "SECOND Rows and Columns." + LS + "Follow the provided prompts. "
            + "You can Enter 'q' or 'quit' at any time to" + LS + "end the game.");
    System.out.println(border1);

    // Get Input from User
    for (int i = 0; i < rowCol.length; i++) {
        // Set up current prompt...
        String prompt = LS;
        switch (i) {
            case 0:
                prompt += "Enter First Row Value " + range + ": ";
                break;
            case 1:
                prompt += "Enter First Column Value " + range + ": ";
                break;
            case 2:
                prompt += "Enter Secomd Row Value " + range + ": ";
                break;
            case 3:
                prompt += "Enter Second Column Value " + range + ": ";
                break;
        }

        input = "";     // Clear input variable
        // Get the actual input from User and validate.
        while (input.equals("")) {
            System.out.print(prompt);       // Display prompt
            input = scan.nextLine();        // Get keyboard input from User

            // Validate input...
            if (!validateUserRowColInput(0, (size - 1), input)) {
                input = ""; // Input was invalid so clear input variable
                continue;   // Re-prompt the User for proper input
            }
            rowCol[i] = input;  // All is good so add input to Array element at index i.
        }
    }

    // Display what was provided.
    System.out.println(border2);
    System.out.println("Row 1/Column 1  = " + rowCol[0] + "/" + rowCol[1] + LS
            + "Row 2/Column 2  = " + rowCol[2] + "/" + rowCol[3]);
    System.out.println(border2 + LS);
}

Остальной код вашего игрового цикла вы можете добавить самостоятельно. В приведенном выше коде простой String Array (с именем rowCol ) используется для хранения значений, предоставленных пользователем. Это позволяет нам использовать один цикл для , вложенный в основной цикл воспроизведения , в то время как , чтобы запрашивать все 4 ввода от пользователя, таким образом, устраняя некоторый дублирующий код и выполняя проверку ввода все в одном дом так сказать.

Если вы хотите преобразовать входные данные в целочисленные (целые числа), то вместо этого вы можете сделать что-то подобное (сразу после цикла для ):

/* Array index 0 and 1 now contains the string numerical 
   values for First Row and First Column. Array index 2 and
   3 now contains the string numerical values for Second Row 
   and Second Column. If you just can't wrap your head around 
   dealing with Arrays and indexes from this point then do 
   something like the following:     */

// Convert String Array elements to integers
row_1 = Integer.parseInt(rowCol[0]);
col_1 = Integer.parseInt(rowCol[1]);
row_2 = Integer.parseInt(rowCol[2]);
col_2 = Integer.parseInt(rowCol[3]);

// Display what was provided.
System.out.println(border2);
System.out.println("Row 1/Column 1  = " + row_1 + "/" + col_1 + LS
        + "Row 2/Column 2  = " + row_2 + "/" + col_2);
System.out.println(border2 + LS);

Метод validateUserRowColInput () , который, как это подразумевает, проверяет ввод пользователя для соблюдения требуемых правил для сегмента кода выше. Он вызывается сразу после ввода данных пользователем. Правила проверки в основном соответствуют тому, что вы изложили в своем посте, и проверка выполняется для каждого предоставленного ввода, а не в ожидании предоставления всех четырех входных данных:

Правила проверки:

  • Пустые записи не допускаются;
  • Можно указывать только числовые символы, никакие другие буквенные символы чем q или слово quit принято (без учета регистра);
  • Если указано q или слово quit , программа завершается;
  • Строка 1 и / или Строка 2 не могут быть меньше 0;
  • Колонка 1 и / или Колонка 2 не могут быть меньше 0;
  • Строка 1 и / или строка 2 не могут быть больше, чем (размер - 1);
  • Колонка 1 и / или столбец 2 не могут быть больше, чем (размер - 1);

Пользователь, конечно, информируется о нарушении правила и получает возможность сделать правильную запись.Вот метод validateUserRowColInput () :

/**
 * Validates the User's Row and Column values input. This method checks to
 * ensure only numerical characters were entered. It also ensures the the
 * numerical value entered is between and or equal to the supplied minValue
 * and maxValue.
 *
 * @param minVal      (Integer) The minium Allowable integer value to be
 *                    entered.
 * @param maxVal      (Integer) The maximum allowable integer value to be
 *                    entered.
 * @param inputString (String) String representation of the integer value
 *                    supplied.
 *
 * @return (Boolean) True if the entry is valid and false if it is not.
 */
private static boolean validateUserRowColInput(int minVal, int maxVal, String inputString) {
    String LS = System.lineSeparator();
    if (inputString.equals("")) {
        System.out.println("Invalid Entry! You must supply a numerical "
                + "value from " + minVal + " to " + maxVal + ".");
        return false;
    }
    if (inputString.equalsIgnoreCase("q") || inputString.equalsIgnoreCase("quit")) {
        System.out.println("We hope you had fun. Bye Bye");
        System.exit(0);
    }
    if (!inputString.matches("\\d+")) {
        System.out.println("Invalid input supplied (" + inputString + ")! "
                + "You can not supply alpha characters, only" + LS 
                + "numerical values are allowed!. Please try again...");
        return false;
    }
    int num = Integer.parseInt(inputString);
    if (num < minVal || num > maxVal) {
        System.out.println("Invalid input supplied (" + inputString + ")! "
                + "The numerical value you supply can not be" + LS + "less "
                + "than " + minVal + " and no greater than " + maxVal + ". "
                + "Please try again...");
        return false;
    }
    return true;
}

Да .... это можно уменьшить еще больше.

1 голос
/ 05 мая 2019

Вы должны использовать цикл do...while, чтобы убедиться, что входы верны. Требуется аргумент boolean:

do {
    // All the System.out.println and Scanner stuff...
} while(!checkAnswers(row_1, row_2, col_1, col_2));

Теперь нам нужно написать функцию checkAnswers, которая будет возвращать логическое значение, чтобы указать, разрешено ли пользователю выходить из цикла do...while:

public static boolean checkAnswers(int row_1, int row_2, int col_1, int col_2) {
    // I don't know why you needed that condition, but I let it there
    if(row_1 == row_2 || col_1 == col_2) return false; 

    // check if the rows and colls are in the range 0...(size - 1)
    int[] rowsAndCols = {row_1, row_2, col_1, col_2};
    for(int i : rowsAndCols)
        if(i < 0 || i >= (size - 1)) return false;

    // If everything is good we can quit the do...while loop
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...