Valhalla Legends Forums Archive | Java Programming | Problem with Arrays - ArrayIndexOutOfBoundsException

AuthorMessageTime
Dynobird
Code:
/*
* Hi, I'm writing a TicTacToe program (that is not yet finished) which
* compiled without any errors.. but when I run the code it says
* "ArrayIndexOutOfBoundsException: 49." What does this mean?
* I've tried try/catch blocks and throwing the exceptions in my methods
* but this doesn't work. Can someone please help me by explaining the problem
* and giving a solution? Thanks.
*/

import java.io.*;

public class TicTacToe {

    char[][] board = new char[3][3];
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in) );
   
    public TicTacToe() throws IOException {
       
        while(!gameOver()) {
            createBoard();
       
            //Player 1
            System.out.println("Which row?");
            int r = in.read();
            System.out.println("Which column?");
            int c = in.read();
            printInput(r, c, 'X');
           
            //Player 2
            System.out.println("\nWhich row?");
            r = in.read();
            System.out.println("Which column?");
            c = in.read();
            printInput(r, c, 'O');
        }
    }
   
    public void createBoard() {
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                board[i][j] = '_';
            }
        }
    }
   
    public void printInput(int row, int column, char input) throws ArrayIndexOutOfBoundsException {
        try {
            board[row][column] = input;
            //line 49 below
            for(int i = 0; i < 3; i++) {
                for(int j = 0; j < 3; j++) {
                    System.out.print(board[i][j] + " ");
                }
                System.out.print("\n");
            }
       
        }
        catch(ArrayIndexOutOfBoundsException e) {
        System.out.println(e);
        }
     
    }
   
    public boolean gameOver() {
        // I am going to add conditions in later; for now I am just testing out the rest of the code.
        return false;
    }
   
    public static void main(String[] args) throws IOException{
        System.out.println("Tic Tac Toe\n-----------------------\n");
        new TicTacToe();
    }
}

July 31, 2005, 9:24 PM
Kp
Aside from being horribly ugly since you forgot to use code tags, it looks OK to me.  Of course, a traceback of the failure would be nice.  Also, your TicTacToe array is much too small.  If you're going to be indexing it with characters, it needs to be at least [58][58], preferably more since it doesn't look like you're doing any input validation (i.e. the program will crash if you ask it for row 'z' instead of '1').
July 31, 2005, 10:05 PM
K
Take a look at what happens if the user inputs a number greater than 2  (or less than 0) for either the row or the column:

[code]
// first line of printInput
board[row][column] = input;
[/code]

try something like this to verify the user input:
[code]
int r;
do
{
  System.out.println("Which row?");
  r = in.read();
}while(r < 0 || r > 2);
[/code]
July 31, 2005, 10:06 PM
Kp
[quote author=K link=topic=12389.msg122649#msg122649 date=1122847568]try something like this to verify the user input:
[code]
int r;
do
{
  System.out.println("Which row?");
  r = in.read();
}while(r < 0 || r > 2);[/code][/quote]

Minor nit: I think he's going to have a difficult time typing NULs, and he's not going to expect needing to use ^A and ^B for rows 1 and 2. :)  Try using [code]r = in.read() - '0';[/code] for the actual input, along with the rest of K's code.
July 31, 2005, 11:04 PM
Dynobird
Thanks guys. It works now. I made my array bigger and used the do-while loops. What also was wrong was that the read() method wasn't reading my integers as I wanted them to. I made a little program to test this out...

<code>
import java.io.*;

public class ReadTest {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in) );

public ReadTest() throws IOException {
int num;
System.out.println("pick a number");
num = in.read();
System.out.println("You chose " + num + ".");
}

public static void main(String[] args) throws IOException {
new ReadTest();
}

}
</code>

When I input 1 it spat out 49! I guess this has something to do with it interpreting my input as ASCII? Is there a different class/method that interprets integers as integers?

Well, in a crude solution to this I got a class off the net called EasyReader which can be found at javamethods.com on the studentdisk. It makes user input a lot easier.

**EDIT: LOL that "html-like-stuff-in-my-java-program" must look silly. How do you use code tags (which I assume make your code go in the gray box...?)
August 1, 2005, 12:21 AM
K
Kp's addition to my code will fix the problem you are having.  I suggest you keep your arrays at size 3, since that's all you need.

Oh, replace the < and > with [ and ] to get the totally sweet code formatting..
August 1, 2005, 3:18 AM
Myndfyr
For the record, I believe it's bad practice to place execution code (or logic) in a constructor beyond that which is necessary to initialize a type.  You do that with:

[code]
new TicTacToe();
[/code]

