4

这是我的代码。我正在尝试检查获胜者。我只是一个初学者,所以请放轻松。我希望董事会改变大小。所以,我希望获胜者的支票可以适应大小,而不仅仅是检查 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

4 回答 4

5

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

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

O X O
X   X
    O

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

O X O
X O X
    O

那么你只需要检查所有中奖组合(8种组合)中涉及到这个中间棋子的中奖组合,即对角线、中间列和中间行(4种组合)。

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

于 2013-10-25T01:09:39.697 回答
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;

}

原来的

有几个人已经回答了这个问题,但这是我的回答,只是为了它的见鬼。

此外,在您的播放方法中,您有一个 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;   
} 
于 2013-10-25T01:37:59.597 回答
0

好的,这就是我做井字游戏时的做法。String我 用过

  1. 创建一个包含所有可能获胜组合的二维数组
  2. 创建两个String变量,每个玩家一个。
  3. 在桌子上展示棋盘
  4. 从左上角开始将每个块从 1 到 9 编号
  5. 每当用户中的任何一个点击棋盘时,将数字附加到玩家String

现在,神奇的部分来了,检查获胜者:
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
        }
    }
}  

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

于 2013-10-25T00:45:02.977 回答
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()调用真正的检查方法。

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

于 2013-10-25T00:57:58.693 回答