查找与给定终点,起点和最小匝数匹配的线的程序

时间:2019-03-22 01:05:43

标签: java maze

我已经写了一个解决迷宫的程序,现在我正在写一个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
    }
}

This is an example maze my program generated

1 个答案:

答案 0 :(得分:0)

有很多迷宫生成算法,但是我建议使用递归回溯算法。它快速,高效且易于编码。您可以在here上找到更多信息,以及其他一些算法。希望这会有所帮助。