回溯迷宫算法

时间:2013-09-10 05:27:01

标签: java algorithm backtracking maze

我遇到了一些实现回溯以解决迷宫的问题,我遇到的问题是,如果玩家走到了死胡同,它就不会回到它有另一个解决方案的地方。在我刚开始巧合的情况下,由于方法的顺序,它起作用,但是如果我认为玩家首先向东移动,它就会达到死胡同并且不会回溯。这是代码:

import java.util.ArrayList;

public class Laberinto {

    int posicionX = 0;
    int posicionY = 0;

    int largo = 6;
    int ancho = 6;

    int solX = 5;
    int solY = 4;

    boolean[][] cordenadas = new boolean[largo][ancho];

    int[] bloqueadasX = {1,2,3,4,5,5,0,2,3,4,5,0,2,3,4,5,3,0,1,5};
    int[] bloqueadasY = {0,0,0,0,0,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5};

    public ArrayList<Coordenada> recorridas = new ArrayList<Coordenada>();

    public Laberinto(int xo,int yo) {
        posicionX = xo;
        posicionY = yo;

        recorridas.add(new Coordenada(posicionX,posicionY));
    }

    public void recorrer() {

        if(posicionX==solX && posicionY == solY) {
            System.out.println("Solucion encontrada");
        }
        else {
            if(este(posicionX,posicionY)) recorrer();
            if(norte(posicionX,posicionY)) recorrer();
            if(sur(posicionX,posicionY)) recorrer();

            if(oeste(posicionX,posicionY)) recorrer();

            volver(new Coordenada(posicionX,posicionY));
        }
    }

    public void armarLaberinto() {

        for(int i=0;i<ancho;i++) {  
            for(int j=0;j<largo;j++) {
                    cordenadas[j][i] = estaBloqueada(j,i);  
            }       
        }

    }

    public boolean estaBloqueada(int x,int y) {

        for(int i=0;i<bloqueadasX.length;i++) {
            if(x==bloqueadasX[i] && y==bloqueadasY[i]) {
                return true;
            }
        }

        return false;
    }

    public boolean norte(int x,int y) {

            if(dentroTablero(x,y-1)) {

                if(!yaRecorrido(new Coordenada(x,y-1))) {

                    if(estaBloqueada(x,y-1)) {
                        return false;
                    }
                    posicionY = posicionY-1;
                    recorridas.add(new Coordenada(x,y));

                    return true;
                }
                return false;
            }
            return false;

    }

    public boolean sur(int x,int y) {

        if(dentroTablero(x,y+1)) {

            if(!yaRecorrido(new Coordenada(x,y+1))) {

                if(estaBloqueada(x,y+1)) {
                    return false;
                }
                posicionY = posicionY+1;
                recorridas.add(new Coordenada(x,y));

                return true;
            }
            return false;
        }
        return false;

        }
     public boolean este(int x,int y) {

            if(dentroTablero(x+1,y)) {

                if(!yaRecorrido(new Coordenada(x+1,y))) {

                    if(estaBloqueada(x+1,y)) {
                        return false;
                    }
                    posicionX = posicionX+1;
                    recorridas.add(new Coordenada(x,y));

                    return true;
                }
                return false;
            }
            return false;
    }

    public boolean oeste(int x,int y) {

            if(dentroTablero(x-1,y)) {

                if(!yaRecorrido(new Coordenada(x-1,y))) {

                    if(estaBloqueada(x-1,y)) {
                        return false;
                    }
                    posicionX = posicionX-1;
                    recorridas.add(new Coordenada(x,y));

                    return true;
                }
                return false;
            }
            return false;
    }

    public boolean dentroTablero(int x, int y) {
        if((x >=0 && x<=ancho) && (y>=0 && y<=largo) ) {
            return true;
        }
        return false;
    }

    public boolean yaRecorrido(Coordenada a) {

        for(int i=0;i<recorridas.size();i++) {
            if(recorridas.get(i).getX() == a.getX() && recorridas.get(i).getY() == a.getY()) {
                return true;
            }
        }
        return false;
    }

    public void volver(Coordenada a) {  
        recorridas.remove(a);
    }

    public void bloqueadas() {

            armarLaberinto();

            for(int i=0;i<ancho;i++) {  
                for(int j=0;j<largo;j++) {

                    if(!cordenadas[j][i]) {

                        if(j==solX && i==solY) {
                            System.out.print("M");

                        }
                        else {
                            System.out.print(" ");
                        }
                    }
                    else {
                        System.out.print("◘");
                    }
                }
                System.out.println();
            }

        }

    public void mostrarRecorrido() {

        armarLaberinto();

        for(int i=0;i<ancho;i++) {  
            for(int j=0;j<largo;j++) {

                if(!cordenadas[j][i]) {

                    if(j==solX && i==solY) {
                        System.out.print("M");

                    }
                    else {

                        if(yaRecorrido(new Coordenada(j,i))) {
                            System.out.print("•");
                        }
                        else {
                        System.out.print(" ");
                        }
                    }
                }
                else {
                    System.out.print("◘");
                }
            }
            System.out.println();
        }

    }

    public static void main(String[] args) {
        Laberinto laberinto = new Laberinto(0,0);
        laberinto.armarLaberinto();
        laberinto.bloqueadas();
        laberinto.recorrer();
        laberinto.mostrarRecorrido();

        System.out.println(laberinto.posicionX);
        System.out.println(laberinto.posicionY);
    }

}

1 个答案:

答案 0 :(得分:0)

一个可能的错误是你的职位具有全局性。一旦第一次调用无法找到解决方案,这将使您的搜索混淆不清。如果可能的话,尽量将posicionX,posicionY保留为该功能的本地。