TicTacToe Java - 检查获胜者

时间:2013-10-25 00:30:10

标签: java

这是我的代码。我正在努力检查获胜者。我只是一个初学者,所以请轻松一点。我希望电路板能够改变尺寸。所以,我希望对获胜者的检查可以使用到大小,它不会只检查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);
    }
}

4 个答案:

答案 0 :(得分:5)

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

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

O X O
X   X
    O

O将他们的作品放在棋盘中间:

O X O
X O X
    O

然后你只需要检查涉及这个中间部分的获胜组合,即对角线,以及获胜组合总数(8种组合)中的中间列和中间行(4种组合)。

因此,跟踪最后一步行动对于有效确定董事会是否处于获胜状态至关重要。

答案 1 :(得分:1)

修改

正如一个人已经提到过的,你实际上在做的是检查最后一次移动是否是一个成功的举动。因此,实际上没有必要对每一行,一列和对角线进行强力检查以查看是否存在获胜位置,或者创建某种列表或解决方案表来检查当前的电路板。

你真正需要做的就是检查行,列和对角线(如果移动是在对角线上)进行了移动,并查看是否符合获胜条件。

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

有些人已经回答了这个问题,但这只是我的回答。

另外,在你的play方法中,你有一个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;   
} 

答案 2 :(得分:0)

好的,这就是我做Tic-tac-toe时的表现。我使用了String s

  1. 创建包含所有可能获胜组合的2D数组
  2. 创建两个String变量,每个玩家一个。
  3. 在桌面上显示电路板
  4. 从左上角开始,从1到9对每个块进行编号
  5. 每当用户点击棋盘时,请将该号码附加到玩家String
  6. 现在,这里有神奇的部分,检查胜利者:
     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
            }
        }
    }  
    

    所以,如果你可以考虑另一种方法,你可以使用它。我将Swing用于用户界面,并使用GridLayout来布局各种JPanel

答案 3 :(得分:0)

只需检查行,列和两个对角线:

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

}

我只是看看是否有胜利者,因为我知道谁有最后一个回合,我知道它是谁。

check()调用真正的checkmethods。

我添加了size,因为它可以扩展。