You are on page 1of 8

Solución de un laberinto mediante la aplicación de un

algoritmo de Backtracking óptimo.

Alberto Corisco Nieto Gunther Calvo Atance


100021578@alumnos.uc3m.es 100029567@alumnos.uc3m.es

estudiar todo el espacio del laberinto sino que una vez


1. INTRODUCTION encontrada una salida solo se consideraran caminos validos
Se utilizara un algoritmo heurístico (CSP) para obtener la aquellos con menor longitud que la salida actual.
solución óptima de un laberinto. El algoritmo que se ha
implementado es el algoritmo de backtracking. De modo que esto ultimo se puede entender como una poda del
árbol de todas aquellas ramas cuya profundidad (numero de
2. OBJETIVOS nodos por los que se ha pasado) es igual a la profundidad de la
Nuestro principal objetivo ser solucionar un laberinto, el cual se solución encontrada hasta el momento de modo que solo se
podrá crear de diferentes formas, ya sea por medio de la tomara como valida otra solución que no pueda ser detenida por
aplicación creada o por un fichero de texto, encontrando la la poda del árbol, lo que viene a significar otra solución con una
salida optima del mismo, esto es, en el caso de que el laberinto profundidad menor que la de la solución actual.
tuviera varias salidas se daría por buena aquella que tenga un
menor número de pasos, entendiendo por pasos cada una de las Otros problemas para los que también es útil utilizar este tipo de
posiciones de la matriz donde mapearemos el laberinto para algoritmo son, por ejemplo, obtener la solución de un sudoku o
poder operar con el. el mínimo cableado de un circuito.
3. ESTRATEGIA 4. RESOLUCION DE PROBLEMAS
El algoritmo utilizado será el algoritmo de backtracking, Los problemas a solucionar por este tipo de algoritmos, son
optimizado para encontrar la solución con menor coste, esto es aquellos que se pueden representar como un árbol, el algoritmo
el camino a recorrer que tiene un menor numero de pasos. de backtracking lo recorrerá en profundidad.

El backtracking es un algoritmo que utiliza una estrategia de En algunas ocasiones el árbol que genera el problema es muy
búsqueda en profundidad y busca la mejor combinación de las grande y encontrar una solución o la solución óptima es
variables para solucionar el problema. Durante la búsqueda, si se computacionalmente muy costoso. En estos casos se suele podar
encuentra una alternativa incorrecta, la búsqueda retrocede hasta el árbol, es decir no se recorrerán ciertos nodos porque debido a
el paso anterior y toma la siguiente alternativa. Cuando se han ciertas características en los mismos ya sabemos que no se
terminado las posibilidades, se vuelve a la elección anterior y se obtendrá una mejor solución a la que ya se tiene o que
toma la siguiente opción. Si no hay más alternativas la búsqueda simplemente no se obtendrá solución.
falla. De esta manera, se crea un árbol implícito, en el que cada
nodo es un estado de la solución (solución parcial en el caso de Este tipo de algoritmos pueden encontrar una o todas las
nodos interiores o solución total en el caso de los nodos hoja). soluciones, siguiendo los siguientes esquemas:

Hemos implementado el algoritmo de forma recursiva, a cada 4.1 Esquema para una solución
llamada le asignamos una dirección posible en la que procedimiento ensayar (paso)
desplazarse a una nueva posición de la matriz donde se volverá a repetir
evaluar los posibles movimientos, si llega un momento que no |seleccionar candidato
puede acceder a ninguna posición no visitada ya desde el lugar |if aceptable then
actual, se considera q se llego a un punto muerto y se vuelve al |begin
nodo anterior donde se moverá a la siguiente posición posible. | anotar_candidato
| if solucion_incompleta then
De este modo el algoritmo ira recorriendo todo el espacio del | begin
laberinto hasta encontrar una salida, y una vez encontrada | ensayar (paso_siguiente)
volverá hacia atrás para ver si es posible encontrar otro camino | if no_acertado then borrar_candidato
con un menor numero de pasos, con lo que no es necesario | end
| else begin
| anotar_solucion
| acertado Åcierto
| end
hasta que (acertado = cierto ) o (candidatos agotados)
fin procedimiento

