package aima.core.environment.hidato; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.ArrayList; import aima.core.agent.Action; import aima.core.environment.hidato.Accion; import aima.core.search.framework.ActionsFunction; import java.util.LinkedHashSet; /** * Clase que implementa la funcion que devuelve las acciones disponibles en un estado dado */ public class AccionesDisponibles implements ActionsFunction { /* hashtable para el metodo is_duplicate */ Map<Integer, Integer> map; public Set<Action> actions(Object state) { /* estado sobre el que se comprueban las acciones disponibles */ Estado estado = (Estado)state; /* conjunto de acciones donde vamos a meter las acciones disponibles */ Set<Action> acciones = new LinkedHashSet<Action>(); /* array auxiliar para almacenar las casillas adyacentes a la posiciĆ³n central sobre las que podemos escribir */ ArrayList<int[]> arrayAux = new ArrayList<int[]>(); /* cada posicion del arrayAux contiene 3 enteros. En 0 valor, en 1 posicionX y en 2 posicionY */ int[] a; /* cargamos actual, que es la ultima posicion escrita en la matriz */ int i=estado.actual[0]; int j=estado.actual[1]; for (int n=i-1; n<=i+1; n++){ /* Recorrer todos los adyacentes a la posicion actual */ for (int m=j-1; m<=j+1; m++){ if(!(n<0 || m<0 || n>=estado.matrix.length || m>=estado.matrix[0].length) /* precondicion de dentro de los limites de la matriz */ && estado.matrix[n][m] != null /* precondicion que la posicion adyacente no sea nula */ && (i!=n || j!=m) /* no metemos en la lista la posicion central */ ){ a = new int[3]; a[0]=estado.matrix[n][m]; /* valor de la casilla adyacente */ a[1]=n; /* posicion en filas de la casilla adyacente */ a[2]=m; /* posicion en columnas de la casilla adyacente */ arrayAux.add(a); /* metemos al arrayAux todas las adyacentes que cumplen las condiciones */ } } } /* con check y el metodo is_duplicate comprobamos que ninguna de las posiciones adyacentes contenga ya el valor actual + 1 */ int[] check = new int[2]; check = is_duplicate(arrayAux, estado.matrix[i][j]+1); if(check[0]==-1){ /* si is_duplicate devuelve -1, ninguna de las posiciones adyacentes contenia al siguiente valor a escribir */ for (int k=0; k<arrayAux.size();k++){ if(arrayAux.get(k)[0]==0){ /* incluimos como acciones todas las casillas adyacentes que cumplen las precondiciones y con el valor a escribir=valorActual+1 */ acciones.add(new Accion("escribir", arrayAux.get(k)[1], arrayAux.get(k)[2], estado.matrix[i][j]+1)); } } }else{ /* si is_duplicate encuentra el valor a escribir en una posiciĆ³n adyacente devuelve la casilla en la que esta y le dejamos el valor que ya estaba escrito */ acciones.add(new Accion("escribir", check[0], check[1], estado.matrix[check[0]][check[1]])); } return acciones; } public int[] is_duplicate(ArrayList<int[]> lista, Integer nuevo_valor){ /* limpiar el map con cada llamada a is_duplicate */ map = new HashMap<Integer, Integer>(); map.put(nuevo_valor, 1); /* variable para devolver resultados a check */ int[] a = new int[2]; for (int i = 0; i < lista.size(); i++) { /* cogemos el valor de todas las posiciones del arrayAux */ int el = lista.get(i)[0]; /* si se encuentra el valor esperado en la hashtable devuelve la posicion en la que lo ha encontrado */ if(map.containsKey(el)){ a[0]=lista.get(i)[1]; a[1]=lista.get(i)[2]; return a; } /* las casillas con valor 0 no se deben comprobar en el map porque son las vacias */ if(el!=0){ map.put(el, 1); } } /* si no se encuentra el valor esperado en el map devuelve -1 */ a[0]=-1; a[1]=-1; return a; } }