【问题标题】:Unable to determine win condition in Tic Tac Toe无法确定井字游戏中的获胜条件
【发布时间】:2015-11-22 15:18:47
【问题描述】:

我一直试图让我的井字游戏程序运行一段时间。 目前我陷入了胜利状态。

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

我需要在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

【问题讨论】:

标签: java arrays tic-tac-toe


【解决方案1】:

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

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

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

请注意,您必须将 playerMarks 从 char 更改为 String。 另外,我建议在宣布谁获胜之前展示棋盘。这样,如果计算机获胜,您就可以看到它的最后一步

【讨论】:

  • 在我看来,参数“int[] move”在 playerHasWon(...) 和 isGameFinished(...) 中都是多余的。它可以简单地取出。
  • 感谢这帮助了很多:)
  • 没问题!不要忘记接受答案,这样其他人才能意识到这是一个有效的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
相关资源
最近更新 更多