我知道有很多关于这个话题的问题。事实上,我正在寻找其他问题而我试图使用一些解决方案,但这还不够。
我必须做一个模拟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;
}
}
答案 0 :(得分:0)
问题是结果。 当我的ArrayList tabVisited.add(newTable)使用引用时,所以它不是复制另一个不同的,而是相同的。并且,所有更改都在引用之间连接。 解决方案如下:https://energiaenescena.wordpress.com/2013/03/11/copia-profunda-de-objetos-en-java-por-serializacion/