java - 无法确定 Tic Tac Toe 中的获胜条件

标签 java arrays tic-tac-toe

我一直在尝试让我的井字游戏程序运行一段时间。 此刻我陷入了胜利状态。

游戏现在可以以平局结束,但没有玩家(人类 || 计算机)能赢。

我需要在 playerHasWon 中确定获胜条件(水平、垂直、横向),但不知道如何实现它们。

import java.util.Scanner;
import java.util.Random;

public class NewTicTacToe {

public static final int DRAW = 0;
public static final int COMPUTER = 1;
public static final int PLAYER = 2;
public static final char PLAYER_MARK = 'X';
public static final char COMPUTER_MARK = 'O';

public static int size;
public static String[][] board;
public static int score = 0;
public static Scanner scan = new Scanner(System.in);

/**
 * Creates base for the game.
 *
 * @param args the command line parameters. Not used.
 */
public static void main(String[] args) {

    while (true) {
        System.out.println("Select board size");
        System.out.print("[int]: ");
        try {
            size = Integer.parseInt(scan.nextLine());
        } catch (Exception e) {
            System.out.println("You can't do that.");
            continue;
        }

        break;
    }

    int[] move = {};
    board = new String[size][size];
    setupBoard();

    int i = 1;

    loop:

    while (true) {
        if (i % 2 == 1) {
            displayBoard();
            move = getMove();
        } else {
            computerTurn();
        }

        switch (isGameFinished(move)) {
            case PLAYER:
                System.err.println("YOU WIN!");
                break loop;
            case COMPUTER:
                System.err.println("Computer WINS!\nYOU LOSE!");
                break loop;
            case DRAW:
                System.err.println("IT'S A DRAW");
                break loop;
        }

        i++;
    }
}

private static int isGameFinished(int[] move) {
    if (isDraw()) {
        return DRAW;
    } else if (playerHasWon(board, move, COMPUTER_MARK)) {
        return COMPUTER;
    } else if (playerHasWon(board, move, PLAYER_MARK)) {
        return PLAYER;
    }

    return -1;
}

/**
 * Checks for win.
 *
 * @param board
 * @return if the game is won.
 */
public static boolean playerHasWon(String[][] board, int[] move,
        char playerMark) { //playermark x || o
    boolean hasWon = false;

    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            // check if 5 in a line
            if (board[i][j].equals(playerMark)) {
                score++;
            } else {
                score = 0;
            }

            if (score == 5) {
                return true;
            }
        }
    }

    return hasWon;
}

/**
 * Checks for draws.
 *
 * @return if this game is a draw
 */
public static boolean isDraw() {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            if (board[i][j] == " ") {
                return false;
            }
        }
    }

    return true;
}

/**
 * Displays the board.
 *
 *
 */
public static void displayBoard() {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            System.out.printf("[%s]", board[i][j]);
        }

        System.out.println();
    }
}

/**
 * Displays the board.
 *
 *
 */
public static void setupBoard() {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            board[i][j] = " ";
        }
    }
}

/*
 * Takes in userinput and sends it to isValidPlay. 
 *
 *
 */
public static int[] getMove() {

    Scanner sc = new Scanner(System.in);
    System.out.println("Your turn:");

    while (true) {
        try {
            System.out.printf("ROW: [0-%d]: ", size - 1);
            int x = Integer.parseInt(sc.nextLine());
            System.out.printf("COL: [0-%d]: ", size - 1);
            int y = Integer.parseInt(sc.nextLine());

            if (isValidPlay(x, y)) {
                board[x][y] = "" + PLAYER_MARK;
                return new int[]{x, y};
            }
        } catch (Exception e) {
            System.out.println("You can't do that.");
        }
        return null;
    }
}

/*
 * Randomizes computer's turn - where it inputs the mark 'O'.
 *
 *
 */
public static void computerTurn() {
    Random rgen = new Random();  // Random number generator   

    while (true) {
        int x = (int) (Math.random() * size);
        int y = (int) (Math.random() * size);

        if (isValidPlay(x, y)) {
            board[x][y] = "" + COMPUTER_MARK;
            break;
        }
    }
}

/**
 * Checks if the move is possible.
 *
 * @param inX
 * @param inY
 * @return
 */
public static boolean isValidPlay(int inX, int inY) {

    // Play is out of bounds and thus not valid.
    if ((inX >= size) || (inY >= size)) {
        return false;
    }

    // Checks if a play have already been made at the location,
    // and the location is thus invalid. 
    return (board[inX][inY] == " ");
    }
}

// End of file

最佳答案

您可以使用不同的方法来检查胜利。也许分成三部分?水平、垂直和对角线?

我对你的代码做了一些修改来举个例子:

public static boolean playerHasWon(String[][] board, int[] move,
                                   String playerMark) { //playermark x || o

    //Horizontal check
    for (int i = 0; i < size; i++) {
        if (board[i][0].equals(playerMark)) {
            int j;
            for (j = 1; j < size; j++) {
                if (!board[i][j].equals(playerMark)) {
                    break;
                }
            }

            if (j == size) {
                return true;
            }
        }
    }

    //Vertical check
    for (int i = 0; i < size; i++) {
        if (board[0][i].equals(playerMark)) {
            int j;
            for (j = 1; j < size; j++) {
                if (!board[j][i].equals(playerMark)) {
                    break;
                }
            }

            if (j == size) {
                return true;
            }
        }
    }

    //Diagonals
    int i;
    for (i = 0; i < size; i++) {
        if (!board[i][i].equals(playerMark)) {
            break;
        }
    }
    if (i == size) {
        return true;
    }

    for (i = 0; i < size; i++) {
        if (!board[i][(size - 1) - i].equals(playerMark)) {
            break;
        }
    }
    if (i == size) {
        return true;
    }

    return false;
}

请注意,您必须将 playerMarkchar 更改为 String。 此外,我建议在宣布谁获胜之前展示董事会。这样,如果计算机获胜,您可以看到它的最后一步

关于java - 无法确定 Tic Tac Toe 中的获胜条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33856395/

相关文章:

javascript - 使用 javascript 对数组进行排序而不更改 null 或空位置

java - 为什么动态修改 ActionBar 中的 TextView 会出现空指针异常?

java - sleep 功能不会落后于人工智能的轮次

java - 用于具有 2D 逻辑的 3D 游戏的 Libgdx scene2d?

java - 将cassandra blob类型转换为字符串

java - jar 中不播放声音

c - C中如何确定数组元素的个数?

javascript - 使用 Underscore 更改数组中所有对象的值

java - 井字游戏抛出异常

java - 是否可以动态地将父级注入(inject) Java 中的类层次结构?