TicTacToe Java - 检查获胜者

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19579113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:29:13  来源:igfitidea点击:

TicTacToe Java - check for winner

java

提问by JAVA

Here is my code. I am trying to check for the winner. I am only a beginner, so please make it easy. I wanted the board to change sizes. So, I want the check for winner can get use to the size, it will not just check the 9 blocks.

这是我的代码。我正在尝试检查获胜者。我只是一个初学者,所以请轻松。我希望董事会改变大小。所以,我希望获胜者的检查可以适应大小,它不会只检查 9 个块。

import java.util.*;

public class TicTacToe {

    private String[][] board;
    private Scanner console;

    public TicTacToe(String[][] table, Scanner console) {
        this.board = table;
        this.console = console;
    }

    public void makeTable() {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                board[i][j] = "_";
            }
        }
    }

    public void printTable() {
        System.out.print(" ");
        for (int i = 0; i < board.length; i++) {
            System.out.print(" " + i);
        }
        System.out.println();
        for (int i = 0; i < board.length; i++) {
            System.out.print(i + "│");
            for (int j = 0; j < board[i].length; j++) {
                System.out.print(board[i][j] + "│");
            }
            System.out.println();
        }
    }

    public void play(Scanner console) {
        int turn = 0;
        String player = "_";
        makeTable();
        printTable();
        while (turn != 9) {
            int x = console.nextInt();
            int y = console.nextInt();

            while (x >= board.length || y >= board[1].length) {
                System.out.println("Out of bounce, try again!!!");
                x = console.nextInt();
                y = console.nextInt();
            }

            while (board[y][x] != "_") {
                System.out.println("Occupied, try again!!!");
                x = console.nextInt();
                y = console.nextInt();
            }

            if (turn % 2 == 0) {
                player = "X";
            } else {
                player = "O";
            }
            board[y][x] = player;
            turn++;
            printTable();
        }
    }

    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        String[][] board = new String[3][3];
        TicTacToe ttt = new TicTacToe(board, console);
        ttt.play(console);
    }
}

回答by Little Child

Ok here is how I did it when I made tic-tac-toe. I used Strings

好的,这是我制作井字游戏时的方法。我用String小号

  1. Create a 2D array that contains all the possible winning combinations
  2. Create two Stringvariables, one for each player.
  3. Display the board on the table
  4. Number each of the blocks from 1 to 9 starting at the top left corner
  5. Whenever the either of the user clicks on the board, append the number to the player String
  1. 创建一个包含所有可能获胜组合的二维数组
  2. 创建两个String变量,每个玩家一个。
  3. 在桌子上展示黑板
  4. 从左上角开始从 1 到 9 为每个块编号
  5. 每当用户中的任何一个点击棋盘时,将数字附加到玩家 String

Now, here comes the magic part, checking the winner:
6. For every click on the board, start iterating on the 2d winning combination. Here is how you check if somebody has won:

现在,神奇的部分来了,检查获胜者:
6. 每点击一次棋盘,就开始迭代 2d 获胜组合。以下是您检查是否有人获胜的方法:

String[][] winningCombo = ... initialization ...
for( int i = 0 ; i < winningCombo.length; i++){
    for(j = 0; j < winningCombo[i].length; j ++){
        char c1 = winningCombo[i][j].charAt(0);
        char c2 = winningCombo[i][j].charAt(1);
        char c3 = winningCombo[i][j].charAt(2);
        if(currentPlayerString.contains(c1) && currentPlayerString.contains(c2) && currentPlayerString.contains(c3)){
            // currentPlayer has won if he has all the 3 positions of a winning combo
        }
    }
}  

So, if you may consider an alternative approach, you can use that. I used Swingfor UI and used GridLayoutto layout the various JPanel.

因此,如果您可以考虑另一种方法,则可以使用它。我用于SwingUI 并用于GridLayout布局各种JPanel.

回答by YAMM

just check rows, cols and both diagonals:

只需检查行、列和两条对角线:

import java.util.Scanner;

