-1

For my programming class I'm supposed to make a program that simulates a game of tic tac toe. My teacher provided all the methods and said we shouldn't need to add any or take any away, and told us we shouldn't change the playGame method, but no matter what I do there seems to be some sort of disconnect between the playGame method and the processComputerMove/processHumanMove methods. Whenever I try to run the program, it seems like those methods just get skipped over entirely even if they have nothing in them but a simple print statement. I was wondering how to fix this. Here's my (unfinished and not working) code so far:

import java.util.*;

public class TicTacToe {

private static Scanner keyboard = new Scanner(System.in);
private static char[] board = new char[9];

// *******************************************************
public static void main(String[] args) {
    String answer;
    System.out.println("Welcome to Tic-Tac-Toe!!");
    System.out.print("Do you want to play a game? (Y/N) ");
    answer = keyboard.next();
        if (answer.charAt(0) == 'Y' || answer.charAt(0) == 'y' ) {
            playGame();
        } else if (answer.charAt(0) == 'N' || answer.charAt(0) == 'n'){
            System.out.println("Goodbye!");
        }   
}

// *******************************************************
private static void playGame() {

    char currentPlayer = determineFirstPlayer();
    System.out.println("The computer is X, the human is O.\n");

    initializeGameBoard();

    while (!isDone()) {
        if (currentPlayer == 'c' || currentPlayer == 'C') { // the computer
            processComputerMove();
            currentPlayer = 'h'; // the human
        } else {
            displayGameBoard();
            processHumanMove();
            currentPlayer = 'c'; // the computer
        }
    }

    displayGameBoard();
    System.out.println("Game over!");
}

public static char determineFirstPlayer() {
    System.out.print("Who would you like to make the first move? (h = human/c = computer) ");
     String response = keyboard.next();
     char player = response.charAt(0);

    return player; // return 'c' or 'h' as appropriate
}


// *******************************************************
private static void initializeGameBoard() {
    String playBoard = "   |   |   \n---+---+---\n   |   |   \n---+---+---\n   |   |   ";
    board[0] = playBoard.charAt(2);
    board[1] = playBoard.charAt(6);
    board[2] = playBoard.charAt(10);
    board[3] = playBoard.charAt(13);
    board[4] = playBoard.charAt(17);
    board[5] = playBoard.charAt(21);
    board[6] = playBoard.charAt(24);
    board[7] = playBoard.charAt(28);
    board[8] = playBoard.charAt(32);

}

// *******************************************************
private static void processComputerMove() {
    Random rand = new Random();
    int array = rand.nextInt(8);
    int comp = rand.nextInt(8);
    if (board[array] != 'X' || board[array] != 'O') {
        board[array] = 'X';
        System.out.println("The computer chooses cell "+board[array]+".");
    } else  {
        board[array] = board[comp];
        board[comp] = 'X';
    }

}


// *******************************************************
private static void processHumanMove() {
    System.out.println("Enter an empty position number (0-8) ");
    int position = keyboard.nextInt();
    if (board[position] != 'X' || board[position] != 'O') {
        board[position] = 'O';
    } else {
        System.out.println("Error! Must enter an empty position from 0-9.");
    }

}

// *******************************************************
private static void displayGameBoard() {
    System.out.println(" "+board[0]+" | "+board[1]+" | "+board[2]+" \n---+---+---\n "+board[3]+" | "+board[4]+" | "+board[5]+" \n---+---+---\n "+board[6]+" | "+board[7]+" | "+board[8]+" ");

}

// *******************************************************
private static boolean isDone() {
    isComputerWin();
    isHumanWin();
    isTie();
    if (isComputerWin()) {
        return true;
    } else if(isHumanWin()) {
        return true;
    } else if (isTie()) {
        return true;
    } else {
        return false;
    }
}

// *******************************************************
private static boolean isComputerWin() {
    if ((board[0] == 'X' && board[1] == 'X' && board[2] == 'X') || (board[0] == 'X' && board[3] == 'X' && board[6] == 'X') || 
            (board[0] == 'X' && board[4] == 'X' && board[8] == 'X') || (board[3] == 'X' && board[4] == 'X' && board[5] == 'X') || 
            (board[1] == 'X' && board[4] == 'X' && board[7] == 'X') || (board[2] == 'X' && board[5] == 'X' && board[8] == 'X') || 
            (board[6] == 'X' && board[7] == 'X' && board[8] == 'X') || (board[6] == 'X' && board[4] == 'X' && board[2] == 'X')){
        return true;
    } else {
        return false; // return true or false as appropriate
    }
}

// *******************************************************
private static boolean isHumanWin() {
    if ((board[0] == 'O' && board[1] == 'O' && board[2] == 'O') || (board[0] == 'O' && board[3] == 'O' && board[6] == 'O') || 
            (board[0] == 'O' && board[4] == 'O' && board[8] == 'O') || (board[3] == 'O' && board[4] == 'O' && board[5] == 'O') || 
            (board[1] == 'O' && board[4] == 'X' && board[7] == 'O') || (board[2] == 'O' && board[5] == 'O' && board[8] == 'O') || 
            (board[6] == 'O' && board[7] == 'O' && board[8] == 'O') || (board[6] == 'O' && board[4] == 'O' && board[2] == 'O')){
        return true;
    } else {
        return false; // return true or false as appropriate
    }

}

// *******************************************************
private static boolean isTie() {
    if (!((board[0] == 'O' && board[1] == 'O' && board[2] == 'O') || (board[0] == 'O' && board[3] == 'O' && board[6] == 'O') || 
            (board[0] == 'O' && board[4] == 'O' && board[8] == 'O') || (board[3] == 'O' && board[4] == 'O' && board[5] == 'O') || 
            (board[1] == 'O' && board[4] == 'X' && board[7] == 'O') || (board[2] == 'O' && board[5] == 'O' && board[8] == 'O') || 
            (board[6] == 'O' && board[7] == 'O' && board[8] == 'O') || (board[6] == 'O' && board[4] == 'O' && board[2] == 'O')) || 
            !((board[0] == 'X' && board[1] == 'X' && board[2] == 'X') || (board[0] == 'X' && board[3] == 'X' && board[6] == 'X') || 
            (board[0] == 'X' && board[4] == 'X' && board[8] == 'X') || (board[3] == 'X' && board[4] == 'X' && board[5] == 'X') || 
            (board[1] == 'X' && board[4] == 'X' && board[7] == 'X') || (board[2] == 'X' && board[5] == 'X' && board[8] == 'X') || 
            (board[6] == 'X' && board[7] == 'X' && board[8] == 'X') || (board[6] == 'X' && board[4] == 'X' && board[2] == 'X'))) {
        return true;
    } else {
        return false;
    }

}
}

