Reputation: 49
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
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
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