A constructor is a method, yes, but it's a special kind of method -- one for allocating memory and initializing an object.  A method such as .runGame() would be great, or even .begin().

I simply think that a constructor should be as exception-free as possible, except to reject exceptional initialization values.  Since this one doesn't accept any parameters, and (should) perform no I/O, there should be no exception being thrown.
August 2, 2005, 2:04 AM
Dynobird
Thanks for the input everybody. Myndfyre I followed your advice about the constructor. I'm sort of new to programming so it's nice to get advice on form and "good practice." Here's the code:

[code]
/*
* Tic Tac Toe program
* by Dynobird
* Yes I know the code is ugly... I tried to make it easy to read
* How exciting, I'm using the code tags (correctly!!) for the first time!
*/

import java.io.*;

public class TicTacToe {

    EasyReader in = new EasyReader();
    char[][] board = new char[100][100];
    int r, c;
    int newGame;
   
    public TicTacToe() {}
   
    /****************** RUNS THE GAME ******************/
    public void runGame() throws IOException {
       
        System.out.println("Please input names");
        System.out.print("Player 1: ");
        String p1 = in.readLine();
        System.out.print("Player 2: ");
        String p2 = in.readLine();
        createBoard();
       
            while(!gameOver(newGame)) {
       
                // Ask player 1
                do {
                    System.out.println(p1 + ": Which row?");
                    r = in.readInt();
                } while( r < 0 || r >2 );
                do {
                    System.out.println(p1 + ": Which column?");
                    c = in.readInt();
                } while( c < 0 || r > 2);
                //Player 1 input and check if game is over
                printInput(r, c, 'X');
                if(gameOver(newGame)) {
                    System.out.println("\n" + p1 + " wins!");
                    break;
                }
           
                //Ask player 2
                do {
                    System.out.println(p2 + ": Which row?");
                    r = in.readInt();
                } while( r < 0 || r >2 );
                do {
                    System.out.println(p2 + ": Which column?");
                    c = in.readInt();
                } while( c < 0 || r > 2);
                //Player 2 input and check if game is over
                printInput(r, c, 'O');
                if(gameOver(newGame)) {
                    System.out.println("\n" + p2 + " wins!");
                    break;
                }
            }
            do {
                System.out.println("New game? 0. No 1. Yes :: ");
                int newGame = in.readInt();
                if (!gameOver(newGame) ) {
                    new TicTacToe();
                }
            } while( newGame < 0 || newGame > 1);
           
        System.out.println("\nThanks for playing. Have a nice day!");
       
    }
   
    /****************** PRINTS EMPTY BOARD ******************/
    public void createBoard() {
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                board[i][j] = '_';
                System.out.print(board[i][j] + " ");
            }
            System.out.print("\n");
        }
    }
   
    /****************** PRINTS USER INPUT ******************/
    public void printInput(int row, int column, char input) throws ArrayIndexOutOfBoundsException {
     
            board[row][column] = input;
            for(int i = 0; i < 3; i++) {
                for(int j = 0; j < 3; j++) {
                    System.out.print(board[i][j] + " ");
                }
                System.out.print("\n");
            }
    }
   
    /****************** CHECKS TO SEE IF GAME IS OVER ******************/
    public boolean gameOver(int newGameOrNot) {
        //new game yes or no?
        if( newGameOrNot == 1) {
            return false;
        }
       
        //rows
        for(int i = 0; i < 3; i++) {
            if( (board[i][0] == 'X' || board[i][0] == 'O') && (board[i][0] == board[i][1]) && (board[i][0] == board[i][2]) ) {
                return true;
            }
        }
       
        //columns
        for(int j = 0; j < 3; j++) {
            if( (board[0][j] == 'X' || board[0][j] == 'O') && (board[0][j] == board[1][j]) && (board[0][j] == board[2][j]) ) {
                return true;
            }
        }
       
        //diagonals
        if(
        ( (board[0][0] == 'X' || board[0][0] == 'O') && (board[0][0] == board[1][1]) && (board[0][0] == board[2][2]) ) ||
        ( (board[2][0] == 'X' || board[2][0] == 'O') && (board[2][0] == board[1][1]) && (board[2][0] == board[0][2]) )
        )
        {
        return true;
        }
       
        //if game is not over, continue while loop
        else {
        return false;
        }
    }
   
    /****************** CALLS CONSTRUCTOR ******************/
    public static void main(String[] args) throws IOException{
        System.out.println("Tic Tac Toe\n-----------------------\n");
        TicTacToe t3 = new TicTacToe();
        t3.runGame();
    }
}
[/code]
August 2, 2005, 2:29 AM

Search