4.2 Esquema para todas las soluciones


procedimiento ensayar (paso)
para cada candidato hacer
|seleccionar candidato
|if aceptable then
|begin Figura 2.solución de la vuelta del caballo.
| anotar_candidato
| if solucion_incompleta then
| begin 4.3.2 El Problema de las Ocho Reinas
| ensayar (paso_siguiente) Consiste en colocar en un tablero ocho reinas de tal modo que
| else ninguna pueda comer a otra, es decir se colocan de tal forma que
| almacenar_solucion ninguna reina esta en la misma fila, en la misma columna o en
| borrar_candidato cualquiera de las diagonales de cualquiera del resto de las reinas.
| end
hasta que (candidatos agotados) A continuación ilustramos con un dibujo una posible solución a
fin procedimiento este problema (Figura 3).

4.3 Algunos Ejemplos


Además del problema del laberinto, existen otros muchos
problemas que pueden ser solucionados por medio del algoritmo
del backtracking como son:

4.3.1 La Vuelta del Caballo


Consiste en que partiendo de un tablero de ciertas dimensiones,
y una posición inicial cualquiera una pieza de ajedrez, en este
caso un caballo, debe pasar por cada posición del tablero una
sola vez y recorrerlo completamente. Todo esto siguiendo el
movimiento que corresponde a dicha pieza en el ajedrez.

A continuación mostramos un tablero con dicha pieza colocada Figura 3.posición de las ocho reinas.
en el centro, y las posibles posiciones a las que podrá acceder
partiendo de la posición inicial (Figura 1)
4.3.3 El Problema del Sudoku
Consiste en rellenar un cuadrado de 9x9 formado a su vez por 9
cuadrados de 3x3. En cada cuadrado pequeño se debe colocar un
número del 1 al 9, pero sin que se repita en filas o en columnas.

Un ejemplo de un sudoku es el siguiente:

Figura 1.Movimientos posibles.

A continuación se mostrara una solución a dicho problema en la


que el caballo parte de la esquina superior izquierda (pudiendo
ser la posición inicial cualquiera del tablero)

Se puede ver por medio de los números en cada una de las


posiciones como efectivamente el caballo recorre todo el tablero
pasando únicamente una vez por cada casilla (Figura 2).

Figura 4.Sudoku
Y aplicando el algoritmo se obtiene:

Figura 7.posición final

Figura 5. Sudoku resuelto 4.3.5 El Problema de la Mochila


Consiste en llenar una mochila con una serie de objetos que
tienen una serie de pesos con un valor asociado. Es decir, se
4.3.4 Torres de Hanoi dispone de n tipos de objetos y no hay un número limitado de
El juego consta de tres varillas verticales y un número cada tipo de objeto. Cada tipo i de objeto tiene un peso wi
indeterminado de discos que determinarán la complejidad de la positivo y un valor vi positivo asociados. La mochila tiene una
solución. No hay dos discos iguales, están colocados de mayor a capacidad de peso igual a W. Se trata de llenar la mochila de tal
menor en la primera varilla ascendentemente, y no se puede manera que se maximice el valor de los objetos incluidos pero
colocar ningún disco mayor sobre uno menor a él en ningún respetando al mismo tiempo la restricción de capacidad. Notar
momento. El juego consiste en pasar todos los discos a la tercera que no es obligatorio que una solución óptima llegue al límite de
varilla colocados de mayor a menor ascendentemente. capacidad de la mochila.

Inicialmente las varillas y los discos están colocados de cierta 5. IMPLEMENTACION


forma véase Figura 6 y se debe llegar a colocarlos de la siguiente 5.1 Descripción General
forma Figura 7.
La implementación se divide en dos bloques claramente
diferenciados: la implementación del algoritmo propiamente
dicho y la de la interfaz gráfica o GUI.

