Michael Simanski
Michael Simanski

Reputation: 49

Array index out of bounds while traversing edge members of array

I am creating a random maze generator in Java using the recursive backtracker algorithm. I need to set the edges of my maze cell data array to have been already visited by the algorithm so that it won't step out of bounds. The problem is probably staring me right in the face, I just cannot see where my error is.

Here is the whole error message:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30
    at mazeMaker.Maze.initBoundries(Maze.java:55)
    at mazeMaker.Maze.<init>(Maze.java:46)
    at mazeMaker.Main.main(Main.java:8)

I have tried tracing the error as best I could and experimented with changing my variables. The program relies on multiple class files, so I think it would be best just to show the whole thing.

Main.java

package mazeMaker;

public class Main 
{

    public static void main(String[] args) 
    {
        Maze mainMaze = new Maze(20, 30);
    }

}

Maze.java

package mazeMaker;

import java.util.Random;
import java.util.Stack;

public class Maze 
{
    public int xSize = 0;
    public int ySize = 0;
    public int totalDimensions = 0;

    Random randomGenerator = new Random();

    public Cell[][] cellData;

    public Stack<Cell> cellStack = new Stack<Cell>();

    Cell tempCell; // Temporary variable used for maze generation

    public Maze(int xSize, int ySize) 
    {
        cellData = new Cell[xSize][ySize];
        this.xSize = xSize;
        this.ySize = ySize;
        this.totalDimensions = this.xSize * this.ySize;

        // Initialize array objects
        for (int i = 0; i < this.xSize; i++) 
        {
            for (int j = 0; j < this.ySize; j++) 
            {
                cellData[i][j] = new Cell();
            }
        }

        // Assign x and y positions
        for (int i = 0; i < this.xSize; i++) 
        {
            for (int j = 0; j < this.ySize; j++) 
            {
                cellData[i][j].xPos = i;
                cellData[i][j].yPos = j;
            }
        }

        initBoundries();
    }

    private void initBoundries() 
    {
        // Initialize the border cells as visited so we don't go out of bounds      
        for (int col = 0; col < this.xSize; col++)
        {
                cellData[0][col].hasBeenVisited  = true;
                cellData[this.ySize][col].hasBeenVisited = true;
        }

        for (int row = 0; row < this.ySize; row++)
        {
                cellData[row][0].hasBeenVisited =  true;
                cellData[row][this.xSize].hasBeenVisited = true;
        }
    }

    private void generateMaze(int x, int y) 
    {
        // Set current cell as visited
        cellData[x][y].hasBeenVisited = true;

        // While there are unvisited neighbors
        while (!cellData[x][y+1].hasBeenVisited || !cellData[x+1][y].hasBeenVisited || !cellData[x][y-1].hasBeenVisited || !cellData[x-1][y].hasBeenVisited) 
        {
            // Select a random neighbor
            while (true) 
            {
                int r = randomGenerator.nextInt(4);
                if (r == 0 && !cellData[x][y+1].hasBeenVisited) 
                {
                    cellStack.push(cellData[x][y]);
                    cellData[x][y].hasNorthWall = false;
                    cellData[x][y+1].hasSouthWall = false;
                    generateMaze(x, y + 1);
                    break;
                }
                else if (r == 1 && !cellData[x+1][y].hasBeenVisited) 
                {
                    cellStack.push(cellData[x][y]);
                    cellData[x][y].hasEastWall = false;
                    cellData[x+1][y].hasWestWall = false;
                    generateMaze(x+1, y);
                    break;
                }
                else if (r == 2 && !cellData[x][y-1].hasBeenVisited) 
                {
                    cellStack.push(cellData[x][y]);
                    cellData[x][y].hasSouthWall = false;
                    cellData[x][y-1].hasNorthWall = false;
                    generateMaze(x, y-1);
                    break;
                }
                else if (r == 3 && !cellData[x-1][y].hasBeenVisited) 
                {
                    cellStack.push(cellData[x][y]);
                    cellData[x][y].hasWestWall = false;
                    cellData[x-1][y].hasEastWall = false;
                    generateMaze(x-1, y);
                    break;
                }
            }
        }

        // There are no unvisited neighbors
        tempCell = cellStack.pop();
        generateMaze(tempCell.xPos, tempCell.yPos);

    }

    // Begin generating maze at top left corner
    private void generateMaze() 
    {
        generateMaze(1,1);
    }

}

Cell.java

package mazeMaker;

public class Cell 
{
    public boolean isCurrentCell;
    public boolean hasBeenVisited;
    public boolean hasNorthWall;
    public boolean hasSouthWall;
    public boolean hasEastWall;
    public boolean hasWestWall;
    public int xPos;
    public int yPos;
}

Upvotes: 1

Views: 168

Answers (2)

Manh Le
Manh Le

Reputation: 1650

My guess is from this code in initBoundries()

    // Initialize the border cells as visited so we don't go out of bounds      
    for (int col = 0; col < this.xSize; col++)
    {
            cellData[0][col].hasBeenVisited  = true;
            cellData[this.ySize][col].hasBeenVisited = true;
    }

this.ySize after initialize (from constructor) has value 30.

Upvotes: 2

Kartik
Kartik

Reputation: 7907

cellData[this.ySize][col].hasBeenVisited = true;

You have initialized your cellData as cellData[20][30], but in the above-mentioned line you are calling cellData[30][col]. Instead of 30, the first bracket should have a value from 0 to 19, because the row size is 20.

Upvotes: 2

Related Questions