How do I determine a winner in my Tic Tac Toe prog

2019-08-12 23:55发布

问题:

Earlier post: How do I make my tictactoe program scalable

I have tried to make a Tic Tac Toe program (human vs computer) scalable (the board size can be changed). I had major problems earlier but fixed most of them.

The game's rules are basic Tic Tac Toe but one different rule is that no matter how large the board is (when >= 5) the player or computer only need five marks in a row to win.

Now the only gamebreaking problem with my program is determining who wins the game. It is only possible that the game ends a 'draw' at the moment. (Also I have not implemented the ">= 5" yet).

Specific problem explanation is that I need to determine a winner and end screen for something like "computer wins" and/or "player wins".

package tictactoe;

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

public class TicTacToe {

    public static int size;
    public static char[][] 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) {

        System.out.println("Select board size");
        System.out.print("[int]: ");
        size = Integer.parseInt(scan.nextLine());

        board = new char[size][size];
        setupBoard();

        int i = 1;

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

            // isWon()
            if (isDraw()) {
                System.err.println("Draw!");
                break;
            }

            i++;
        }

    }

    /**
     * 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] = ' ';
            }
        }
    }

    /*
     * Checks if the move is allowed. 
     *
     *
     */
    public static void getMove() {

        Scanner sc = new Scanner(System.in);

        while (true) {
            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] = 'X';
                break;
            }
        }
    }

    /*
     * 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] = 'O';
                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] == ' ');
    }
}

回答1:

You have already the loop to play, so, in each iteration, in the same way you check if the game isDraw(), check also if some of the players won:

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

    // isWon()
    if (isDraw()) {
        System.err.println("Draw!");
        break;
    } else if (playerHasWon()){
        System.err.println("YOU WIN!");
        break;
    } else if (computerHasWon()) {
        System.err.println("Computer WINS!\nYOU LOOSE!!");
        break;
    }

    i++;
}

After create the needed methods:

public static boolean playerHasWon() {
    boolean hasWon = false;

    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
              // check if 5 in a line
        }
    }

    return hasWon ;
}

public static boolean computerHasWon() {
    boolean hasWon = false;

    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
              // check if 5 in a line
        }
    }

    return hasWon ;
}

Next question of course is HOW DO I CREATE THIS METHODS?? dunno if you have problems with this, but doing a fast check here here and here you will find some ideas.


ADD ON:

In order to clarify, I would make a function returning an int instead booleans, to check if the game is finished using some constants:

private final int DRAW = 0;
private final int COMPUTER = 1;
private final int PLAYER = 2;

private int isGameFinished() {
    if (isDraw()) return DRAW;
    else if (computerHasWon()) return COMPUTER;
    else if (playerHasWon()) return PLAYER;
}

Then simply check with a switch case (check here how to break the while insite the while)

loop: while (true) {
    // other stufff
    switch (isGameFinished()) {
    case PLAYER:
        System.err.println("YOU WIN!");
        break loop;
    case COMPUTER:
        System.err.println("Computer WINS!\nYOU LOOSE!!");
        break loop;
    case DRW:       
        System.err.println("IT'S A DRAW");
        break loop;
}