public class TTT {

private String[][] board;
private Scanner console;
private int size;

public TTT(String[][] table, Scanner console, int size) {
    this.board = table;
    this.console = console;
    this.size = size;
}

public void makeTable() {
    for (int i = 0; i < board.length; i++) {
        for (int j = 0; j < board[i].length; j++) {
            board[i][j] = "_";
        }
    }
}

public void printTable() {
    System.out.print(" ");
    for (int i = 0; i < board.length; i++) {
        System.out.print(" " + i);
    }
    System.out.println();
    for (int i = 0; i < board.length; i++) {
        System.out.print(i + "│");
        for (int j = 0; j < board[i].length; j++) {
            System.out.print(board[i][j] + "│");
        }
        System.out.println();
    }
}

public void play(Scanner console) {
    int turn = 0;
    String player = "_";
    makeTable();
    printTable();
    while (turn != 9) {
        int x = console.nextInt();
        int y = console.nextInt();

        while (x >= board.length || y >= board[1].length) {
            System.out.println("Out of bounce, try again!!!");
            x = console.nextInt();
            y = console.nextInt();
        }

        while (board[y][x] != "_") {
            System.out.println("Occupied, try again!!!");
            x = console.nextInt();
            y = console.nextInt();
        }

        if (turn % 2 == 0) {
            player = "X";
        } else {
            player = "O";
        }
        board[y][x] = player;
        turn++;
        printTable();
        if(check()){
            System.out.println("Player "+player+" won!");
            break;
        }
    }
}
public boolean check(){
    //check diagonals
    if(check00ToNN()){
        return true;
    }
    if(check0NToN0()){
        return true;
    }
    for(int i = 0 ; i< size ; i++){

        if(checkCol(i)){
            return true;
        }
        if(checkRow(i)){
            return true;
        }
    }
    return false;

}

public boolean checkRow(int index){

    for(int i = 1 ; i< size ; i++){
        if(board[i-1][index]!=board[i][index]||board[i][index]=="_"){
            return false;
        }
    }
    return true;


    }
public boolean checkCol(int index){
    for(int i = 1 ; i< size ; i++){
        if(board[index][i-1]!=board[index][i]||board[index][i]=="_"){
            return false;
        }
    }
    return true;


    }
public boolean check00ToNN(){
    for(int i = 1 ; i< size ; i++){

            if(board[i-1][i-1]!=board[i][i]||board[i][i]=="_"){
                return false;

        }
    }
    return true;
    }

public boolean check0NToN0(){ //diagonal
    for(int i = 1 ; i< size ; i++){

            if(board[i-1][size-i-1]!=board[i][size-i]||board[i][size-i]=="_"){
                return false;
            }

    }
    return true;
    }




public static void main(String[] args) {
    Scanner console = new Scanner(System.in);
    int size = 3;
    String[][] board = new String[size][size];
    TTT ttt = new TTT(board, console,size);
    ttt.play(console);
}

}

i just look if there is a winner, since i know who had the last turn, i know who it is.

我只是看看是否有赢家,因为我知道最后一轮是谁,我知道是谁。

check()calls the real checkmethods.

check()调用真正的检查方法。

i added sizesince it is scalable.

我补充说,size因为它是可扩展的。

回答by Bernard

A winning move can only happen when a piece is placed on the board, so you only need to check winning combinations that involve the piece that was just placed on the board.

只有在棋盘上放置棋子时才能获胜,因此您只需要检查涉及刚刚放置在棋盘上的棋子的获胜组合。

For example, if the current state of the board is:

例如,如果板的当前状态是:

O X O
X   X
    O

And Oplaces their piece in the middle of the board:

并将O他们的棋子放在棋盘中间:

O X O
X O X
    O

Then you only need to check the winning combinations that involve this middle piece, namely both diagonals, and the middle column and middle row (4 combinations) out of the total number of winning combinations (8 combinations).

那么你只需要在获胜组合总数(8个组合)中检查涉及这个中间件的获胜组合,即两条对角线,以及中间列和中间行(4个组合)。

Thus, tracking the last move made is essential to effectively determining if the board is in a winning state.

因此,跟踪最后一步对有效确定棋盘是否处于获胜状态至关重要。

回答by DiscoChinchilla