5.2 Algoritmo
La implementación se ha llevado a cabo mediante llamadas
recursivas partiendo de la casilla origen. El diagrama de flujo
correspondiente se muestra en la Figura 8. El método se
inicializa sobre la posición de la casilla origen y un paso de 1. A
partir de ahí se mira si dicha casilla es la final, en caso
afirmativo se introduce la posición en el camino solución que se
devuelve a la función llamante. En caso negativo, se comprueba
que no se pueda llegar a dicha casilla por un camino más corto
(menor número de pasos).
En dicho caso se devuelve null al método llamante pues éste
camino no es una posibilidad viable; de no ser así, se actualiza la
Figura 6.posición inicial distancia de ésta casilla al origen, se obtienen los movimientos
posibles desde dicha casilla y se llama al método de forma
Y para obtener la solución del problema se debe llegar a este recurrente para cada uno de ellos.
estado: Se comparan las distancias relativas hasta la meta para cada una
de las posibilidades; se añade la casilla actual al camino de la
mejor de las soluciones y se devuelve dicho camino al método
llamante.
Debido a la naturaleza basada en eventos intrínseca a las
interfaces gráficas y al carácter secuencial de la definición de un
laberinto (definición del mapa, de los puntos de salida y
llegada,…) hemos optados por un diseño basado en estados.

Figura 8.Diagrama de flujo del algoritmo


Figura 10. Diagrama de estados de la GUI
Mediante ésta implementación del algoritmo no solo se obtiene
un camino entre el origen y el final, si no que éste es óptimo (es
Los estados definidos son:
un camino que implica un número mínimo de pasos). Esto se
• Cero: sistema iniciado y preparado para cargar un
consigue gracias a la comparación de los caminos obtenidos para
mapa desde un fichero o generar una cuadrícula en
cada una de las posibilidades. Un algoritmo más eficiente pero
blanco de dimensiones definidas.
menos óptimo emplearía ésta segunda estrategia.
• Uno: a la espera de que el usuario realice cambios en
5.3 Interfaz Gráfico la topología del mapa (añadir/eliminar casillas muro o
El objetivo de ésta práctica era la implementación de un pasillo).
algoritmo óptimo de Backtracking; sin embargo, se hace • Dos: emplazamiento de la casilla de salida (marcada
necesario demostrar su funcionalidad y para ello decidimos huir en azul).
de la esterilidad de la línea de comandos y diseñar un interfaz • Tres: emplazamiento de la casilla de llegada (marcada
gráfico agradable que permitiese de forma sencilla poner a en verde).
prueba las capacidades del algoritmo (vease figura 9). • Cuatro: muestra de la resolución del problema
marcando el camino óptimo en rojo.
La transición de unos estados a otros se realiza mediante los
eventos generados al presionar los botones (“reset” y “general”)
presentes en la parte inferior de la ventana de acuerdo con el
diagrama de flujo de la Figura 10.

