Hi all! I am racking my brain trying to figure out why my code is not working for this TicTacToe board assignment. I keep getting the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at TTTBoard.makeMove(TTTBoard.java:79)
at TTTGame.main(TTTGame.java:59)
Java Result: 1

The assignment calls for a 3-by-3 2-dimensional array of integers. The constructor should initialize the empty board to all zeros (which I've done). Allow 2 human players. Wherever the first player moves, place a 1 in the specified square, and place a 2 wherever the second player moves. Each move must be to an empty square. After each move, determine whether the game has been won and whether it is a draw.
I am beginner with java and this has frustrated me for the last couple days that I can't figure this out. I do notice that when it asks to pick which row and column, and if I pick let's say row 3, col 3, it gives me the above error. It shouldn't even allow me to input a 3 in the 1st place as the main method error traps for that input. Plus I can't ever get the input to go in to the 1st row, and 1st col. I think there's issues in the makeMove and displayBoard methods. Please help. I'll put my code that I have, plus the main method:

/*
 * TTTBoard UML
 * ------------
 * - _board : int[3][3]
 * - _player : int
 * ------------
 * TTTBoard()
 * + makeMove(row : int, col : int) : boolean
 * + isBoardComplete() : boolean
 * + determineWinner() : int
 * + displayBoard()
 * + getCurrentPlayer() : int
 * ------------
 *
 * Descriptions:
 * TTTBoard constructs a 3x3 array of integers and sets all values to 0
 * makeMove tries to move at row,col. If it can, it does and returns true;
 *      if it can't, then it returns false
 * isBoardComplete returns true if there the board is completely full, no moves
 *      to be made
 * determineWinner sends back either 0 if there's no winner at this time, or
 *      1 or 2 if player 1 or player 2 won at this time
 * displayBoard does just that .. something like:
 *      _ _ 1
 *      2 1 _
 *      _ 2 1
 * getCurrentPlayer returns either a 1 or 2 depending on whose turn is is
 *      (the player).
 *
 */

/**
 *
 * @author YOU
 */
public class TTTBoard
{
    // Declare out class variables
    private int _player;
    private int _board[][];

    /**
     * 
     * @param numRow
     * @param numCol
     */
    public TTTBoard()
    {
        // Initializes private data
        _player = 1; // player1 always goes first, but could randomize it

        // Constructs 3 X 3 array of int for the board
        _board = new int[3][3];

        // Initializes all elements to the array of 0; nested for loop
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                _board[i][j] = 0;
            }
        }
    }

    /**
     * accepts row and col (parameters), if that position happens to be a 0
     * then it's okay to make a move, otherwise if occupied then it's still
     * that player's turn
     * @param row
     * @param col
     * @return
     */
    public boolean makeMove(int row, int col)
    {
        // Initialize boolean move
        boolean move;
        
        // Checks to see if board location is occupied and a move can be made
        if (_board[row][col] == 0)
        {
            _board[row][col] = _player;
            return true;

        }
        else
        {
            // The specified cell is already occupied.
            move = false;
        }
        return move;
    }

    /**
     *
     * @return
     */
    public boolean isBoardComplete()
    {
        boolean complete = true;

        for (int i = 0; i < 3; i++)
        {
            for(int j =0; j < 3; j++)
            {
                if (_board[i][j] == 0)
                {
                    complete = false;
                }
            }
        }
        return complete;
    }

    /**
     * This method helps determine who is the winner by going through the 3
     * rows, the 3 columns, and the 2 diagonal options (total of 8 possibilities)
     * @return
     */
    public int determineWinner()
    {
        // First check rows and columns
      	int winner = 0;

        // Check for winner in row 1
        if (_board[0][0] == _board[0][1] && _board[0][0] == _board[0][2] &&
                _board[0][0] != 0)
        {
            winner = _board[0][0];
        }

        // Check for winner in row 2
        if (_board[1][0] == _board[1][1] && _board[1][0] == _board[1][2] &&
                _board[1][0] != 0)
        {
            winner = _board[1][0];
        }

        // Check for winner in row 3
        if (_board[2][0] == _board[2][1] && _board[2][0] == _board[2][2] &&
                _board[2][0] != 0)
        {
            winner = _board[2][0];
        }

        // Check for winner in col 1
        if (_board[0][0] == _board[1][0] && _board[0][0] == _board[2][0] &&
                _board[0][0] != 0)
        {
            winner = _board[0][0];
        }

        // Check for winner in col 2
        if (_board[0][1] == _board[1][1] && _board[0][1] == _board[2][1] &&
                _board[0][1] != 0)
        {
            winner = _board[0][1];
        }

        // Check for winner in col 3
        if (_board[0][2] == _board[1][2] && _board[0][2] == _board[2][2] &&
                _board[0][2] != 0)
        {
            winner = _board[0][2];
        }

        // Check for winner in first diagonal
        if (_board[0][0] == _board[1][1] && _board[0][0] == _board[2][2] &&
                _board[0][0] != 0)
        {
            winner = _board[0][0];
        }

        // Check for winner in 2nd diagonal
        if (_board[2][0] == _board[1][1] && _board[2][0] == _board[0][2] &&
                _board[2][0] != 0)
        {
            winner = _board[2][0];
        }
        return winner;
    }

    /**
     * This method goes through array and prints out to screen what the board
     * looks like at that time, after input
     */
    public void displayBoard()
    {     
        // nested for loop to display the TTT board after each players input
        for ( int i = 0; i < 3; i++)
        {
            System.out.println("  ");

            for( int j = 0; j < 3; j++)
            {
                System.out.print(_board[i][j] + " ");
            }
            
            System.out.println("\n------");
        }
    }

    /**
     * This method gets the current player
     * @return
     */
    public int getCurrentPlayer()
    {
        return _player;
    }
}

