CODERULER(4 paginas) ¿Qué es? CodeRuler es un juego que simula batallas entre señores feudales. Cada uno de ellos controla un cierto número de campesinos (peasants), caballeros (knights) y castillos (castles). Ahora bien, al principio del juego, todos los señores feudales tienen sólo un castillo, diez campesinos y diez caballeros. El castillo inicial se asigna de manera aleatoria, y el resto de piezas comienzan en las casillas adyacentes al castillo, también de forma aleatoria. CodeRuler es un juego (en tiempo real) creado por IBM basado en Java y en la plataforma Eclipse. CodeRuler fue concebido como un medio para hacer el aprendizaje de Java más entretenido. Coderuler funciona sobre la plataforma Eclipse, que es un proyecto (de código abierto) dedicado a suministrar una plataforma para el desarrollo de herramientas altamente integradas. Usa también un API muy simple orientado a facilitar la programación de un jugador. Dicho API consiste en una serie de clases, interfaces y métodos que representan diferentes facetas del juego. La clase World dispone de varios métodos que facilitan la programación del jugador como por ejemplo el método getObjectAt(int x, int y) que devuelve el objeto situado en la posición (x,y) del tablero, getDirectionTo(int x, int y) que devuelve la dirección que hay que tomar para llegar a una determinada casilla. Las fichas del juego (castillos, campesinos y caballeros) implementan la interfaz correspondiente (ICastle, IPeasant, IKnight) y todas ellas heredan de la interfaz IObject. Cada uno de los objetos creados que implementan dichas interfaces tienen métodos propios de acuerdo a la funcionalidad específica de cada uno. Por ejemplo, a un objeto castillo se le puede ordenar producir campesinos o caballeros; a los campesinos únicamente se les puede ordenar que se muevan a una determinada casilla (reclaman cada casilla por la que se mueven automáticamente) y a los caballeros además de moverse también se les puede ordenar que capturen en una determinada dirección. ¿Cómo funciona? El flujo del programa es el siguiente: al principio de una partida se ejecuta el método initialize, que da la opción de inicializar las estructuras de datos (nosotros lo dejamos en blanco). Después, en cada turno, se ejecuta el método orderSubjects que es el método que hemos implementado. (NOTA: aquí se comprueba la orientación didáctica del programa) Vamos a comentar el funcionamiento de cada uno de los participantes del juego. Empezaremos por los castillos, que están situados en un lugar predeterminado al principio de la partida, que en todo momento pertenecen a un señor feudal, pueden ser capturados por otro señor feudal sin más complicacion que capturar esa casilla por un caballero de otro bando. Dichos castillos son la fuente de producción de caballeros y campesinos. Es obvio que si un señor feudal tiene el doble de castillos que otro producirá exactamente el doble de caballeros o campesinos. En el caso de que un señor feudal se quede sin castillos, deberá intentar a toda costa conquistar al menos uno para no quedarse sin activos, lo que le llevaria irremediablemente a perder la partida. Hay que mencionar que los castillos, al contrario de lo que se espera, no tienen ninguna defensa en sí, sino que esta debe hacerse a través de los caballeros y campesinos .Los primeros harán una defensa activa, pudiendo atacar a las posibles amenazas del castillo, mienstras que los segundos sólo podrán servir para una defensa pasiva, es decir, que sean atacados ellos en vez del castillo (efecto “escudos humanos”). En segundo lugar, los caballeros son unidades de combate y conquista. Es decir, se dedican a pelear con los caballeros de otros bandos, a matar campesinos y a conquistar castillos. Hay que reseñar que para tomar un castillo o matar a un campesino basta con ocupar la casilla en la que se encuantran. En el caso de un enfrentamiento con otro caballero la suerte de la pelea se decide por una cuenta de puntos de fuerza que se reduce en el caso del caballero atacado, (si llega a 0 esta cuenta, el caballero muere) quitándose en cada ataque entre 15 y 30 puntos de fuerza. Cada vez que un caballero mata a otro, incrementa su cuenta en 20 puntos, y no pierde puntos cuando ataca, sino cuando es atacado. Es obvio que la parte más crítica del juego es la programación del comportamiento de los caballeros, y debe hacerse con sumo ciudado. Por último, los campesinos se dedican fundamentalmente a ocupar la tierra. La funcionalidad de los campesinos no puede ser más simple: solo pueden moverse o quedarse quietos. Reclaman para su señor feudal cada casilla a la que se mueven, coloreándola del color del estandarte de su señor. La tierra conquistada por los campesinos sirve para aumentar la producción del castillo, es decir, cuanta más tierra tenga el señor feudal, menos turnos tardan sus castillos en producir activos (campesinos y caballeros). ¿Qué reglas tiene? CodeRuler tiene dos tipos de reglas: el primer conjunto está dedicado a evitar irregularidades en la utilización del API, y el segundo tiene que ver con el desarrollo del juego propiamente dicho. En el primer conjunto de reglas, CodeRuler no nos permite usar una serie de funcionalidades de Java como son los constructores, bloques de inicialización, hilos, acceder a una red y escribir en archivos. En cualquier competición se descalificará a cualquiera que haga uso de éstas técnicas fraudulentas (desde el punto de vista de CodeRuler, claro). El otro conjunto de reglas se reduce básicamente a las temporizaciones, queriendo evitar así costes computacionales excesivamente altos, que ralentizarían excesivamente el juego. El límite es de 1 segundo para el método initialize, y de 0,5 segundos para el método orderSubjects. Si te excedes en el caso de initialize se suspende la ejecución del método cuando finaliza el segundo (el resto de código no se ejecuta). En cambio, si se supera el tiempo asignado a orderSubjects, el jugador no podrá volver a ejecutar este método, y por tanto no podrá hacer más movimientos ni crear más unidades. Hay que mencionar que, sin embargo, esto no impide necesariamente la victoria del jugador, puesto que si ocurre esto cuando ya no quedan (por ejemplo) caballeros o castillos enemigos en el tablero, el jugador ganará igualmente. Por último, comentar que el número mínimo de jugadores es 2 y el máximo es 6. Jugando uno contra uno es donde se aprecia de manera más evidente la bondad de las estrategias y de los algoritmos utilizados, el caso de tres jugadores es el más complicado de abordar puesto que dos de ellos pueden centrarse en aniquilar al tercero y en el caso de que haya cuatro o más jugadores la componente aleatoria aumenta como es lógico (este punto se abordará de manera más extensa posteriormente). ¿Qué hay que hacer para programar un jugador de Coderuler? Hay que crear un proyecto de CodeRuler en el Eclipse, luego hay que implementar los métodos initialize y orderSubjects, y después sólo queda lanzarlo en el entorno CodeRuler (compilar y ejecutar el código). Esto es lo que hay que hacer para jugar, pero para lo verdaderamente importante, que es ganar, es necesario comprender los detalles de la dinámica del juego, así como implementar estrategias que optimizan el rendimiento del ejército en sí. En este punto, es perentorio destacar que no por usar estrategias con “inteligencia” muy elevada (y por tanto, muy compleja) se gana más y mejor. ¿cómo se gana? Se gana por puntos. Al final de la partida, el que más puntos tiene, gana. Se suman puntos de dos maneras: conquistando/matando caballeros, campesinos y castillos, y p Si se mata a un campesino, se ganan cuatro puntos para la cuenta global de ese jugador, si se mata a un caballero son 6 punto más, y por último, si se conquista un castillo, se sumarán quince puntos. ESTRATEGIAS SEGUIDAS ¿Cómo defendemos un castillo? Los castillos no poseen una tropa regular de caballeros destinados a defenderlos, sino que se ocupan de esta labor los caballeros recién creados dado que éstos atacaran al caballero enemigo más cercano, como se crean en el castillo atacarán por lo tanto al caballero enemigo más cercano. Esta estrategia, absolutamente innovadora, inhibe a nuestro sistema de tener que asignar un número fijo de caballeros a la defensa de los castillos. Tiene la ventaja de que con una alta producción de caballeros, los castillos son prácticamente inconquistables, y por otro lado, con una producción media o baja, están mucho mejor defendidos (y sin comprometer las ofensivas sobre los objetivos enemigos) que de la otra manera. Esta estrategia tiene como inconveniente (por llamarlo así) el hecho de que los caballeros “recién nacidos” no se lanzan inmediatamente a la conquista de castillos, caballeros o campesinos, sino que sacrifican una serie de turnos en la defensa del castillo donde fueron creados. Algunos pueden llegar a morir en esta tarea, no llegando nunca a realizar ninguna conquista, pero es el precio que hay que pagar por una defensa efectiva. ¿Cómo se organizan los caballeros? Una quinta parte de los caballeros se van a dedicar a conquistar castillos. Aún en el caso de que tengamos muy pocos caballeros, siempre habrá al menos dos que se dediquen a ello, salvo en el caso de que no haya ni dos caballeros vivos. Si el caballero es uno de los que tienen que conquistar castillos (y quedan castillos por conquistar), se irá a por el más cercano. En el caso de que no sea uno de esos caballeros, también tendrá sus prioridades: ante la duda, primero atacar a los castillos; si no los hubiera dentro de su zona de influencia, atacarían a los caballeros enemigos que encontraran dentro de esta; si tampoco hubiera caballeros, atacarán a los campesinos, y por último, si no hubiera ni campesinos, el caballero, (con gran tristeza) se movería a otra casilla aleatoriamente, esto permite que los campesinos puedan conquistar todas las casillas del mapa, porque en el caso de que el caballero se quedara quieto en una casilla que no nos perteneciera ésta no podría ser conquistada por los campesinos. ¿Cómo actúan los campesinos? Como se mencionó en la parte de la descripción del juego, los campesinos son los encargados de poseer la tierra para su amo, y cuanta más tierra posean, más producirán los castillos de dicho señor feudal. Un campesino actuará de la siguiente manera: primero mira si tiene que huir de la presencia de alguna amenaza. Si es el caso, buscará la mejor dirección de huida, y si no es el caso, se moverá, intentando hacerlo en dirección contraria a la del campesino (de nuestro bando) más cercano. Esto se hace así porque lo que se busca es que los campesinos recorran la mayor superficie posible, y se consigue separándolos, es decir, haciendo que sus caminos diverjan al máximo. En el caso de que la tierra que hay en dirección opuesta a la del campesino amigo más cercano caiga fuera de los bordes, o sea ya nuestra, el campesino busca una dirección en la que haya tierra sin conquistar por nosotros. El campesino elige una de las ocho posibles direcciones que puede tomar (N,S,E,O,NE,NO,SE,SO) , y si no hay ninguna en las casillas adyacentes utilizará un algoritmo de búsqueda en anchura para encontrar la casilla que no nos pertenece más cercana. Los campesinos huyen de sus amenazas porque no tienen ninguna posibilidad a la hora de hacerles frente, y también porque huyendo no pierden la posesión de la tierra conquistada, puesto que los caballeros enemigos no se la pueden arrebatar, sino los campesinos enemigos, cuando lleguen. ¿Qué criterio se sigue para la producción en un castillo? Por defecto se crearan caballeros salvo las siguientes excepciones. Cuando queden menos de cinco campesinos vivos, lo cual nos garantiza que se podrán seguir reclamando tierras para aumentar la producción de los castillos; otro caso es cuando ya no queden ni caballeros ni castillos enemigos, y por lo tanto no nos queden más amenazas y hayamos ganado prácticamente la partida, en este caso se producirán campesinos para conquistar rápidamente la totalidad del mapa (asegurándonos más puntos) en cuanto la casi totalidad del mapa esté conquistada se comenzará de nuevo a producir caballeros para aumentar aún más la cantidad de puntos dado que cada caballero que quede vivo al final de la batalla sumará dos puntos (los campesinos únicamente suman uno). Esta estrategia es, una vez más, una muestra del planteamiento ofensivo del que hemos hecho gala a lo largo de toda la práctica. Las partidas se ganan, en nuestra opinión, conquistando cuanto antes los castillos enemigos, y cortando así la producción del enemigo le estamos abocando inexorablemente a la derrota. Una estrategia que primara la producción de campesinos frente a la de caballeros tendría el serio inconveniente de que a medio plazo dejaría al señor feudal sin lo uno ni lo otro pues los campesinos serían incapaces de defender los castillos, que caerían en manos enemigas más tarde o más temprano. No obstante hay que mencionar que no se puede abandonar por completo la producción de campesinos, puesto que el número de caballeros nuevos decrecería al mismo ritmo que baja la superficie controlada por nuestro señor feudal. A continuación comentamos una serie de capturas correspondientes a una partida que ilustran las estrategias seguidas. En esta imagen se observa la estrategia seguida por los campesinos, que se dispersan rápidamente por el mapa. Aquí se observa la táctica de los caballeros, la flecha situada más al sur indica los dos caballeros en cargados de conquistar el castillo enemigo más cercano, mientras que los otros caballeros se dedican a atacar al caballero enemigo más cercano. En este caso en la flecha situada al sur se aprecia que los caballeros encargados de conquistar el castillo han logrado su objetivo. En la flecha situada al noreste se encuentra un campesino huyendo de un caballero enemigo mientras que en la flecha noroeste se encuentran varios caballeros recién creados defendiendo el castillo de la amenaza que representa el caballero morado; esto pone de relieve que la estrategia de defensa del castillo es efectiva. En esta imagen se observa que los caballeros caza castillos situados al sur han completado su objetivo y se dirigen hacia el siguiente castillo. Mientras que los caballeros del norte, una vez eliminada la amenaza al castillo se dirigen a defender al campesino que está siendo perseguido. Aquí se observa que los caballeros caza castillos han conseguido conquistar el castillo que se proponían, también en la misma zona se observa que los caballeros recién creados contribuyen a la defensa del castillo. Una vez capturados todos los castillos y eliminado todos los caballeros enemigos sólo queda eliminar los campesinos, además comienza la producción de campesinos para ocupar todo el mapa lo más rápidamente posible. En esta imagen se observa la eficacia de la generación de nuevos campesinos, que en pocos turnos aumentan el ritmo de conquista de territorio; en esta imagen ya se ha conseguido eliminar totalmente al enemigo. Aquí se aprecia que tenemos la práctica totalidad del mapa conquistado, por lo tanto comienza la producción de caballeros para aumentar la puntuación total. CÓDIGO FUENTE Y COMENTARIOS import com.ibm.ruler.*; import java.awt.Point; import java.util.Random; import java.util.Vector; public class MyRuler extends Ruler { public String getRulerName() { return "Equipo A"; } public String getSchoolName() { return "HO HO HO"; } public void initialize() { } protected Random rand = new Random(); public void orderSubjects(int lastMoveTime) { // Amigos ICastle[] castillos = getCastles(); IPeasant[] peasants = getPeasants(); IKnight[] knights = getKnights(); //Enemigos IRuler[] contrincantes = World.getOtherRulers(); IPeasant[] otherPeasants = World.getOtherPeasants(); IKnight[] otherKnights = World.getOtherKnights(); ICastle[] otherCastles = World.getOtherCastles(); //Siempre crear caballeros for(int i = 0; i<castillos.length;i++){ //salvo cuando quedan menos de 5 campesinos o cuando hemos eliminado todas las amenazas y no controlamos la mayoría del tablero if(((numeroVivos(peasants)< 5) || (otherKnights.length==0 && otherCastles.length==0))&& this.getOwnedLandCount()< 4000 ) createPeasants(castillos[i]); else createKnights(castillos[i]); } // Mover campesinos moverCampesinos(peasants, otherKnights); // Mover caballeros moverCaballeros(knights, otherCastles, otherKnights, otherPeasants, castillos); } /* * Para mover los caballeros utilizaremos una tactica ofensiva, consistira en atacar los castillos * enemigos y atacar a los caballeros enemigos, cada uno al que tenga mas cerca. */ public void moverCaballeros(IKnight[] cab, ICastle[] casE, IKnight[] cabE, IPeasant[] camE, ICastle[] cas ){ IObject castillo; // Castillo dentro de la zona de influencia del caballero int cazaCastillos; // Un quinto de los caballeros se convierten en caza castillos, cazaCastillos = cab.length/5; // Aunque tengamos menos de 10 caballeros al menos dos se dedicarán a conquistar castillos if (cazaCastillos<2) cazaCastillos=2; // Si no tentemos castillos todos se convierten en caza castillos if(cas.length==0) cazaCastillos= cab.length-1; // Recorremos la matriz de caballeros amigos uno a uno for(int i=0; i<cab.length;i++){ /* * En el caso de que no haya ninguna amenaza tenemos que hacer q dos caballeros * vayan a por el castillo enemigo, y el resto ataquen al bicho mas cercano */ // Los caza castillos actúan como tales siempre y cuando haya castillos enemigos, // si no los hay éstos caballeros se comportan como los caballeros normales. if(i<cazaCastillos && casE.length!=0){ moveAndCapture(cab[i], masCercano(cab[i], casE), cas); }else{ // Los caballeros normales se comportan de la siguiente manera // Primero vemos si tiene algun castillo en su radio de accion castillo=atacarCastillo(cab[i], casE); if(castillo!= null){ // En el caso de que lo tengan lo atacan moveAndCapture(cab[i],castillo, cas); continue; } // Si no tiene que atacar a ningun castillo ataca al caballero enemigo más cercano if(cabE.length!=0){ moveAndCapture(cab[i],masCercano(cab[i],cabE), cas); }else{ // Si no quedan caballeros atacan a los campesinos if(camE.length!=0){ moveAndCapture(cab[i],masCercano(cab[i],camE), cas); }else{ // Si no quedan campesinos se mueven aleatoriamente move(cab[i], rand.nextInt(8) + 1); } } } } } /* * Devuelve el objeto mas cercano dado un objeto y un grupo de objetos */ public IObject masCercano(IObject io, IObject[] ios){ int temp=0; int distancia=1000000; int indice=0; // se recorre la matriz comparando distancias y quedándonos con la distancia más corta // y el índice al que corresponde for(int j=0; j< ios.length; j++){ temp=io.getDistanceTo(ios[j].getX(), ios[j].getY()); if(temp < distancia && temp!=0){ distancia=temp; indice = j; } } // devolvemos el objeto más cercano return ios[indice]; } /* * Este metodo esta diseñado para que los caballeros ataquen a un castillo enemigo que se encuentre * muy cerca suyo, asi se consigue que no se pierdan oportunidades de conquistar castillos */ public IObject atacarCastillo(IKnight cab, ICastle[] casE){ int x; int y; int direccion; x=cab.getX(); y=cab.getY(); IObject objeto; //Analizamos todos los cuadrados hasta una distancia de dos en busca de castillos enemigos for(int i=-2;i<3;i++){ for(int j=-2; j<3;j++){ // Si hay enemigos devolvemos al que tenemos que atacar objeto=World.getObjectAt(x+i,y+j); if(objeto!=null && estaEnGrupo(objeto, casE)){ return objeto; } } } // si no encontramos ningun enemigo devolvemos null return null; } /* * Metodo que define si un determinado objeto se encuentra en una matriz o no */ public boolean estaEnGrupo (IObject io, IObject[] ios){ // Se recorre la matriz comparando cada objeto con el que se ha pasado por parámetro for(int i=0; i<ios.length;i++){ // Si el objeto está devolvemos true if (io.equals(ios[i])) return true; } // Si después de recorrer la matriz no lo encontramos devolvemos false return false; } /* * Metodo que dado un objetivo hace que el caballero se mueva hacia él y lo capture, * capturando a su vez todo lo que se encuentre en el camino */ public void moveAndCapture(IKnight knight, IObject enemy, ICastle[] cas) { if ((enemy == null) || !enemy.isAlive()) return; // Encontrar la siguiente posicion en la direccion del enemigo. int dir = knight.getDirectionTo(enemy.getX(), enemy.getY()); Point np = World.getPositionAfterMove(knight.getX(), knight.getY(), dir); if (np == null) return; if ((np.x == knight.getX()) && (np.y == knight.getY())) { move(knight, rand.nextInt(8) + 1); return; } // Capturar cualquier cosa que este en nuestro camino IObject obj = World.getObjectAt(np.x, np.y); if ((obj != null) && (obj.getRuler()!= this)){ capture(knight, dir); return; } if ((obj != null) && (estaEnGrupo(obj, cas))){ move(knight, rand.nextInt(8) + 1); } move(knight, dir); } /* * Este metodo hace que los campesinos se muevan hacia el lugar mas alejado * de otro campesino expandiendose siempre que el cuadrado donde vayan a moverse este libre * tambien huyen en caso de que tengan algun enemigo cerca * */ public void moverCampesinos(IPeasant[] campesinos, IKnight[] CabE){ IObject cercano; int direccion; int direccionHuida; Point punto; boolean movido=false; // Recorremos el vector de campesinos for (int i = 0; i < campesinos.length; i++) { movido=false; // Primero miramos si debemos huir direccionHuida=huir(campesinos[i], CabE); if(direccionHuida!=-1){ move(campesinos[i],direccionHuida); continue; } // Buscamos el campesino mas cercano cercano=masCercano(campesinos[i], campesinos); direccion=campesinos[i].getDirectionTo(cercano.getX(),cercano.getY()); direccion=(direccion+4);// Para moverse en la dir contraria if(direccion>8) direccion=direccion-8; /* * Ahora tenemos la direccion contraria al campesino mas cercano, si esa dir * esta fuera de los bordes o si esta ya reclamada */ /* * Probamos las 8 posibles direcciones buscando alguna tierra para reclamar, * si no la encontramos nos movemos aleatoriamente */ for(int k=0; k<8 && !movido; k++){ if(direccion+k>8){ direccion=direccion-8; } punto=World.getPositionAfterMove(campesinos[i].getX(),campesinos[i].getY(),direccion+k); if(punto!=null && World.getLandOwner(punto.x,punto.y) == null && World.getObjectAt(punto.x,punto.y)==null){ move(campesinos[i],direccion+k); movido=true; }else{ if(punto!=null && World.getLandOwner(punto.x,punto.y) != this && World.getObjectAt(punto.x,punto.y)==null){ move(campesinos[i],direccion+k); movido =true; } } } // Si al final no hemos encontrado ningun cuadrado para conquistar nos movemos al cuadrado mas cercano q no este conquistado if(!movido) move(campesinos[i], tierraAConquistar(campesinos[i])); } } /* * Metodo que devuelve la direccion en la que se tiene que mover un campesino para ir a la tierra sin conquistar mas cercana */ public int tierraAConquistar(IPeasant cam){ for(int radio=1;radio<30; radio++){ for(int i=-radio;i<=radio;i++){ if((cam.getX()+radio)<72 (cam.getY()+i)<64 && && (cam.getY()+i)>-1 World.getLandOwner(cam.getX()+radio,cam.getY()+i)!= this && && World.getObjectAt(cam.getX()+radio,cam.getY()+i)==null){ return cam.getDirectionTo(cam.getX()+radio, cam.getY()+i); } if((cam.getX()+i)>-1 (cam.getY()+radio)<64 && &&(cam.getX()+i)<72 World.getLandOwner(cam.getX()+i,cam.getY()+radio)!= && this && World.getObjectAt(cam.getX()+i,cam.getY()+radio)==null){ return cam.getDirectionTo(cam.getX()+i, cam.getY()+radio); } if((cam.getX()-radio)>-1 (cam.getY()+i)<64 && && (cam.getY()+i)>-1 World.getLandOwner(cam.getX()+radio,cam.getY()+i)!= this && && World.getObjectAt(cam.getX()-radio,cam.getY()+i)==null){ return cam.getDirectionTo(cam.getX()-radio, cam.getY()+i); } if((cam.getX()+i)>-1 &&(cam.getX()+i)<72 && (cam.getY()-radio)>1 && World.getLandOwner(cam.getX()+i,cam.getY()-radio)!= this && World.getObjectAt(cam.getX()+i,cam.getY()-radio)==null){ return cam.getDirectionTo(cam.getX()+i, cam.getY()-radio); } } } return rand.nextInt(8) + 1; } /* * Metodo que devuelve el numero de bichos que aun siguen vivos dado una matriz */ public int numeroVivos(IObject objetos[]){ int vivos=0; for(int i=0;i<objetos.length;i++){ if(objetos[i].isAlive()) vivos++; } return vivos; } /* Este metodo devuelve la direccion por la que tiene que huir el campesino * o -1 si resulta que no tiene necesidad de huir */ public int huir(IPeasant campesino, IKnight[] cabE){ int x; int y; int direccion; x=campesino.getX(); y=campesino.getY(); IObject objeto; //Analizamos cada uno de los 9 cuadrados adyacentes en busca de enemigos for(int i=-5;i<6;i++){ for(int j=-5; j<6;j++){ // Si hay enemigos decidimos la direccion de huida objeto=World.getObjectAt(x+i,y+j); if(objeto!=null && estaEnGrupo(objeto, cabE) && objeto.isAlive()){ direccion=campesino.getDirectionTo(x+i,y+j); direccion=direccion + 4;//para tener la direccion contraria if(direccion>8) direccion=direccion-8; while(World.getPositionAfterMove(x,y,direccion)==null){ // Si la direccion de huida esta fuera de limites entonces aumentamos en uno // esta direccion (esto no vale en el caso de las esquinas direccion++; if(direccion>8) direccion=direccion-8; } return direccion; } } } return -1; } }