5.4 Codificación
Como Lenguaje de programación escogimos Java por la amplia
experiencia que tenemos con dicho entorno. El programa se
compone de cuatro clases:
• Posicion - representa un punto en coordenadas
cartesianas.
• Casilla - La clase Casilla representa una casilla en el
mapa del laberinto a resolver. Se compone
básicamente de un elemento Posicion que define su
situación en el mapa, un entero para almacenar el
numero de pasos mínimos necesarios para alcanzar
dicha Posicion desde la Casilla de salida y un
booleano indicador de si dicha Casilla forma parte de
la solución. Al ser parte fundamental de la GUI,
Figura 9. Resolución de un laberinto de 20x10x2
Casilla es un tipo Canvas extendido. Los colores * Metodo que implementa de forma recursiva el algoritmo de
backtracking.
mostrados por cada casilla significan: * p - es la posicion de la Casilla a analizar
- gris - muro * paso - el numero de saltos necesarios para alcanzar dicha Casilla por
- blanco - pasillo el camino analizado
- azul - casilla de salida */
public Vector<Posicion> camino(Posicion p,int paso){
- verde - casilla de llegada Vector<Posicion> miCamino=new Vector<Posicion>(1,1);
- rojo - casilla perteneciente al camino solución
• BTAlgorithm – implementa el algoritmo Backtracking //Comprueba que no se haya encontrado el final
if(mapa[p.getX()][p.getY()][p.getZ()].isNotTheEnd()){
óptimo utilizado para resolver el laberinto. //Comprueba que no se pueda llegar a esta Casilla con un
• BackTracker – ésta clase compone la parte gráfica de numero menor de pasos
la aplicación. if((mapa[p.getX()][p.getY()][p.getZ()].getStep())>=(paso)){
//parametros utilizados para encontrar el camino mas corto de
enter todos los posibles desde esta casilla
5.5 Código Fuente int mejordistancia=Integer.MAX_VALUE;
Vector<Posicion> suMejorCamino=null;
5.5.1 BTAlgorithm Vector<Posicion> suCamino;
package backtracker; Object movs[];
import java.util.Vector; //se actualiza el valor de paso de la casilla actual
mapa[p.getX()][p.getY()][p.getZ()].setStep(paso);
/*
* Esta case implementa el algoritmo de BackTracking optimo //se buscan los posibles movimientos se puedan hacer desde
*/ aqui
public class BTAlgorithm{ movs=movPosibles(p);
//dimensiones del mapa
private int dim_x; //para cada posible camino
private int dim_y; for(int i=0;i<movs.length;i++){
private int dim_z; //calcular la solucion
//sucesion de casillas que conforman la solucion suCamino=camino((Posicion)movs[i],paso+1);
Vector movP; //si se encontro una solucion, comparar el numero de pasos
//mapa del laberinto necesarios para esta solucion con las otras posibilidades
Casilla mapa [][][]; if( (suCamino!=null) && (mejordistancia>suCamino.size())
){
public BTAlgorithm(Casilla mapa[][][]) { //por ahora es el mejor camino, actualizar mejor
this.mapa=mapa; distancia
dim_x=mapa.length; suMejorCamino=suCamino;
dim_y=mapa[0].length; mejordistancia=suCamino.size();
dim_z=mapa[0][0].length; }
movP=new Vector(); }
} //si no se encontro ninguna solucion
if(suMejorCamino==null)
/* return null;
* Este etodo analiza las Casilla circundantes y devuelve un array con //si se encontro, añadir esta casilla a la solucion
las posiciones donde hay pasillo miCamino=suMejorCamino;
*/ miCamino.add(p);
Object[] movPosibles(Posicion p){ }
Vector<Posicion> m=new Vector<Posicion>(3,1); else{
return null;
if(p.getY()>0 && mapa[p.getX()][(p.getY()-1)][p.getZ()].isNotWall()){ }
m.addElement(new Posicion(p.getX(),(p.getY()-1),p.getZ())); }
} else{
if(p.getY()<(dim_y-1) && miCamino.addElement(p);
mapa[p.getX()][(p.getY()+1)][p.getZ()].isNotWall()){ }
m.addElement(new Posicion(p.getX(),(p.getY()+1),p.getZ())); return miCamino;
} }
}
if(p.getX()>0 && mapa[(p.getX()-1)][p.getY()][p.getZ()].isNotWall()){
m.addElement(new Posicion((p.getX()-1),p.getY(),p.getZ())); 5.5.2 Posicion
} package backtracker;
if(p.getX()<(dim_x-1) &&
mapa[(p.getX()+1)][p.getY()][p.getZ()].isNotWall()){ /*
m.addElement(new Posicion((p.getX()+1),p.getY(),p.getZ())); * La clase Posicion representa un punto en coordenadas cartesianas
} */
public class Posicion {
if(p.getZ()>0 && mapa[p.getX()][(p.getY())][p.getZ()-1].isNotWall()){
m.addElement(new Posicion(p.getX(),(p.getY()),p.getZ()-1)); private int x;
} private int y;
if(p.getZ()<(dim_z-1) && private int z;
mapa[p.getX()][(p.getY())][p.getZ()+1].isNotWall()){
m.addElement(new Posicion(p.getX(),(p.getY()),p.getZ()+1)); public Posicion(int x,int y,int z) {
} this.x=x;
m.trimToSize(); this.y=y;
return m.toArray(); this.z=z;
} }
public void setX(int nx){
/* x=nx;
}
public int getX(){ setBackground(Color.WHITE);
return x; }
} }
public void setY(int ny){ public void mark(){
y=ny; if(isNotTheEnd() & isNotTheBeginning() & isNotWall()){
} setBackground(Color.RED);
public int getY(){ marked=true;
return y; }
} }
public void setZ(int nz){ public void unmark(){
z=nz; if(marked)
} setBackground(Color.WHITE);
public int getZ(){ }
return z; public boolean isWall(){
} return step == -1;
public String toString(){ }
return "x=" + String.valueOf(x) + " y=" + String.valueOf(y) + " z=" + public boolean isNotWall(){
String.valueOf(z); return step != -1;
} }
} public boolean isTheEnd(){
return step==0;
5.5.3 Casilla }
package backtracker; public boolean isNotTheEnd(){
return step!=0;
import java.awt.Color; }
import java.awt.*; public void setAsEnd(){
step=0;
/* setBackground(Color.GREEN);
* La clase Casilla representa una casilla en el mapa del laberinto a }
resolver. public void unsetAsEnd(){
* Se compone básicamente de un elemento Posicion que define su step=Integer.MAX_VALUE;
situación en el mapa, setBackground(Color.WHITE);
* un entero para almacenar el numero de pasos minimos necesarios para }
alcanzar dicha public boolean isTheBeginning(){
* posicion desde la Casilla de salida y un booleano indicador de si dicha return step==1;
Casilla }
* forma parte de la solución. public boolean isNotTheBeginning(){
* Al ser parte fundamental de la GUI, Casilla es un tipo Canvas extendido. return step!=1;
*/ }
public class Casilla extends Canvas{ public void setAsBeginning(){
//elemento Posicion que define su situación en el mapa. Valores step=1;
especiales son: setBackground(Color.BLUE);
private Posicion pos; }
/* public void unsetAsBeginning(){
* numero de pasos minimos necesarios para alcanzar dicha posicion step=Integer.MAX_VALUE;
desde la Casilla de salida setBackground(Color.WHITE);
* -1 si es representa un elemento no navegable (muro) }
* 0 si representa la casilla de llegada public void setStep(int i){
* 1 si representa la casilla de salida step=i;
*/ }
private int step; public int getStep(){
//indicador de si dicha Casilla forma parte de la solución return step;
private boolean marked; }
public void setPosicion(Posicion p){
public Casilla(int x, int y, int z){ pos=p;
setBackground(Color.LIGHT_GRAY); }
pos=new Posicion(x,y,z); public Posicion getPosicion(){
step=-1; return pos;
marked=false; }
} public void setX(int nx){
pos.setX(nx);
public String toString(){ }
return pos.toString() + " step= " + String.valueOf(step) + " marked= " public void setY(int ny){
+ String.valueOf(marked); pos.setY(ny);
} }
//reinicia la casilla a su valor previo al calculo de la solución public void setZ(int nz){
public void reset(){ pos.setZ(nz);
if(isNotWall()){ }
unmark();
step=Integer.MAX_VALUE; public int getX(){
} return pos.getX();
} }
//cambia la naturaleza de la Casilla entre muro y pasillo
public void changeState(){ public int getY(){
if(isNotWall()){ return pos.getY();
step=-1; }
setBackground(Color.LIGHT_GRAY);
} public int getZ(){
else{ return pos.getZ();
step=Integer.MAX_VALUE; }
} i=Integer.parseInt(alto.getText());
j=Integer.parseInt(ancho.getText());
5.5.4 BackTracker k=Integer.parseInt(pisos.getText());
package backtracker;
maze=new Casilla[i][j][k];
import java.awt.event.*; mapa=new Panel[k];
import java.awt.*; setSize(k*500,600);
import java.util.Vector;
import java.io.*; for(kk=0; kk<k; kk++){
mapa[kk]=new Panel();
/* mapa[kk].setSize(500,500);
* Esta clase implementa la GUI mapa[kk].setBackground(Color.BLACK);
*/ mapa[kk].setLayout(new GridLayout(i,j,1,1));
public class BackTracker extends java.applet.Applet implements tablero.setLayout(new GridLayout(1,k,5,5));
MouseListener, ActionListener, ItemListener{ tablero.add(mapa[kk]);
private static final long serialVersionUID = 1L;
int state; for(ii=0; ii<i; ii++){
boolean endMarked, beginningMarked; for(jj=0; jj<j; jj++){
Casilla beginningTile, endTile; maze[ii][jj][kk]=new Casilla(ii,jj,kk);
Casilla maze[][][]; maze[ii][jj][kk].addMouseListener(this);
Panel tablero; mapa[kk].add(maze[ii][jj][kk]);
Panel control; }
Panel mapa[]; }
Button reset; mapa[kk].doLayout();
Button general; }
Checkbox ffile; tablero.doLayout();
TextField alto; doLayout();
TextField ancho; }
TextField pisos; private void loadFromFile(){
Label altoL; BufferedReader br;
Label anchoL; FileDialog fd;
Label pisosL; Vector<String> lines=new Vector<String>();
String line;
public void init() { char marcas[][];
state=0; int i,ii, j,jj, k,kk;
endMarked=false;
beginningMarked=false; fd=new FileDialog(new Frame(),"Abrir",FileDialog.LOAD);
setSize(500,600); fd.setVisible(true);
reset=new Button("Resetear"); try {
reset.setName("reset"); br=new BufferedReader(new
reset.setEnabled(false); FileReader(fd.getDirectory().concat(fd.getFile()) ));
reset.addActionListener(this); line=br.readLine();
general=new Button("Siguiente"); while(line!=null){
general.setName("general"); lines.add(line);
general.addActionListener(this); line=br.readLine();
ffile=new Checkbox("File",false); }
ffile.addItemListener(this); br.close();
alto=new TextField(3); } catch (FileNotFoundException e) {
ancho=new TextField(3); e.printStackTrace();
pisos=new TextField(2); }catch (IOException e) {
altoL=new Label("Alto"); e.printStackTrace();
anchoL=new Label("Ancho"); }
pisosL=new Label("Pisos");
marcas=new char[lines.size()][((String)lines.elementAt(0)).length()];
setLayout(new BorderLayout()); for(int merlo=0;merlo<marcas.length;merlo++)
tablero=new Panel(); marcas[merlo]=((String)lines.elementAt(merlo)).toCharArray();
tablero.setBackground(Color.RED);
add(tablero,BorderLayout.CENTER); i=marcas.length;
j=marcas[0].length;
control=new Panel(); k=1;
control.setBackground(Color.BLUE);
add(control,BorderLayout.SOUTH); maze=new Casilla[i][j][k];
mapa=new Panel[k];
control.add(reset); setSize(k*500,600);
control.add(general);
control.add(ffile); for(kk=0; kk<k; kk++){
control.add(altoL); mapa[kk]=new Panel();
control.add(alto); mapa[kk].setSize(500,500);
control.add(anchoL); mapa[kk].setBackground(Color.BLACK);
control.add(ancho); mapa[kk].setLayout(new GridLayout(i,j,1,1));
control.add(pisosL); tablero.setLayout(new GridLayout(1,k,5,5));
control.add(pisos); tablero.add(mapa[kk]);
doLayout();
} for(ii=0; ii<i; ii++){
public String getAppletInfo() { for(jj=0; jj<j; jj++){
return "Title: BackTracker"; maze[ii][jj][kk]=new Casilla(ii,jj,kk);
} if(marcas[ii][jj]!='*')
private void loadWithoutFile(){ maze[ii][jj][kk].changeState();
int i,ii, j,jj, k,kk; maze[ii][jj][kk].addMouseListener(this);
mapa[kk].add(maze[ii][jj][kk]);
} ancho.setText("");
} ancho.setEnabled(true);
mapa[kk].doLayout(); pisos.setText("");
} pisos.setEnabled(true);
tablero.doLayout(); }
doLayout(); repaint();
} }
public void actionPerformed(ActionEvent arg0) { public void mouseClicked(MouseEvent arg0) {
String buttonName=((Button)arg0.getSource()).getName(); Casilla source=(Casilla)arg0.getSource();

if( buttonName.equals("general") ){ switch(state){


case 1:
switch(state){ source.changeState();
case 0: break;
if(ffile.getState()) case 2:
loadFromFile(); if(beginningMarked){
else if(source.isTheBeginning()){
loadWithoutFile(); source.unsetAsBeginning();
beginningTile=null;
general.setLabel("definir"); beginningMarked=false;
state=1; }
reset.setEnabled(true); }else if(source.isNotWall()){
ffile.setEnabled(false); source.setAsBeginning();
alto.setEnabled(false); beginningTile=source;
ancho.setEnabled(false); beginningMarked=true;
pisos.setEnabled(false); }
break; break;
case 1: case 3:
general.setLabel("salida?"); if(endMarked){
state=2; if(source.isTheEnd()){
break; source.unsetAsEnd();
case 2: endTile=null;
general.setLabel("llegada?"); endMarked=false;
if(beginningMarked) }
state=3; }else if(source.isNotWall()){
break; source.setAsEnd();
case 3: endTile=source;
general.setLabel("resolver"); endMarked=true;
if(endMarked){ }
Posicion p; break;
BTAlgorithm solver=new BTAlgorithm(maze); }
Vector source.repaint();
elCamino=solver.camino(beginningTile.getPosicion(),1); }
elCamino.trimToSize(); public void itemStateChanged(ItemEvent arg0) {
for(int pp=0;pp<elCamino.size();pp++){ if(((Checkbox)arg0.getSource()).getState()){
p=(Posicion)elCamino.elementAt(pp); alto.setEnabled(false);
maze[p.getX()][p.getY()][p.getZ()].mark(); ancho.setEnabled(false);
} pisos.setEnabled(false);
solver=null; }else{
elCamino=null; alto.setEnabled(true);
state=4; ancho.setEnabled(true);
} pisos.setEnabled(true);
break; }
case 4: }
general.setLabel("definir"); public void mouseEntered(MouseEvent arg0) {}
for(int a=0; a<maze.length;a++) public void mouseExited(MouseEvent arg0) {}
for(int b=0;b<maze[0].length;b++) public void mousePressed(MouseEvent arg0) {}
for(int c=0;c<maze[0][0].length;c++) public void mouseReleased(MouseEvent arg0) {}
maze[a][b][c].reset(); }
state=1;
beginningTile.unsetAsBeginning();
beginningMarked=false;
6. REFERENCIAS
endTile.unsetAsEnd();
endMarked=false; [1] http://www.algoritmia.net/
break;
}
}else if( buttonName.equals("reset") ){
[2] http://en.wikipedia.org
tablero.removeAll();
state=0; [3] http://www.uhu.es/nieves.pavon/pprogramacion/te
maze=null; mario/tema4/tema4.html
mapa=null;
beginningMarked=false;
endMarked=false; Apuntes IRC uc3m 2006
setSize(500,600);
reset.setEnabled(false);
general.setLabel("definir");
ffile.setState(false);
ffile.setEnabled(true);
alto.setText("");
alto.setEnabled(true);