EDIT

编辑

As one person already mentioned, what you're essentially doing is checking to see if the last played move is a winning move. As a result, there really isn't any need to brute force check every row, column, and diagonal systematically to see if there's a winning position or to create some sort of list or table of solutions to check the current board against.

正如一个人已经提到的,您本质上所做的是检查最后下的棋步是否是获胜棋步。因此,真的没有必要系统地强力检查每一行、每一列和对角线以查看是否有获胜的位置,或者创建某种解决方案列表或表格来检查当前的棋盘。

All you really need to do is check the row, column, and diagonal (if the move was on a diagonal) that the move was played on and see if the winning condition is met there.

您真正需要做的就是检查走棋的行、列和对角线(如果走棋在对角线上),看看那里是否满足获胜条件。

// Takes the row and column coordinates of the last move made
// and checks to see if that move causes the player to win
public boolean isWinner(int row, int col){
    String Player = board[row][col];

    int r = row;
    int c = col;

    boolean onDiagonal = (row == col) || (col == -1 * row + (board.length-1));
    boolean HorizontalWin = true, VerticalWin = true;
    boolean DiagonalWinOne = true; DiagonalWinTwo = true;

    // Check the rows and columns
    for(int n = 0; n < board.length; n++){
        if(!board[r][n].equals(Player))
            HorizontalWin = false;
        if(!board[n][c].equals(Player))
            VerticalWin = false;
    }

    // Only check diagonals if the move is on a diagonal
    if(onDiagonal){
        // Check the diagonals
        for(int n = 0; n < board.length; n++){
            if(!board[n][n].equals(Player))
                DiagonalWinOne = false;
            if(!board[n][-1*n+(board.length-1)].equals(Player))
                DiagonalWinTwo = false;
        }
    }
    else{
        DiagonalWinOne = false;
        DiagonalWinTwo = false;
    }

    boolean hasWon = (HorizontalWin || VerticalWin || DiagonalWinOne || DiagonalWinTwo);

    return hasWon;

}

ORIGINAL

原来的

A few people have already answered this question, but here's my answer just for the heck of it.

一些人已经回答了这个问题,但这里是我的答案,只是为了解决这个问题。

Also, in your play method, you have a while loop to check to make sure that the user doesn't specify a move that is out-of-bounds, but then afterwards you have another while loop check to make sure that the move is in an empty space. You'll still probably want to check to make sure that their new move is also within the boundaries otherwise your loop condition will throw an ArrayOutOfBoundsException.

此外,在您的播放方法中,您有一个 while 循环来检查以确保用户没有指定越界的移动,但之后您有另一个 while 循环检查以确保移动是在一个空旷的地方。您可能仍然需要检查以确保他们的新移动也在边界内,否则您的循环条件将抛出 ArrayOutOfBoundsException。

public boolean isWinner(String player){
    // Check for N-in-a-row on the rows and columns
    for(int i = 0; i < board.length; i++){
        boolean verticalWin = true, horizontalWin = true;
        for(int j = 0; j < board.length; j++){
            if(!board[i][j].equals(player)))
                horizontalWin = false;
            if(!board[j][i].equals(player))
                verticalWin = false;
            if(!(horizontalWin || verticalWin))
                break;
        }
        if(horizontalWin || verticalWin)
            return true;
    }

    // If there was a N-in-a-row on the rows or columns
    // the method would have returned by now, so we're
    // going to check the diagonals

    // Check for N-in-a-row on both the diagonals
    boolean diagonalWinOne = true, diagonalWinTwo = true;
    for(int n = 0; n < board.length; n++){
        diagonalWinOne = true;
        diagonalWinTwo = true;
        int row = board.length - 1 - n;
        if(!board[n][n].equals(player))
            diagonalWinOne = false;
        if(!board[row][n].equals(player))
            diagonalWinTwo = false;
        if(!(diagonalOne || diagonalTwo))
            break;
    }

    // If either one of the diagonals has N-in-a-row, then there's a winner
    if(diagonalWinOne || diagonalWinTwo)
        return true;
    // Otherwise, no one has won yet
    else
        return false;   
}