java - Java 中的两人井字游戏 - 如何防止非整数输入

标签 java tic-tac-toe

所以我的 TicTacToe 游戏感觉几乎是完美的,除了我不知道如何防止非整数(字符或字符串)输入这一事实。我想让它“这不是一个数字,请再试一次”。每当通过扫描仪输入字母或符号时。相反,每当我尝试时,我就会得到

Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    at java.base/java.util.Scanner.next(Scanner.java:1594)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
    at TicTactoe3.main(TicTactoe3.java:23)

似乎还有 java.util.InputMismatchException;从未使用过,因此无法以某种方式访问​​该 block 。我将它放在 while 循环中的 try catch 语句中,这似乎几乎无法访问,并且我知道这是因为playerPos() 与playerPos 不同,但我仍然不知道解决方案。将 try catch 放入 main 方法中也不起作用,returns 不能在 void 语句中使用,没有它它就不会执行任何操作。

这是我的所有代码供引用。我真的不知道如何解决这个问题,尽管我不希望重写所有代码,但任何答案/建议将不胜感激。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;
// import java.util.Random;
import java.util.Scanner;

public class TicTactoe3 {
    
    static Scanner move = new Scanner(System.in);
    static ArrayList<Integer> playerPositions = new ArrayList<Integer>();
    static ArrayList<Integer> playerPositions2 = new ArrayList<Integer>();

    public static void main(String[] args) {
        
        char[][] gameBoard = {{' ', '|', ' ', '|', ' '}, 
                              {'-', '+', '-', '+', '-'}, 
                              {' ', '|', ' ', '|', ' '}, 
                              {'-', '+', '-', '+', '-'}, 
                              {' ', '|', ' ', '|', ' '}};
        
        printGameBoard(gameBoard);  
        int playerPos = move.nextInt();
        
        while(true) {
            

            System.out.println("Enter your move (1-9) player one ");
            while(playerPositions.contains(playerPos) || playerPositions2.contains(playerPos)) {
                System.out.println("Position taken");
                playerPos = move.nextInt();
            }

            while(playerPos >= 10 || playerPos <= 0) {
                System.out.println("Incorrect Input");
                playerPos = move.nextInt();
            }
            

            placePiece(gameBoard, playerPos, "player 1");
            printGameBoard(gameBoard);

            String result = checkWinner();
            if(result.length() > 0) {
                System.out.println(result);
                break;
            }
            
            if (Character.isLetter(playerPos)) {
                System.out.println("Invalid Input. Numbers 1-9 only!");
            }

            System.out.println("Enter your move (1-9) player two ");
            int playerPos2 = move.nextInt();
            while(playerPositions.contains(playerPos2) || playerPositions2.contains(playerPos2)) {
                System.out.println("Position taken");
                playerPos2 = move.nextInt();
            }

            while(playerPos2 >= 10 || playerPos2 <= 0) {
                System.out.println("Incorrect Input");
                playerPos2 = move.nextInt();
            }

            placePiece(gameBoard, playerPos2, "player 2");  
            printGameBoard(gameBoard);

            result = checkWinner();
            if(result.length() > 0) {
                System.out.println(result);
                break;
            }
        }   
    }
    
    
    public static int playerPos() { // This is where I try to prevent non-integer input but it doesn't do anything
                                    // That and it seems to regard playerPos() as different from playerPos but
                                    // simply using playerPos leads to other issues
        while (true) {
            try {
                return move.nextInt();
            }
            catch (InputMismatchException a) {
                move.next();
                System.out.println("That is not a number please try again.");
            }
        }
    } 
    
    public static void printGameBoard(char[][] gameBoard) {
        for(char[] row : gameBoard) {
            for(char c : row) {
                System.out.print(c);
            }
            System.out.println();
        }
    }
    
