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");
}
}
}
}