ArrayList добавить новый объект и перезаписать объект, который я добавил ранее

Я знаю, что есть много вопросов по этой теме. На самом деле я искал другие вопросы и пытался использовать некоторые решения, но этого было недостаточно.

Я должен сделать программу, которая имитирует пуффбол, используя backtracking, и теперь я разрабатываю ходы, и когда я делаю ход, мне нужно сохранить стол, потому что это возможное решение, поэтому ПРОБЛЕМА СЛЕДУЕТ: Когда я пытаюсь оставьте таблицу первой, сохраните ее правильно, но добавьте следующую и перезапишите предыдущую. Я покажу вам код, это не все, только методы и другая информация, которая, на мой взгляд, может быть полезна для всех вас.

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

1 ответ

Проблема в результате. Когда мой ArrayList tabVisited.add(newTable) использует ссылки, значит, он не копирует другое, а то же самое. И вроде бы, все связаны между собой ссылками, все изменения. Решение здесь: https://energiaenescena.wordpress.com/2013/03/11/copia-profunda-de-objetos-en-java-por-serializacion/

Другие вопросы по тегам