Rafael Leal-Mccormack
Rafael Leal-Mccormack

Reputation: 63

Assistance with Tic Tac Toe program

I've been working on for awhile but i can't seem to fix it and get it to wrong correctly. It tells me where the exception is but I don't see any problems.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at TicTacToe.displayWinner(TicTacToe.java:243)
    at TicTacToe.playerMove(TicTacToe.java:151)
    at TicTacToe.playGame(TicTacToe.java:303)
    at TicTacToeTester.main(TicTacToeTester.java:20)

Java Result: 1
import java.util.Scanner; //Used for player's input in game

public class TicTacToe 
{ 
    //instance variables
    private char[][] board; //Tic Tac Toe Board, 2d array
    private boolean xTurn; // true when X's turn, false if O's turn
    private Scanner input; // Scanner for reading input from keyboard

    //Constants for creation of gameboard
    public final int ROWS = 3; //total rows
    public final int COLS = 3; //total columns
    public final int WIN = 3; //amount needed to win

    public TicTacToe()    
    {
        //creates the board
        board = new char[ROWS][COLS];

        for(int r = 0; r < ROWS; r++)
        {
            for(int c = 0; c < COLS; c++)
            {   
                board[r][c] = ' ';
            }
        }

        //X's turn when game starts
        xTurn = true; 

        //creates our input object for the turn player
        input = new Scanner(System.in);
    }

    //shows game board
    public void displayBoard()

    {   
    int colNum = 0; //number of columns
    int rowNum = 0; //number of rows

    //creates column labels
    System.out.println(" \n");
    System.out.println("     Columns ");
    for (int num = 0; num < COLS; num++)
    {
        System.out.print("   " + colNum);
        colNum++;
    }

    //creates vertical columns and spaces between each spot 
    System.out.println(" \n");
    for (int row = 0; row < ROWS; row++) 
    {
        //numbers rows
        System.out.print(" " + rowNum + "  ");
        rowNum++;

        for (int col = 0; col < COLS; ++col) 
        {

            System.out.print(board[row][col]); // print each of the cells

            if (col != COLS - 1) 
            {
                System.out.print(" | ");   // print vertical partition
            }   
     }

     System.out.println();

     //creates seperation of rows
     if (row != ROWS - 1) 
     {
        System.out.println("   ------------"); // print horizontal 
   partition
     }

    }
    //labels row
    System.out.println("Rows \n");
    }

    //displays turn player
    public void displayTurn()
    {
        if (xTurn)
        {
            System.out.println("X's Turn");

        }
        else
        {
            System.out.println("O's Turn");
        }
    }

    //allows you to make move
    public boolean playerMove()
    {
        boolean invalid = true;
        int row = 0;
        int column = 0;

        while(invalid)
        {
            System.out.println("Which row (first) then column (second)
 would you like to \n"
                    + "play this turn? Enter 2 numbers between 0-2 as \n"
                    + "displayed on the board, seperated by a space to 
 \n"
                    + "choose your position.");

            row = input.nextInt();
            column = input.nextInt();

            //checks if spot is filled
            if (row >= 0 && row <= ROWS - 1 && 
            column >= 0 && column <= COLS - 1)
            {
                if (board[row][column] != ' ')
                {
                    System.out.println("Spot is taken \n");
                }
                else
                {
                    invalid = false;
                }

            }
            else
            {
                System.out.println("Invalid position");
            }

            //fills spot if not taken
            if (xTurn)
            {
                board[row][column] = 'X';
            }
            else
            {
                board[row][column] = 'O';
            }
        }
        return displayWinner(row,column);       
    }

