CODERULER(4 paginas) ¿Qué es? CodeRuler es un juego que

Anuncio
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;
}
}
Descargar