当可扩展板大于4x4时,井字游戏获胜条件发生变化 [英] Tic Tac Toe winning condition change when scalable board is larger than 4x4

查看:50
本文介绍了当可扩展板大于4x4时,井字游戏获胜条件发生变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我已经制作了Tic Tac Toe程序已有一段时间了.这是一款基本的Tic Tac Toe游戏,但游戏板具有可扩展性.该程序快要完成了,但是缺少一个小功能.

So, I have been making this Tic Tac Toe program for a while now. It's a basic Tic Tac Toe game but the game board is scalable. The program is almost finished but one little feature is missing.

如果游戏板大于4x4,如果玩家连续获得五个或更多标记,我必须结束游戏.

I have to make the game end if player gets five or more marks in a row when the game board is larger than 4x4.

F.E.如果游戏板为9x9,则当玩家或计算机连续获得5个标记时,游戏必须结束.

F.E. If the game board is 9x9 the game has to end when the player or the computer gets five marks in a row.

(标记="O"或"X").

(Mark = "O" or "X").

现在,当某人连续获得等于棋盘大小的标记时,游戏结束(如果9x9,您需要连续获得9个标记才能获胜).

The game now ends when someone gets marks in a row equals to the size of the board (if 9x9 you need 9 marks in a row to win).

我必须在 playerHasWon 中实现一项功能,而在寻找方法上却遇到了很多麻烦.我认为这很容易实现,但是我还没有找到实现方法.

I have to implement a feature in the playerHasWon and I've been having a lot of trouble finding out how. I think it's a simple to implement thing but I have not found out how to do it.

希望我的解释很容易理解.这是代码:

Hope my explanation is easy enough to understand. Here's the code:

package tictac; 

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

public class Tictac {

public static final int DRAW = 0; // game ends as a draw
public static final int COMPUTER = 1; // computer wins
public static final int PLAYER = 2; // player wins
public static final char PLAYER_MARK = 'X'; // The "X"
public static final char COMPUTER_MARK = 'O'; // The "O"

public static int size; // size of the board
public static String[][] board; // the board itself
public static int score = 0; // game win score
public static Scanner scan = new Scanner(System.in); // scanner

/**
 * Builds the board with the integer size and user input.
 * 
 * Displays game win message and switches play turns.
 * 
 * @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; // after message, give player new try
        }

        break;
    }

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

    int i = 1;

    loop: // creates the loop

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

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

        i++;
    }
}

/**
 * Checks for game finish.
 *
 * @param args command line parameters. Not used.
 * 
 * @return DRAW the game ends as draw.
 * @return COMPUTER the game ends as computer win.
 * @return PLAYERE the game ends as player win.
 */
private static int isGameFinished(int[] move) {
    if (isDraw()) {
        return DRAW;
    } else if (playerHasWon(board, move,
            Character.toString(COMPUTER_MARK))) {
        return COMPUTER;
    } else if (playerHasWon(board, move,
            Character.toString(PLAYER_MARK))) {
        return PLAYER;
    }

    return -1; // can't be 0 || 1 || 2
}

/**
 * Checks for win for every direction on the board.
 *
 * @param board the game board.
 * @param move move on the board.
 * @param playerMark mark on the board "X" or "O".
 * @return the game is won.
 */
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 check
    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;
        }
    }

    return i == size;
}

/**
 * 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 user input and sends it to isValidPlay. 
 *
 * @return null.
 */
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};
            } else { // if input is unallowed
                System.out.println("You can't do that");
                continue; // after message, give player new try
            }
        } 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 a move is possible.
 *
 * @param inX x-move is out of bounds.
 * @param inY y-move is out of bounds.
 * @return false
 */
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

推荐答案

快速浏览一下,检测到问题并提出了快速解决方案:

Took a quick look, detected the problem and came up with a quick fix:

public static boolean checkDiagonal(String markToLook) {
// how many marks are we looking for in row?
int sizeToWin = Math.min(size, 5);

// running down and right
// don't need to iterate rows that can't be the starting point
// of a winning diagonal formation, thus can exlude some with
// row < (size - (sizeToWin - 1))
for (int row = 0; row < (size - (sizeToWin - 1)); row++) {
    for (int col = 0; col < size; col++) {
        int countOfMarks = 0;

        // down and right
        for (int i = row; i < size; i++) {
            if (board[i][i] == null ? markToLook == null :
                    board[i][i].equals(markToLook)) {
                countOfMarks++;

                if (countOfMarks >= sizeToWin) {
                    return true;
                }
            }
        }

        countOfMarks = 0;

        // down and left
        for (int i = row; i < size; i++) {
            if (board[i][size - 1 - i] == null ? markToLook == null :
                    board[i][size - 1 - i].equals(markToLook)) {
                countOfMarks++;

                if (countOfMarks >= sizeToWin) {
                    return true;
                }
            }
        }
    }
}

return false;
}

然后从PlayerHasWon方法调用它,而不是在那里执行检查.基本上,我们在板上对每个可能的起始正方形进行迭代,以获得对角线获胜的阵型,然后对每个正方形进行下+左和下+右检查.

And call it from your PlayerHasWon method instead of performign the checks there. Basically we iterate each possible starting square on the board for a diagonal winning formation, and run check down+left and down+right for each of the squares.

我很着急,没有进行太多测试,但是将在几个小时后返回以改进此解决方案.似乎可以正常工作.

I am in awful hurry and did not test it much, but will return in couple of hours to improve this solution. Seems to work.

我发现以前的解决方案缺少进一步的测试,我已经将上面的代码更新为可以正常使用的功能.

My previous solution I found lacking in further tests, I've updated the above code to function as desired.

这篇关于当可扩展板大于4x4时,井字游戏获胜条件发生变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