Valhalla Legends Archive

Programming => General Programming => Java Programming => Topic started by: Dynobird on July 31, 2005, 04:24 PM

Title: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: Dynobird on July 31, 2005, 04:24 PM
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[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[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();
    }
}

Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: Kp on July 31, 2005, 05:05 PM
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').
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: K on July 31, 2005, 05:06 PM
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:


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


try something like this to verify the user input:

int r;
do
{
   System.out.println("Which row?");
   r = in.read();
}while(r < 0 || r > 2);
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: Kp on July 31, 2005, 06:04 PM
Quote from: K on July 31, 2005, 05:06 PMtry something like this to verify the user input:

int r;
do
{
   System.out.println("Which row?");
   r = in.read();
}while(r < 0 || r > 2);

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 r = in.read() - '0'; for the actual input, along with the rest of K's code.
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: Dynobird on July 31, 2005, 07:21 PM
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...?)
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: K on July 31, 2005, 10:18 PM
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..
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: MyndFyre on August 01, 2005, 09:04 PM
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:


new TicTacToe();


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.
Title: Re: Problem with Arrays - ArrayIndexOutOfBoundsException
Post by: Dynobird on August 01, 2005, 09:29 PM
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:


/*
* 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();
    }
}