0
votes

I am currently working on an assignment, which is to create a Tic Tac Toe game. I got to the point where players can place their marks on the board, draw it and switch turns after. However, my check if a win-condition exists only seems to evaluate to true when a player places his mark in the top left (1st) field.

I've been trying to work with this answer to get it right, but no luck so far and I don't want to just copy that answer, but know where my coding is flawed. The debugger isn't giving me much. I suspect it has something to do with the way playerTurn() is set up. What am I missing? Any help would be appreciated.

Here's my code:

import java.util.Scanner;

public class tictactoe {

private static char[][] board;
private char currentPlayer = 'X';

public static void main(String[] args) {
    board = new char [3][3];
    tictactoe game = new tictactoe();

    game.welcomeAndInstruct();
    game.boardInit();
    game.playerTurn();

}

public void playerTurn() {
    do {
        Scanner input = new Scanner(System.in);
        System.out.print("Player " + currentPlayer + "'s turn: ");
        int move = input.nextInt();
        if (move == 1) {
            placeMark(0, 0);
            drawBoard();
        } else if (move == 2) {
            placeMark(0, 1);
            drawBoard();
        } else if (move == 3) {
            placeMark(0, 2);
            drawBoard();
        } else if (move == 4) {
            placeMark(1, 0);
            drawBoard();
        } else if (move == 5) {
            placeMark(1, 1);
            drawBoard();
        } else if (move == 6) {
            placeMark(1, 2);
            drawBoard();
        } else if (move == 7) {
            placeMark(2, 0);
            drawBoard();
        } else if (move == 8) {
            placeMark(2, 1);
            drawBoard();
        } else if (move == 9) {
            placeMark(2, 2);
            drawBoard();
        } else {
            System.out.println("Invalid, choose a number between 1-9"); 
            continue; 
        }

    if (checkForWin()) {
        System.out.println("Player " + currentPlayer + " has won!");
        break;
    }

    if (isBoardFull()) {
        System.out.println("It's a tie!");
        break;
    }
    changePlayer();
} while (true);

}

//Empties the board by replacing all X/O with -
public void boardInit() {
    for (int r = 0; r < 3; r++) {
        for (int c = 0; c < 3; c++) {
            board[r][c] = '-';
        }
    }
}

//Draws the board in it's current state
public void drawBoard() {
    System.out.println("+---+---+---+");
    for (int r = 0; r < 3; r++) {
        System.out.print("| ");
        for (int c = 0; c < 3; c++) {
            System.out.print(board[r][c] + " | ");              
        }
        System.out.println();
        System.out.println("+---+---+---+");
    }
    System.out.println("\n-------------------------------------\n");

}

//Place's the current players mark in the indicated position
public void placeMark(int row, int col) {
    if ((row >= 0) && (row < 3)) {
        if ((col >= 0) && (col < 3)) {
            if (board[row][col] == '-') {
                board[row][col] = currentPlayer;    
            } 
        }
    }
}



//switches players
public char changePlayer() {
        if (currentPlayer == 'X') {
            currentPlayer = 'O';
        } else
            currentPlayer = 'X';
    return currentPlayer;
}


//checks whether the board is full or not
public boolean isBoardFull() {
    for (int r = 0; r < 3; r++) {
        for (int c = 0; c < 3; c++) {
            if (board[r][c] == '-') {
            return false;
            }
        }
    }
    return true;
}

//checks whether a win-condition exists or not
public boolean checkForWin() {
    //loops through rows checking if win-condition exists
    for (int r = 0; r < 3; r++) {
        if (board[r][0] == board[r][1] && board[r][1] == board[r][2] && board[r][0] != '-')
            return true;
        }
    //loops through columns checking if win-condition exists
    for (int c = 0; c < 3; c++) {
        if (board[0][c] == board[1][c] && board[1][c] == board[2][c] && board[0][c] != '-' ) 
            return true;
        }
    //checks diagonals for win-condition
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != '-')
        return true;

    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][0] != '-')
        return true;

    return false;
}

// prints the instructions at the start of the game
public void welcomeAndInstruct() {
    System.out.println("Welcome to Tic Tac Toe, a 2 player game for console.");
    System.out.println("Two players take turns in marking the squares on a 3 x 3 grid.");
    System.out.println("The player who succeeds in placing three of their marks in a horizontal, vertical or diagonal row wins the game.");
    System.out.println("To select a square on the grid by entering it's corresponding number when prompted, as shown below:");
    System.out.println();

    board[0][0] = '1';
    board[0][1] = '2';
    board[0][2] = '3';
    board[1][0] = '4';
    board[1][1] = '5';
    board[1][2] = '6';
    board[2][0] = '7';
    board[2][1] = '8';
    board[2][2] = '9';

    drawBoard();

    }
}
2
Debugger should definitely let you see where your logic flaw is. Specifically under your checkForWin() method your last if conditiongtgaxiola

2 Answers

4
votes

At :

if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][0] != '-')

instead of board[0][0] check board[0][2].

1
votes

Ok, so the question has been answered - I'd leave this as a comment but I don't have the rep.

By simply playing the game, the first thing I naturally did was place a O in box 1, and the game said player O had won. Immediately, you can see that this box causes a problem (not necessarily the only problem, mind).

From there, it is easy to look through every condition that utilises this square and check for any that don't make sense. It's clear that the diagonal from bottom left to top right are all the same, and [0,0] is not '-', exactly as your final check states.

A word of advice - try to be a bit more specific and accurate when asking questions. From

However, my check if a win-condition exists only seems to evaluate to true when a player places his mark in the top left (1st) field.

I had (incorrectly) assumed that the game only was marked as won if there was a winning condition that involved the top left square. In fact, the check-if-win function was incorrectly returning true way before that. A more accurate problem description would have been "placing a mark in the top left square sometimes prematurely and incorrectly causes the game to end"