我已经写了一个解决迷宫的程序,现在我正在写一个Java程序来创建迷宫(迷宫是黑白的32x32 png文件)。我需要能够指示迷宫的程序特性,同时允许一定程度的随机性,这样即使在输入相同参数的情况下,迷宫也不总是相同的。我要解决这个问题的方法是,首先绘制解决方案路径,然后用额外的路径修饰迷宫以隐藏解决方案。但是我不确定应该如何创建解决方案路径。这是我卡在正方形上的那些问题之一,我在想也许我应该分段组装路径,绘制几个方程式的范围,然后将它们拼合在一起,但是我将如何确保构造最终使它完成,而又不交叉很多次,以至于有几种方法可以完成迷宫?任何想法将不胜感激。
编辑:我使用了答案中描述的算法的一种变体,该算法的工作方式是创建解决方案路径,然后添加分支/错误的解决方案。它被编程为在建立分支超过设置的长度后尝试连接到主路径。但是分支由于某种原因只会相互连接,而不会连接到路径。我尽可能地包含了尽可能多的源代码,而不会引起混淆,我当然愿意提供任何其他信息。
public static void main(String[] args) throws IOException {
DrawingPanel panel = new DrawingPanel(width, height);
Graphics g = panel.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
panel.zoom(8);
List redsListX = new List();
List redsListY = new List();
int counter = 0;
for (int i = 2; i < height-2; i = i + 2) {
for (int j = 2; j < width-2; j = j + 2) {
panel.setPixel(i, j, Color.RED);
redsListX.add(Integer.toString(counter), j);
redsListY.add(Integer.toString(counter), i);
}
}
System.out.println("Grid frame set!");
buildSolutionPath(bias1,bias2,panel);
removeGreen(panel);
System.out.println("Done building solution path!");
addBranches(panel);
System.out.println("Branches are done!");
removeGreen(panel);
System.out.println("Maze is completed!");
panel.save("GeneratedMaze.png");
}
public static void buildSolutionPath(int bias1, int bias2, DrawingPanel panel){
int posX = 2;
int posY = 2;
int posX2 = 2;
int posY2 = 2;
int posX3 = 2;
int posY3 = 2;
panel.setPixel(posX,posY,Color.GREEN);
while(posX+posY!=64) {
int rand = randomInt(bias1, bias2, 1, 4);
if(rand==1 && panel.getRed(panel.getPixelRGB(posX, posY+2))==255){//what happens if rand equals a non-red tile?
panel.setPixel(posX,posY+1,Color.GREEN);
panel.setPixel(posX,posY+2,Color.GREEN);
posY = posY+2;
}
if(rand==2 && panel.getRed(panel.getPixelRGB(posX+2, posY))==255){
panel.setPixel(posX+1,posY,Color.GREEN);
panel.setPixel(posX+2,posY,Color.GREEN);
posX = posX+2;
}
if(rand==3 && panel.getRed(panel.getPixelRGB(posX, posY-2))==255){
panel.setPixel(posX,posY-1,Color.GREEN);
panel.setPixel(posX,posY-2,Color.GREEN);
posY = posY-2;
}
if(rand==4 && panel.getRed(panel.getPixelRGB(posX-2, posY))==255){
panel.setPixel(posX-1,posY,Color.GREEN);
panel.setPixel(posX-2,posY,Color.GREEN);
posX = posX-2;
} else if(panel.getRed(panel.getPixelRGB(posX, posY+2))!=255 && panel.getRed(panel.getPixelRGB(posX+2, posY))!=255 && panel.getRed(panel.getPixelRGB(posX, posY-2))!=255 && panel.getRed(panel.getPixelRGB(posX-2, posY))!=255) {
List bestGreen = findBestGreen(panel);
posX = Integer.parseInt(bestGreen.getItem(0));
posY = Integer.parseInt(bestGreen.getItem(1));
}
}
}
public static void addBranches(DrawingPanel panel) {
for (int i = 2; i < height - 2; i = i + 2) {
for (int j = 2; j < width - 2; j = j + 2) {
if (panel.getRed(panel.getPixelRGB(j, i)) == 255 && panel.getGreen(panel.getPixelRGB(j, i)) != 255) {
for (int counter = 0; counter < desiredBranchLength; counter++) {
int posX = j;
int posY = i;
int posX2 = j;
int posY2 = i;
int posX3 = j;
int posY3 = i;
int posX4 = j;
int posY4 = i;
int posX5 = j;
int posY5 = i;
int posX6 = j;
int posY6 = i;
int posX7 = j;
int posY7 = i;
int rand = randomInt(branchBias1, branchBias2, 1, 4);
panel.setPixel(j, i, Color.WHITE);
if (rand == 1 && panel.getRed(panel.getPixelRGB(posX, posY + 2)) == 255 && panel.getGreen(panel.getPixelRGB(posX, posY + 2)) != 255) {//what happens if rand equals a non-red tile?
panel.setPixel(posX, posY + 1, Color.WHITE);
posY7 = posY6;
posY6 = posY5;
posY5 = posY4;
posY4 = posY3;
posY3 = posY2;
posY2 = posY;
posY = posY + 2;
}
if (rand == 2 && panel.getRed(panel.getPixelRGB(posX + 2, posY)) == 255 && panel.getGreen(panel.getPixelRGB(posX + 2, posY)) != 255) {
panel.setPixel(posX + 1, posY, Color.WHITE);
posX7 = posX6;
posX6 = posX5;
posX5 = posX4;
posX4 = posX3;
posX3 = posX2;
posX2 = posX;
posX = posX + 2;
}
if (rand == 3 && panel.getRed(panel.getPixelRGB(posX, posY - 2)) == 255 && panel.getGreen(panel.getPixelRGB(posX, posY - 2)) != 255) {
panel.setPixel(posX, posY - 1, Color.WHITE);
posY7 = posY6;
posY6 = posY5;
posY5 = posY4;
posY4 = posY3;
posY3 = posY2;
posY2 = posY;
posY = posY - 2;
}
if (rand == 4 && panel.getRed(panel.getPixelRGB(posX - 2, posY)) == 255 && panel.getGreen(panel.getPixelRGB(posX - 2, posY)) != 255) {
panel.setPixel(posX - 1, posY, Color.WHITE);
posX7 = posX6;
posX6 = posX5;
posX5 = posX4;
posX4 = posX3;
posX3 = posX2;
posX2 = posX;
posX = posX - 2;
} else {//if no more reds to connect to, connect to white
if (connectWhite(posX,posY,panel)) {
} else if (connectWhite(posX7,posY7,panel)){
} else if (connectWhite(posX6,posY6,panel)){
} else if (connectWhite(posX5,posY5,panel)){
} else if (connectWhite(posX4,posY4,panel)){
} else if (connectWhite(posX3,posY3,panel)){
} else {
connectWhite(posX2,posY2,panel);
System.out.println("Branch failed to connect");
}
}
}
}
}
}
}
public static List findBestGreen(DrawingPanel panel){
List bestGreen = new List();
int bestGX = 2;
int bestGY = 2;
int bestGX2 = 2;
int bestGY2 = 2;
for (int i = 2; i < height-2; i = i + 2) {
for (int j = 2; j < width-2; j = j + 2) {
if(panel.getGreen(panel.getPixelRGB(j,i))==255) {
bestGX2 = j;
bestGY2 = i;
int c = bestGX + bestGY;
int c2 = bestGX2 + bestGY2;
int score1 = ((bestGX*buildBias2X)+(bestGY*buildBias2Y));
int score2 = ((bestGX2*buildBias2X)+(bestGY2*buildBias2Y));
if (c2==c||c-c2<=4||c2-c<=4 && score2>score1){
bestGX = bestGX2;
bestGY = bestGY2;
} else if(bestGX2+bestGY2>bestGX+bestGY){
bestGX = bestGX2;
bestGY = bestGY2;
}
}
}
}
System.out.println(bestGX+", "+bestGY);
bestGreen.add(Integer.toString(bestGX));
bestGreen.add(Integer.toString(bestGY));
return bestGreen;
}
public static void removeGreen(DrawingPanel panel){
for (int i = 2; i < height-2; i++) {
for (int j = 2; j < width-2; j++) {
if(panel.getGreen(panel.getPixelRGB(j,i))==255){
panel.setPixel(j,i,Color.WHITE);
}
}
}
}
public static boolean connectWhite(int posX, int posY, DrawingPanel panel) {//attempts to connect the newly constructed branch with the main path
if (panel.getGreen(panel.getPixelRGB(posX + 2, posY))==255 && panel.getRed(panel.getPixelRGB(posX+2,posY))!=255) {
panel.setPixel(posX + 1, posY, Color.GREEN);
panel.setPixel(posX + 2, posY, Color.GREEN);
return true;
} else if (panel.getGreen(panel.getPixelRGB(posX-2, posY))==255 && panel.getRed(panel.getPixelRGB(posX-2,posY))!=255) {
panel.setPixel(posX - 1, posY, Color.GREEN);
panel.setPixel(posX - 2, posY, Color.GREEN);
return true;
} else if (panel.getGreen(panel.getPixelRGB(posX, posY+2))==255 && panel.getRed(panel.getPixelRGB(posX,posY+2))!=255) {
panel.setPixel(posX, posY + 1, Color.GREEN);
panel.setPixel(posX, posY + 2, Color.GREEN);
return true;
} else if (panel.getGreen(panel.getPixelRGB(posX, posY-2))==255 && panel.getRed(panel.getPixelRGB(posX,posY-2))!=255) {
panel.setPixel(posX, posY - 1, Color.GREEN);
panel.setPixel(posX, posY - 2, Color.GREEN);
return true;
} else {
return false;//if return is false, it means there were no options for connecting the branch to the solution path
}
}