    public boolean displayWinner(int lastR, int lastC)
    {
        boolean winner = false;
        int letter = board[lastR][lastC];

        //checks row for win
        int spotsFilled = 0;
        for (int c = 0; c < COLS; c++)
        {
            if(board[lastR][c] == letter)
            {
                spotsFilled++;
            }
        }

        if (spotsFilled == WIN)
        {
            winner = true;

            if (xTurn)
            {
                System.out.println("X won");
                displayBoard();
            }
            else
            {
                System.out.println("O won");
                displayBoard();
            }
        }

        //checks columns for win
        spotsFilled = 0;
        for (int r = 0; r < ROWS; r++)
        {
            if(board[r][lastC] == letter)
            {
                spotsFilled++;
            }
        }

        if (spotsFilled == WIN)
        {
            winner = true;
            if (xTurn)
            {
                System.out.println("X won");
                displayBoard();
            }
            else
            {
                System.out.println("O won");
                displayBoard();
            }
        }

        //checks diagonals for win
        spotsFilled = 0;
        for (int i = 0; i < WIN; i++)
        {
            if(board[i][i] == letter)
            {
                spotsFilled++;
            }
        }

        if(spotsFilled == WIN)
        {
            winner = true;
            if (xTurn)
            {
                System.out.println("X won");
                displayBoard();


            }
            else
            {
                System.out.println("O won");
                displayBoard();


            }
        }

        //checks other diagonal
        spotsFilled = 0;
        for(int i = 0; i < WIN; i++)
        {
            if(board[i][COLS-i] == letter)
            {
                spotsFilled++;
            }
        }
        if(spotsFilled == WIN)
        {
            winner = true;
            if (xTurn)
            {
                System.out.println("X won");
                displayBoard();


            }
            else
            {
                System.out.println("O won");
                displayBoard();


            }
        }


        return winner;
    }

//checks if board is full
public boolean fullBoard()
{
    int filledSpots = 0;

    for(int r = 0; r < ROWS; r++)
    {
        for (int c = 0; c < COLS; c++)
        {
            if (board[r][c] == 'X' || board[r][c] == 'O')
            {
                filledSpots++;
            }
        }
    }
    return filledSpots == ROWS*COLS;
}

//plays game
public void playGame()
{
    boolean finish = true;
    System.out.println("Are your ready to start?");
    System.out.println("1 for Yes or 0 for No? : ");
    int choice = input.nextInt();
    if (choice == 1)
        {
    while (finish)
    {
        displayBoard();
        displayTurn();

        if (playerMove())
        {
            displayBoard();

        }
        else if (fullBoard())
        {
            displayBoard(); 
            System.out.println("Draw");


        }
        else
        {
            xTurn=!xTurn;
        }

        }

    }
}
}

my tester

public class TicTacToeTester {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {

    TicTacToe tictactoe = new TicTacToe();

    tictactoe.playGame();
}

}

Upvotes: 0

Views: 226

Answers (2)

Andrew Alderson
Andrew Alderson

Reputation: 903

The reason you are getting your exception is this section of code inside your displayWinner method:

//checks other diagonal
    spotsFilled = 0;
    for(int i = 0; i < WIN; i++)
    {
        if(board[i][COLS-i] == letter)
        {
            spotsFilled++;
        }
    }

When i = 0 then COLS-i will be 3. This is outside the bounds of your array.

There are multiple ways to solve this, one would be to increase i by 1 during comparison.

//checks other diagonal
    spotsFilled = 0;
    for(int i = 0; i < WIN; i++)
    {
        if(board[i][COLS-(i+1)] == letter)
        {
            spotsFilled++;
        }
    }

Edit: also make sure you check out Null Saints answer, as it will cause you headaches later if you don't address it now.

Upvotes: 2

user5342366
user5342366

Reputation:

Your Player Move method has an issue take a look at this if you notice you have commented saying "// fills spot when not taken" but you misplaced the while loop bracket and included move part inside it so it threw that exception, just close the while loop bracket before moving as follows (also follow @oblivion Creations Answer these are the two issues with your code) :-

public boolean playerMove()
{
    boolean invalid = true;
    int row = 0;
    int column = 0;

    while (invalid)
    {
        System.out.println("Which row (first) then column (second)" + "would you like to \n"
                + "play this turn? Enter 2 numbers between 0-2 as \n"
                + "displayed on the board, seperated by a space to" + "\n" + "choose your position.");

        row = input.nextInt();
        column = input.nextInt();

        // checks if spot is filled
        if (row >= 0 && row <= ROWS - 1 && column >= 0 && column <= COLS - 1)
        {
            if (board[row][column] != ' ')
            {
                System.out.println("Spot is taken \n");
            }
            else
            {
                invalid = false;
            }

        }
        else
        {
            System.out.println("Invalid position");
        }
    } // close while loop here
        // fills spot if not taken
        if (xTurn)
        {
            board[row][column] = 'X';
        }
        else
        {
            board[row][column] = 'O';
        }

    return displayWinner(row, column);
} 

Upvotes: 3

Related Questions