2012-04-09 5 views
-1

Где я устанавливаю проверку границ, чтобы программа генерировала весь лабиринт? Код должен печатать сетку с помощью лабиринта, нарисованного разбитыми стенами между ячейками. Однако, к моему ужасу, сетка останавливается, когда она достигает индекса 0 или 24. Мне нужно, чтобы программа посещала каждую ячейку до ее остановки (если она идет на границу, она возвращается).OutOfBoundsException. Где поставить Bounds-Checking?

Вот предыдущая ошибка, что я получаю:

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 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) { 
     Frame y = new Frame(); 
     y.setLayout(new BorderLayout()); 
     Panel r = new Panel(); 
     r.setLayout(new BorderLayout()); 
     Grid f = new Grid(25, 400, 400); 
     r.add(f, BorderLayout.CENTER); 
     y.add(r, BorderLayout.CENTER); 
     f.genRand(); 
     f.repaint(); 
     y.pack(); 
     y.setPreferredSize(new Dimension(450, 450)); 
     y.setVisible(true); 
    } 

    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); 
     while(m<1){ 
      m = randomInt(size); 
     } 
     while(n<1){ 
      n = randomInt(size); 
      } 
     Cell curCel = maze[m][n]; 
     // set VisitedCells = 1 
     int visCel = 1; 
     int o = 0; 
     int p = 0; 
     int h; 
     int d; 
     int[] q; 
     // while VisitedCells < TotalCells 
     while(visCel < TotalCells){ 
      d = 0; 
      // find all neighbors of CurrentCell with all walls intact 
      if(m!=0&&n!=0){ 
       if(m<size&&n<size){ 
        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

извините за это, просто сумасшедший здесь, нуждающийся в исправлении. Я попытался исправить свой код, но он до сих пор не удовлетворяет меня, так как, когда он достигает цели, он останавливается, а не выходит из строя. –

+0

Я также подумал о заявлении try-catch ... я должен положить все, если в try {}? –

+1

Ваш код пытается посмотреть, существует ли индекс -1 или индекс 25, и, конечно же, он генерирует исключение, потому что такого элемента массива нет. Вы можете просто добавить инструкцию проверки, если она выходит из строя, или вы можете исправить логику программы. – mbaydar

ответ

0

я проглядел ваш код очень быстро:

  1. вы можете получить свои исключения при вызове top() или pop(), когда координаты пусты. -> координаты .get (coord.size() - 1), если размер равен 0, вы пытаетесь обратиться к индексу -1 -> BAM!

  2. некоторые методы выглядят очень сложными. вы можете разделить эту функциональность, в отдельных методах/функции

  3. не смешивать AWT и SWING компоненты, так как ведет себя различные

  4. НИКОГДА не делать GUI вещи (показывая, прятался, меняющееся содержание, нажав, независимо в JFrame, JPanel и т. Д.) Из Event Dispatcher Thread (EDT) -> это может привести к блокировке замков

Смежные вопросы