-2

我知道关于这个话题有很多问题。事实上,我正在寻找其他问题,并尝试使用一些解决方案,但这还不够。

我必须做一个模拟puffball的程序,使用回溯,现在我正在开发动作,当我移动时,我需要保存表格,因为这是一个可能的解决方案,所以问题是下一个:当我尝试保留表第一个保存正确,但添加下一个并覆盖较早的。我向您展示了代码,它不是全部,只有我认为对大家有用的方法和其他信息。

在 main() 中你可以看到我是如何获取所有信息的,然后当我开始玩时,我调用了 soplarBola(),在这里你可以看到问题所在。

对不起,因为都是西班牙语。我希望你能理解我的缺陷。

非常感谢!

public class Main {
    static Scanner sc = new Scanner(System.in);
    static int[] dimension = new int[2];
    static int numPoscionesFinales;
    static int numBolas;
    static ArrayList<Integer> totalIdBolas;
    static ArrayList<ArrayList<Integer>> totalesIdBolas;
    static ArrayList<int[]> coordenadasFinales;
    static ArrayList<int[]> coordenadasBolas;
    static Casilla ca;
    static ArrayList<Casilla> tablero;
    static ArrayList<ArrayList<Casilla>> tablerosSol;
    static ArrayList<Integer> bolasSopladas; //Recoge todos los caminos     posibles
    static ArrayList<ArrayList<Casilla>> tablerosVisitados;
    static ArrayList<ArrayList<Integer>> caminos; //Recoge los int[] que     contienen caminos solucion
    public static void main(String[] args) { 
        //Dimensiones del tablero
        //Numero de posiciones finales que son las mismas que bolas habra
        //Generamos un ArrayList con los idBolas posibles para despues     permutar todas las posibles soluciones y generar los tableros solucion con los que compararemos los     tableros que vayamos creando
            //coordenadas de posiciones finales
        //coordenadas de bolas

    crearTablero(dimension);
    crearTablerosSol(tablero,totalesIdBolas);
    bolasSopladas = new ArrayList<Integer>();
        resolverSoplarBola(bolasSopladas,tablero,totalesIdBolas,tablerosVisitados, caminos);
}

/* Esta es la semilla de la que nacerá el árbol solucion */
public static void resolverSoplarBola(ArrayList<Integer> bolasSopladas, ArrayList<Casilla> ta,
        ArrayList<ArrayList<Integer>> totalesIdBolas, ArrayList<ArrayList<Casilla>> tablerosVisit, ArrayList<ArrayList<Integer>> caminos) {

    ArrayList<Integer> solParcial = bolasSopladas;
    int nBolas = 1;
    caminos = new ArrayList<ArrayList<Integer>>();
    //imprimirTab1(ta,nBolas);
    while(nBolas<numBolas){
            //Sea b la bola que sopla  ...sopla y mueve todas las bolas generando un nuevo tablero añadido a tablerosVisitados
            tablerosVisit.add(soplarBola(nBolas,ta));
//          imprimirTableros(tablerosVisitados,nBolas);
            //y calculamos el nuevo tablero a partir de tablero_actual - ta - y...

            //solucionesParciales - bolasSopladas - añade b
            solParcial.add(nBolas);

            if(esTableroSolucion(ta, tablerosSol)){
                caminos.add(bolasSopladas);
            }else if(esTableroVisitado(ta, tablerosVisit)){
                //se para aquí y no avanzará
                break;
            }else{
                resolverSoplarBola(solParcial, ta, totalesIdBolas, tablerosVisit, caminos);
            }
            nBolas++;
    }       
}

private static void imprimirTab1(ArrayList<Casilla> ta, String m) {

    Iterator<Casilla> itTab= ta.iterator();
    System.out.println("");
    System.out.println("Tablero actual: " + m);
        for(int i=1; i<=dimension[0];i++){
            for(int j=1; j<=dimension[1]; j++){
                System.out.print("["+itTab.next().idBola+"] ");
            }
            System.out.println(".");
        }       
}

private static void imprimirTabVisitados(ArrayList<ArrayList<Casilla>> tabVisitados){
    ArrayList<ArrayList<Casilla>> tabVis = tabVisitados;
    Iterator<ArrayList<Casilla>> itVis = tabVis.iterator();
    ArrayList<Casilla> tabN;
    //Los tableros que se imprimen aquí ya han sido comprobados de que no están duplicados
    while(itVis.hasNext()){
        tabN = itVis.next();
        imprimirTab1(tabN," visitados");
    }
}

public static ArrayList<Casilla> soplarBola(int idBola,ArrayList<Casilla> tabl){
    tablerosVisitados = new ArrayList<ArrayList<Casilla>>();
    //ArrayList<Casilla> tabl = tab;
    boolean movimientoHecho = false;
    Iterator<Casilla> it = tabl.iterator();
    int x =1;
    int y =1;
    Casilla casi;
    Casilla casi2;
    boolean hayMovimiento = false;
    int cont = 0;
    idBola = 3;
    while(it.hasNext()){//Recorremos todo el tablero buscando la bola con idBola para obtener sus coordenadas
        casi = it.next();
        if(casi.idBola == idBola){
            x = casi.coordX;
            y = casi.coordY;
        }
    }

    **tablerosVisitados.add(cont, tabl);
//  imprimirTab1(tablerosVisitados.get(0), "0");
    imprimirTodo(tablerosVisitados, "inicial");** <- //Here is all OK, print the rigth table.

                                        //MOVIMIENTOS EN LA FILA
    it = tabl.iterator();
    //Vamos a analizar las filas desde el borde hasta la bola
    casi = casillaBuscada(x,1,tabl); //Desde la izq
    while(casi.coordY < y && casi.coordX == x){ 
        //coordenadas que están a la izquierda de la idBola
            if(casi.idBola!=0){ //Si hay bola no se podrá mover a esa posicion
                hayMovimiento=false;
            }else{
                hayMovimiento=true;  //si no hay bola, es que hay hueco y se puede mover a esa posicion
            }
            casi2 =casillaBuscada(casi.coordX,casi.coordY+1,tabl);
            if(hayMovimiento && casi2.getIdBola()!=0 && casi2.getIdBola()!=idBola){ //si hay movimiento y en la posterior hay bola, se traslada a ocupar ese hueco
                casi.setIdBola(casi2.getIdBola());
                casi2.setIdBola(0); //Desplazamiento a la derecha cambiado el idBola
                movimientoHecho = true;
            }
            casi = it.next();//pasamos a la siguiente casilla
        }
    **//imprimirTab1(tabl, "1"); If I use that line print the rigth table in that moment**
    if(movimientoHecho){
        cont++;
        tablerosVisitados.add(cont, tabl);
        //tablerosVisitados.add(tabl);
        imprimirTodo(tablerosVisitados,"1");
        movimientoHecho=false;
    }

    //coordenadas que están a la derecha de la idBola
        casi = casillaBuscada(x,dimension[1],tabl); //nos colocamos a la derecha de la bola y vamos ---->>>
        while(casi.coordY > y && casi.coordX == x){
            if(casi.idBola!=0){ //Si hay bola no se podrá mover a esa posicion
                hayMovimiento=false;
            }else{
                hayMovimiento=true;  //si no hay bola, es que hay hueco y se puede mover a esa posicion
            }
            casi2 =casillaBuscada(casi.coordX,casi.coordY-1,tabl);
            if(hayMovimiento && casi2.getIdBola()!=0){ //si hay movimiento y en la posterior hay bola, se traslada a ocupar ese hueco
                casi.setIdBola(casi2.getIdBola());
                casi2.setIdBola(0); //Desplazamiento a la derecha cambiado el idBola
                movimientoHecho=true;
            }
            casi = it.next();//pasamos a la siguiente casilla
        }
    //  imprimirTab1(tabl,"2");

        if(movimientoHecho){
            cont++;
            **tablerosVisitados.add(cont, tabl);** 
//This is the line of horror. Delete the first one and set all table like that
            //tablerosVisitados.add(tabl);
            imprimirTodo(tablerosVisitados,"2");
            movimientoHecho=false;
        }

                                        //MOVIMIENTO EN LA COLUMNA
        it = tabl.iterator();
        //Vamos a analizar las columnas desde arriba hacia abajo
        casi = casillaBuscada(1,y,tabl); //Desde arriba
        while(casi.coordY == y && casi.coordX <= x){    

            //coordenadas que están por encima de la idBola
                if(casi.idBola!=0){ //Si hay bola no se podrá mover a esa posicion
                    hayMovimiento=false;
                }else{
                    hayMovimiento=true;  //si no hay bola, es que hay hueco y se puede mover a esa posicion
                }
                casi2 =casillaBuscada(casi.coordX-1,casi.coordY,tabl);
                if(hayMovimiento && casi2.getIdBola()!=0 && casi2.getIdBola() != idBola){ //si hay movimiento y en la posterior hay bola, se traslada a ocupar ese hueco
                    casi.setIdBola(casi2.getIdBola());
                    casi2.setIdBola(0); //Desplazamiento hacia arriba cambiado el idBola
                    movimientoHecho=true;
                }
                casi = casi2;//pasamos a la siguiente casilla

            }
        //imprimirTab1(tabl,"3");
        if(movimientoHecho){
            cont++;
            **tablerosVisitados.add(cont, tabl);** //This is the line of horror. Delete the first one and set all table like that
            //tablerosVisitados.add(tabl);
            imprimirTodo(tablerosVisitados,"3");
            movimientoHecho=false;
        }

            //coordenadas que están por debajo de la idBola
            casi = casillaBuscada(dimension[0],y,tabl); //nos colocamos a la abajo del todo
            casi2 =casillaBuscada(casi.coordX-1,casi.coordY,tabl);
            while(casi2.coordY == y && casi2.coordX > x){
                if(casi2.idBola!=0 && casi.idBola == 0){ //Si hay bola no se podrá mover a esa posicion
                    hayMovimiento=true;
                }else{
                    hayMovimiento=false;  //si no hay bola, es que hay hueco y se puede mover a esa posicion
                }

                if(hayMovimiento && casi.getIdBola()==0 && casi2.getIdBola() != idBola){ //si hay movimiento y en la posterior hay bola, se traslada a ocupar ese hueco
                    casi.setIdBola(casi2.getIdBola());
                    casi2.setIdBola(0); //Desplazamiento a la derecha cambiado el idBola
                    movimientoHecho=true;
                }
                casi = casi2;//pasamos a la siguiente casilla
                casi2 = casillaBuscada(casi.coordX-1,casi.coordY,tabl);
            }
            //imprimirTab1(tabl,"4");
            if(movimientoHecho){
                cont++;
                **tablerosVisitados.add(cont, tabl);**
//This is the line of horror. Delete the first one and set all table like that
                //tablerosVisitados.add(tabl);
                imprimirTodo(tablerosVisitados,"4");
                movimientoHecho=false;
            }

            suprTablVisitDuplicados(tablerosVisitados);
            imprimirTabVisitados(tablerosVisitados);

    return tabl;
}

private static void imprimirTodo(ArrayList<ArrayList<Casilla>> tablerosVisitados2, String m) {

    for(int i = 0; i<tablerosVisitados2.size();i++){
        imprimirTab1(tablerosVisitados.get(i), m);
    }

}

private static void suprTablVisitDuplicados(ArrayList<ArrayList<Casilla>> tabVis) {
    ArrayList<Casilla> tabTemp;
    for(int i=0; i<tabVis.size(); i++){
        tabTemp = tablerosVisitados.get(i);
        if(esTableroVisitado(tabTemp, tablerosVisitados)){
            tablerosVisitados.remove(i);
        }
    }
}

private static Casilla casillaBuscada(int cX, int cY, ArrayList<Casilla> tab) {
    Casilla buscada = null;
    boolean encontrada = false;
    Iterator<Casilla> it = tab.iterator();
    while(it.hasNext() && !encontrada){
        buscada = it.next();
        if(buscada.coordY==cY && buscada.coordX==cX){
            encontrada=true;
        }
    }
    return buscada;
}

private static boolean esTableroSolucion(ArrayList<Casilla> tab1, ArrayList<ArrayList<Casilla>> tabSol){
    Iterator<ArrayList<Casilla>> it0 = tabSol.iterator();
    Iterator<Casilla> it1 = tab1.iterator();
    ArrayList<Casilla> tsol;
    boolean esIgual = false;
    while(it0.hasNext() && !esIgual){ //bucle que recorre el ArrayList de tableros visitados
        tsol = it0.next();
        Iterator<Casilla> it2 = tsol.iterator(); //iterator de una de los tableros visitados
        while(it1.hasNext() && it2.hasNext() && !esIgual){ //bucle que recorrera los tableros a comparar
            if(it1.next().equals(it2.next())){
                esIgual=true;
            }else{
                esIgual=false;
            }
        }
    }
    return esIgual;
}

private static boolean esTableroVisitado(ArrayList<Casilla> tab1, ArrayList<ArrayList<Casilla>> tabVisitadas){
    //Partimos de la suposición de que los 2 tableros son iguales y en caso de encontrar una diferencia break
    Iterator<ArrayList<Casilla>> it0 = tabVisitadas.iterator();
    Iterator<Casilla> it1 = tab1.iterator();
    ArrayList<Casilla> tv;
    boolean esIgual = true;
    imprimirTab1(tab1, " original");
    while(it0.hasNext() && esIgual){ //bucle que recorre el ArrayList de tableros visitados
        tv = it0.next();
        Iterator<Casilla> it2 = tv.iterator(); //iterator de una de los tableros visitados
        while(it1.hasNext() && it2.hasNext() && esIgual){ //bucle que recorrera los tableros a comparar
            imprimirTab1(tv, " comparado.");
            if(it1.next() == it2.next()){
                esIgual=true;
            }else{
                esIgual=false;
                break;
            }
        }
    }
    return esIgual;
}

private static boolean estaContenido(int[] posicion, ArrayList<int[]> coords) {
    boolean r = false;
    int[] option;
    for(int i=0; i<coords.size();i++){
        option=new int[2];
        option = coords.get(i);
        if(option[0] == posicion[0]){
            if(option[1]==posicion[1]){
                r=true;
                break;
            }else{
                r=false;
            }
        }else{
            r=false;
        }
    }
    return r;
}
}

4

1 回答 1

0

问题是结果。当我的 ArrayList tabVisited.add(newTable) 使用引用时,它不会复制另一个不同的,而是相同的。就像,所有的引用和所有的变化都是相互联系的。解决方案在这里:https ://energiaenescena.wordpress.com/2013/03/11/copia-profunda-de-objetos-en-java-por-serializacion/

于 2016-02-02T01:03:47.530 回答