プログラムが迷路全体を生成するように、境界チェックをどこに配置すればよいですか? このコードは、セル間の壁を壊して描かれた迷路を含むグリッドを出力する必要があります。しかし、非常に残念なことに、グリッドはインデックス 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;}
}