EDIT: shoot, I accidentally posted before I was done typing. I think the error is in processComputerMove/processHumanMove methods, because even when I put just print statements in there, nothing shows up from them when I run the program.

1 Answers1

1

Your isTie() method is one of the culprits.

Looking at it with a debugger, I observe that your boolean statements to check for a "tie" condition are evaluation to true every time.

Yes, I mean this monster statement:

(!((board[0] == 'O' && board[1] == 'O' && board[2] == 'O') || (board[0] == 'O' && board[3] == 'O' && board[6] == 'O') ||
            (board[0] == 'O' && board[4] == 'O' && board[8] == 'O') || (board[3] == 'O' && board[4] == 'O' && board[5] == 'O') ||
            (board[1] == 'O' && board[4] == 'X' && board[7] == 'O') || (board[2] == 'O' && board[5] == 'O' && board[8] == 'O') ||
            (board[6] == 'O' && board[7] == 'O' && board[8] == 'O') || (board[6] == 'O' && board[4] == 'O' && board[2] == 'O'))

The actual evaluation is false, but since you negate it, you flip the value to true, thus short-circuiting your entire expression, causing you to (eventually) return true.

My gut tells me that your definition of a tie is skewed - wouldn't a tie be easier defined as neither a human win, nor a computer win?

If we trim down the isDone() method to only look at isHumanWin and isComputerWin (as well as get rid of the useless method calls at the top), and delete the unnecessary isTie method, we get a (mostly) playable Tic-Tac-Toe game. It kind of peters out towards the fourth move, but that is an exercise to the reader.

private static boolean isDone() {
    return isComputerWin() || isHumanWin();
}
Makoto
  • 104,088
  • 27
  • 192
  • 230