2012-04-09 130 views
0

我的迷宫发生器似乎有问题。 我想产生something like this maze 我的程序显示这样的:迷宫无法正常生成。越界异常

enter image description here

和错误

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 
     at Grid.genRand(Grid.java:73) 
     at Grid.main(Grid.java:35) 

如何解决我的生成器程序?

import java.awt.*; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import javax.swing.*; 
import java.util.ArrayList; 

public class Grid extends Canvas { 

    Cell[][] maze; 
    int size; 
    int pathSize; 
    double width, height; 
    ArrayList<int[]> coordinates = new ArrayList<int[]>(); 

    public Grid(int size, int h, int w) { 
     this.size = size; 
     maze = new Cell[size][size]; 
     for(int i = 0; i<size; i++){ 
      for(int a =0; a<size; a++){ 
      maze[i][a] = new Cell(); 
      } 
     } 
     setPreferredSize(new Dimension(h, w)); 
    } 

    public static void main(String[] args) { 
     JFrame y = new JFrame(); 
     y.setLayout(new BorderLayout()); 
     Grid f = new Grid(25, 400, 400); 
     y.add(f, BorderLayout.CENTER); 
     y.setSize(450, 450); 
     y.setVisible(true); 
     y.setDefaultCloseOperation(y.EXIT_ON_CLOSE); 
     f.genRand(); 
     f.repaint(); 
    } 

    public void push(int[] xy) 
    { 
    coordinates.add(xy); 
    int i = coordinates.size(); 
    coordinates.ensureCapacity(i++); 
    } 

    public int[] pop() { 
    int[] x = coordinates.get((coordinates.size())-1); 
    coordinates.remove((coordinates.size())-1); 
    return x; 
    } 

    public int[] top() { 
    return coordinates.get((coordinates.size())-1); 
    } 

    public void genRand(){ 
    // create a CellStack (LIFO) to hold a list of cell locations [x] 
    // set TotalCells = number of cells in grid 
    int TotalCells = size*size; 
    // choose a cell at random and call it CurrentCell 
    int m = randomInt(size); 
    int n = randomInt(size); 
    Cell curCel = maze[m][n]; 
    // set VisitedCells = 1 
    int visCel = 1,d=0; 
    int[] q; 
    int h,o = 0,p = 0; 
    // while VisitedCells < TotalCells 
    while(visCel < TotalCells){ 
    // find all neighbors of CurrentCell with all walls intact 
    if(maze[m-1][n].countWalls() == 4){d++;} 
    if(maze[m+1][n].countWalls() == 4){d++;} 
    if(maze[m][n-1].countWalls() == 4){d++;} 
    if(maze[m][n+1].countWalls() == 4){d++;} 
    // if one or more found 
    if(d!=0){ 
    Point[] ls = new Point[4]; 
    ls[0] = new Point(m-1,n); 
    ls[1] = new Point(m+1,n); 
    ls[2] = new Point(m,n-1); 
    ls[3] = new Point(m,n+1); 
    // knock down the wall between it and CurrentCell 
    h = randomInt(3); 
    switch(h){ 
     case 0: o = (int)(ls[0].getX()); 
       p = (int)(ls[0].getY()); 
       curCel.destroyWall(2); 
       maze[o][p].destroyWall(1); 
      break; 
     case 1: o = (int)(ls[1].getX()); 
       p = (int)(ls[1].getY()); 
       curCel.destroyWall(1); 
       maze[o][p].destroyWall(2); 
      break; 
     case 2: o = (int)(ls[2].getX()); 
       p = (int)(ls[2].getY()); 
       curCel.destroyWall(3); 
       maze[o][p].destroyWall(0); 
      break; 
     case 3: o = (int)(ls[3].getX()); 
       p = (int)(ls[3].getY()); 
       curCel.destroyWall(0); 
       maze[o][p].destroyWall(3); 
      break; 
    } 
    // push CurrentCell location on the CellStack 
    push(new int[] {m,n}); 
    // make the new cell CurrentCell 
    m = o; n = p; 
    curCel = maze[m][n]; 
    // add 1 to VisitedCells 
    visCel++; 
    } 
    // else 
    else{ 
    // pop the most recent cell entry off the CellStack 
    q = pop(); 
    m = q[0]; n = q[1]; 
    curCel = maze[m][n]; 
    // make it CurrentCell 
    // endIf 
    } 
    // endWhile 
    } 
    } 