Main class:
import java.util.Scanner;
/**
 *
 * @author 
 */
public class TTTGame
{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        // declare variables included in our TTT board
        TTTBoard myGame = new TTTBoard();
        Scanner input = new Scanner(System.in);
        int row;
        int col;
        
        // As long as there is no winner and there are still moves that can
        // be made, then play on. If these conditions happen game is over or we
        // have a draw
        while(myGame.determineWinner() == 0 && !myGame.isBoardComplete())
        {
            // dispaly the current board state
            myGame.displayBoard();

            // get the current move from the current player
            System.out.println("Player " + myGame.getCurrentPlayer());
            System.out.println("Make your move.");
            System.out.print("Row please (1-3):");
            row = input.nextInt();

            // error trap for valid row
            while(row < 1 || row > 3)
            {
                System.out.println("Invalid Row.");
                System.out.print("Try again (1-3):");
                row = input.nextInt();
            }

            System.out.print("Col please (1-3):");
            col = input.nextInt();

            // error trap for valid col
            while(col < 1 || col > 3)
            {
                System.out.println("Invalid Col.");
                System.out.print("Try again (1-3):");
                col = input.nextInt();
            }

            // while the move is invalid make them make another move
            while(!myGame.makeMove(row, col))
            {
                System.out.println("Invalid Move... Try Again.");
                System.out.print("Row please (1-3):");
                row = input.nextInt();

                // error trap for valid row
                while(row < 1 || row > 3)
                {
                    System.out.println("Invalid Row.");
                    System.out.print("Try again (1-3):");
                    row = input.nextInt();
                }

                System.out.print("Col please (1-3):");
                col = input.nextInt();

                // error trap for valid col
                while(col < 1 || col > 3)
                {
                    System.out.println("Invalid Col.");
                    System.out.print("Try again (1-3):");
                    col = input.nextInt();
                }
            }
        }

        // if we left the loop because the boards full and there's no winner
        // it must be a cats game
        if (myGame.determineWinner() == 0)
        {
            System.out.println("Sorry - Cat's Game");
        }
        else
        {
            // the last player to move won but the board has already advanced
            // the turn, therefore the winner is opposite of whose turn it is
            System.out.print("The Winner is Player ");
            if (myGame.getCurrentPlayer() == 1)
            {
                System.out.println("2");
            }
            else
            {
                System.out.println("1");
            }
        }
    }

}

Recommended Answers

All 2 Replies

You forced them to input a row between 1 and 3 and a column between 1 and 3. Your array has 3 rows and 3 columns. Arrays in Java (and most other languages) are indexed from 0 to (rows-1). Which means that your array's first cell is _board[0][0], and _board[3][3] is NOT a valid row or column.

In your makeMove method, you should convert rows and columns so that they can be used to index the array. Since the first row is indexed by 0, not by 1, all you have to do is subtract 1 from whatever the user inputs.

You're amazing! Thanks so much! It works great!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.