package algoritmos;
import java.util.Collection;
import java.util.Iterator;
import tablero.CasillaTablero.ColorLinea;
import tablero.CasillaTablero.TipoLinea;
import traza.TrazaAlgoritmo;
public class AlgoritmoAEstrella extends AlgoritmoResolucion {
/**
* TODO: cambiar el contenido de cerrados por un nodo para poder saber si
* el camino recorrido hasta ese nodo es menor que el que acabamos de encontrar
*/
public AlgoritmoAEstrella(TrazaAlgoritmo traza,String cadenaHorizontal,String cadenaVertical){
this.traza=traza;
this.cadenaHorizontal=cadenaHorizontal;
this.cadenaVertical=cadenaVertical;
}
@Override
public void run() {
super.iniciarEstructurasDeDatos();
// TODO Auto-generated method stub
this.traza.iniciarAlgoritmo("A*");
Nodo nodoInicio=new Nodo();
nodoInicio.setFilaColumna(1, 1);
Nodo nodoObjetivo=new Nodo();
nodoObjetivo.setFilaColumna(this.cadenaVertical.length()+1, this.cadenaHorizontal.length()+1);
VariablesProblema variables=new VariablesProblema(nodoInicio,nodoObjetivo);
super.setVariablesProblema(variables);
resolverAlgoritmo();
//System.out.println(this.cerrados.toString());
pintarSolucion();
}
public int funcionHeuristica(Nodo nodo){
int fila=nodo.getFila();
int columna=nodo.getColumna();
String indiceActual=nodo.getCoordenadas();
int coste=0;
//System.out.println(nodo.toString());
String nodoObjetivo=this.variables.nodoObjetivo.getCoordenadas();
boolean entraFila=false;
boolean entraColumna=false;
while(!nodoObjetivo.equals(indiceActual)){
entraFila=false;
entraColumna=false;
if(fila<this.variables.nodoObjetivo.getFila()){
fila++;
entraFila=true;
}
if(columna<this.variables.nodoObjetivo.getColumna()){
columna++;
entraColumna=true;
}
if(entraFila && entraColumna ){
String letrahorizontal=this.cadenaHorizontal.substring(columna-2,columna-1);
String letravertical=this.cadenaVertical.substring(fila-2,fila-1);
if(!letravertical.equals(letrahorizontal)){
coste+=2;
}
}
else{
coste+=2;
}
indiceActual=fila+"-"+columna;
}
return coste;
}
public int funcionCoste(Nodo nodoActual,Nodo nodoSiguiente){
int coste=0;
if((nodoSiguiente.getFila()==nodoActual.getFila()+1 && nodoSiguiente.getColumna()==nodoActual.getColumna()) ||
(nodoSiguiente.getFila()==nodoActual.getFila() && nodoSiguiente.getColumna()==nodoActual.getColumna()+1) ){
coste+=2;
}
else{
if( !this.cadenaHorizontal.substring(nodoActual.getColumna()-1, nodoActual.getColumna()).equals(
this.cadenaVertical.substring(nodoActual.getFila()-1, nodoActual.getFila()))){
coste+=2;
}
}
return coste;
}
@Override
public void insertarEnAbiertos(Nodo nuevoNodo, Nodo nodoActual) {
// TODO Auto-generated method stub
TipoLinea tipoLinea=seleccionarTipoLinea(nodoActual,nuevoNodo);
if(!this.abiertos.containsKey(nuevoNodo.getCoordenadas())){
//Comprobamos que no se haya expandido ya
if(!this.cerrados.containsKey(nuevoNodo.getCoordenadas())){
//Lo insertamos ya que su coste es infinito
nuevoNodo.setGn(nodoActual.getGn()+funcionCoste(nodoActual,nuevoNodo));
nuevoNodo.setHn(funcionHeuristica(nuevoNodo));
//Pintamos la l�nea
this.traza.pintarLinea(nodoActual.getFila(),nodoActual.getColumna(),nuevoNodo.getFila(),nuevoNodo.getColumna(),tipoLinea,ColorLinea.ABIERTO);
this.abiertos.put(nuevoNodo.getCoordenadas(), nuevoNodo);
}
else{
/**
* TODO: hacer que se borren los nodos que cuelgan del nuevoNodo
* y asignarle como padre el nodoActual. Sacar el nodod de cerrados y meterlo en abiertos
*/
}
}
else{
Nodo nodoTemp=this.abiertos.get(nuevoNodo.getCoordenadas());
if(nodoTemp.getGn()>(nodoActual.getGn()+funcionCoste(nodoActual, nodoTemp))){
nodoTemp.setGn(nodoActual.getGn()+funcionCoste(nodoActual, nodoTemp));
nodoTemp.setHn(funcionHeuristica(nodoTemp));
//Borramos la l�nea anterior que lo conectaba al padre
this.traza.pintarLinea(nodoTemp.getFilaPadre(), nodoTemp.getColumnaPadre(), nodoTemp.getFila(), nodoTemp.getColumna(), TipoLinea.INVISIBLE,ColorLinea.ABIERTO);
//Pintamos la l�nea
this.traza.pintarLinea(nodoActual.getFila(),nodoActual.getColumna(),nuevoNodo.getFila(),nuevoNodo.getColumna(),tipoLinea,ColorLinea.ABIERTO);
this.abiertos.put(nodoTemp.getCoordenadas(), nodoTemp);
}
}
}
public Nodo siguienteNodo(){
Integer menorNodorNoVisitado=Integer.MAX_VALUE;
Nodo nodoSeleccionado=null;
Collection<Nodo> c=this.abiertos.values();
Iterator<Nodo> itr=c.iterator();
while(itr.hasNext()){
Nodo n=itr.next();
if(!n.getVisitado() && n.getFn()<menorNodorNoVisitado ){
menorNodorNoVisitado=n.getFn();
nodoSeleccionado=n;
}
}
return nodoSeleccionado;
}
}