    public int randomInt(int s) { return (int)(s* Math.random());} 

    public void paint(Graphics g) { 
     int k, j; 
     width = getSize().width; 
     height = getSize().height; 
     double htOfRow = height/(size); 
     double wdOfRow = width/(size); 
//checks verticals - destroys east border of cell 
     for (k = 0; k < size; k++) { 
      for (j = 0; j < size; j++) { 
       if(maze[k][j].checkWall(2)){ 
       g.drawLine((int) (k * wdOfRow), (int) (j * htOfRow), (int) (k * wdOfRow), (int) ((j+1) * htOfRow)); 
      }} 
     } 
//checks horizontal - destroys north border of cell 
     for (k = 0; k < size; k++) { 
      for (j = 0; j < size; j++) { 
       if(maze[k][j].checkWall(3)){ 
       g.drawLine((int) (k * wdOfRow), (int) (j * htOfRow), (int) ((k+1) * wdOfRow), (int) (j * htOfRow)); 
      }} 
     } 
    } 
} 

class Cell { 

    private final static int NORTH = 0; 
    private final static int EAST = 1; 
    private final static int WEST = 2; 
    private final static int SOUTH = 3; 
    private final static int NO = 4; 
    private final static int START = 1; 
    private final static int END = 2; 
    boolean[] wall = new boolean[4]; 
    boolean[] border = new boolean[4]; 
    boolean[] backtrack = new boolean[4]; 
    boolean[] solution = new boolean[4]; 
    private boolean isVisited = false; 
    private int Key = 0; 

    public Cell(){ 
    for(int i=0;i<4;i++){wall[i] = true;} 
    } 
    public int countWalls(){ 
    int i, k =0; 
    for(i=0; i<4; i++) { 
    if (wall[i] == true) 
    {k++;} 
    } 
    return k;} 
    public boolean checkWall(int x){ 
    switch(x){ 
     case 0: return wall[0]; 
     case 1: return wall[1]; 
     case 2: return wall[2]; 
     case 3: return wall[3]; 
    } 
    return true; 
    } 
    public void destroyWall(int x){ 
    switch(x){ 
     case 0: wall[0] = false; break; 
     case 1: wall[1] = false; break; 
     case 2: wall[2] = false; break; 
     case 3: wall[3] = false; break; 
     } 
    } 
    public void setStart(int i){Key = i;} 
    public int getKey(){return Key;} 
    public boolean checkVisit(){return isVisited;} 
    public void visitCell(){isVisited = true;} 
} 

回答

0
int m = randomInt(size); 
int n = randomInt(size); 

那是你的问题。 nm可以为0

当您尝试:

if(maze[m-1][n].countWalls() == 4){d++;} 
if(maze[m+1][n].countWalls() == 4){d++;} 
if(maze[m][n-1].countWalls() == 4){d++;} 
if(maze[m][n+1].countWalls() == 4){d++;} 

你会试图让maze[-1][n]maze[m][-1]如果其中任何一个是0,这就是为什么你会得到异常的ArrayIndexOutOfBounds 。

+0

因此,如果我检查m和n,如果它们是0,我应该再次调用randomInt(size)? – 2012-04-09 10:44:44

+0

你必须看看你的算法的其余部分,看看是否会破坏任何东西,但是,它会修复这个错误。我只是看着你的异常和堆栈跟踪,看看在这个特殊情况下出了什么问题。 – 2012-04-09 10:47:33

+0

更好的是,您可以更改大小以接受两者的上限和下限,并确保它在该范围内生成一个数字。你还会想要考虑当randomInt生成'size'时会发生什么。当您尝试访问'迷宫[m + 1] [n]'或迷宫[m] [n + 1]'时,您将再次超出阵列的范围。 – 2012-04-09 10:49:12

0

你不是边界检查你对迷宫的访问。例如,如果m = 0,那么

maze[m-1][n] 

将访问

maze[-1][n] 

这是出界。