-1

プログラムが迷路全体を生成するように、境界チェックをどこに配置すればよいですか? このコードは、セル間の壁を壊して描かれた迷路を含むグリッドを出力する必要があります。しかし、非常に残念なことに、グリッドはインデックス 0 または 24 に達すると停止します。停止する前にすべてのセルにアクセスするプログラムが必要です (境界線に到達すると、元に戻ります)。

これが私が得ている以前のエラーです:

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;}
}
4

1 に答える 1

0

私はあなたのコードをすぐに見落としました:

  1. 座標が空のときに top() または pop() を呼び出しているときに例外が発生する可能性があります->座標.get(coordinates.size()-1)サイズが0の場合、インデックス-1に対処しようとします-> BAM!

  2. 一部のメソッドは非常に複雑に見えます。その機能を別々のメソッド/関数に分割できます

  3. AWT と SWING コンポーネントは異なる動作をするため、混在させないでください。

  4. Event Dispatcher Thread (EDT) から GUI 操作 (表示、非表示、コンテンツの変更、クリックなど、JFrame、JPanel など) を実行しないでください -> デッドロックが発生する可能性があります

于 2012-04-09T14:55:46.277 に答える