-2

I know there are a lot of questions about that topic. In fact, I was searching in others questions and I tried to use some solutions but it was not enough.

I have to do a program that simulate puffball, using backtracking, and now I am developing the moves, and when I do a move I need to save the table because is a possible solution, so THE PROBLEM IS NEXT: When a I try to keep off a table the first one save it right but the next is added and overwrite the earlier. I show you the code, it is not all, only methods and other info that I think can be useful for all of you.

In main() you can see how I get all information, and then when I start to play, I call to soplarBola(), It is here where you could see the problem.

Excuse me, because all is in Spanish. I hope you could understand my handicap.

Thanks a lot!

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;
}
}

Enery93
  • 11
  • 5

1 Answers1

0

The problem is result. When my ArrayList tabVisited.add(newTable) is using references, so it is not copying another different, but the same. And like, all are connected between references, all changes. The solution is here: https://energiaenescena.wordpress.com/2013/03/11/copia-profunda-de-objetos-en-java-por-serializacion/

Enery93
  • 11
  • 5