    public static void placePiece(char[][] gameBoard, int pos, String user) {
        
        char symbol = ' ';
        
        if(user.equals("player 1")) {
            symbol = 'X';
            playerPositions.add(pos);
        } else if(user.equals("player 2")) {
            symbol = 'O';
            playerPositions2.add(pos);
        }
        
        switch(pos) {
        case 1:
            gameBoard[0][0] = symbol;
            break;  
        case 2:
            gameBoard[0][2] = symbol;
            break;  
        case 3:
            gameBoard[0][4] = symbol;
            break;
        case 4:
            gameBoard[2][0] = symbol;
            break;
        case 5:
            gameBoard[2][2] = symbol;
            break;
        case 6:
            gameBoard[2][4] = symbol;
            break;
        case 7:
            gameBoard[4][0] = symbol;
            break;
        case 8:
            gameBoard[4][2] = symbol;
            break;
        case 9:
            gameBoard[4][4] = symbol;
            break;
        default:
            break;
        }
    }
    public static String checkWinner() {
        
        List topRow = Arrays.asList(1, 2, 3);
        List midRow = Arrays.asList(4, 5, 6);
        List botRow = Arrays.asList(7, 8, 9);
        List leftCol = Arrays.asList(1, 4, 7);
        List midCol = Arrays.asList(2, 5, 8);
        List rightCol = Arrays.asList(3, 6, 9);
        List cross1 = Arrays.asList(1, 5, 9);
        List cross2 = Arrays.asList(7, 5, 3);
        
        List<List> winning = new ArrayList<List>();
        winning.add(topRow);
        winning.add(midRow);
        winning.add(botRow);
        winning.add(leftCol);
        winning.add(midCol);
        winning.add(rightCol);
        winning.add(cross1);
        winning.add(cross2);
        
        for (List l : winning) {
            if(playerPositions.containsAll(l)) {
                return "Congrats, player 1 wins!";
            }
            else if(playerPositions2.containsAll(l)) {
                return "Congrats, player 2 wins";
            }
        }
        
        for (List l : winning) {
            if(playerPositions.size() + playerPositions2.size() == 9) {
                return "NOBODY WINS";
            }
        }
        
        return "";
    }
}

编辑:我想出了一个部分解决方案。首先,我让playerPos和playerPos2在任何玩家输入之前从零开始。

int playerPos = 0;
int playerPos2 = 0;

然后我写了一个简单的 try 和 catch 语句,但我无法让它循环,所以它必须中断。继续只是输入令人作呕的错误。

try {
                playerPos = move.nextInt();
            } catch (InputMismatchException e) {
                System.out.println("1-9 only, please try again.");
                break;
            }

代替中断,我尝试了playerPos = move.nextInt();就像我的其他 while 循环一样,但这只会导致“线程主线程中的异常”错误,从而停止程序。可能有一个非常简单的解决方案,但我只是没有意识到。

最佳答案

我喜欢的典型模式:

public Optional<Integer> getInt(String input) {
    try {
        return Integer.parseInt(input);
    } catch (NumberFormatException ex) {
        return Optional.empty();
    }
}

然后,在你的主要逻辑中:

//...
Scanner move = /* your scanner object */;
Optional<Integer> input;
while ((input = getIntLine(move.nextLine())).isEmpty()) {
    System.out.println("Invalid input, expected (number)"); 
}
int value = input.get();

如果您想让循环重复输入请求,那也很简单:

//...
Scanner move = /* your scanner object */;
Optional<Integer> input;
boolean read = false;
while (!read) {
    System.out.print("Please enter a number: ");
    input = getInt(move.nextLine());
    read = !input.isEmpty();
    if (!read) {
        System.out.println("Not a number " /* ... etc */);
    }
}
int value = input.get();

关于java - Java 中的两人井字游戏 - 如何防止非整数输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62440043/

相关文章:

java - 使用 ASM 插入字节码

java - jsf。如何将 backbean 对象从 jsf 表单发布到 javascript

c - Minimax 不能在井字游戏中正确计分分支

Java线程调用父函数

java - 当在父 dependencyManagement 中定义依赖版本时,传递依赖未解决

C++ : Help understanding what this line of code is trying to do

Javascript Tic Tac Toe Win Checker 很湿

java - 3d 数组出了问题

用于 Tic Tac Toe 游戏的 Java ArrayList

java - Java中将整数转换为int数组