aauuttoorreess eelleennaa aallaaññaa ssaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf ·...

24
A A A u u u t t t o o o r r r e e e s s s E E E l l l e e e n n n a a a A A A l l l a a a ñ ñ ñ a a a S S S a a a l l l a a a z z z a a a r r r E E E d d d u u u a a a r r d d d o o o F F F e e e r r r n n n á á á n n n d d d e e e z z z M M M a a a t t t a a a m m m a a a l l l a a a

Upload: others

Post on 18-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

AAAuuutttooorrreeesss

EEEllleeennnaaa AAAlllaaañññaaa SSSaaalllaaazzzaaarrr EEEddduuuaaarrrdddooo FFFeeerrrnnnááánnndddeeezzz MMMaaatttaaammmaaalllaaa

Page 2: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 2 de 24 Eduardo Fernández Matamala

ÍNDICE

U Página

• Introducción…………………………………………...3 o Robocode………………………………………………………..3 o Reglas del juego………………………………………………....3

• Campo de batalla……………………………………..4

• Robots…………………………………………………..4 o Descripción general……………………………………………..4 o Movimientos…………………………………………………….5 o Ángulos………………………………………………………….6

♦ Heading………………………………………………….6 ♦ Bearing…………………………………………………..6

o Acciones………………………………………………………....6 o Eventos…………………………………………………………..7

• Decisiones de diseño de Robot individual……..…..7

o Estrategia………………………………………………………..8 ♦ Movimientos…………………………………………….8 ♦ Disparo…………………………………………………..9 ♦ Potencia de disparo ……………………………………...9 ♦ Otras consideraciones…………………………………..10

• Decisiones de diseño del equipo………….………..10 • Banco de pruebas…………………………………….11

• Código Aplasteitor.java……………………………..12

• Código Enemigo.java………………………………..21

• Bibliografía…………………………………………...24

Page 3: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 3 de 24 Eduardo Fernández Matamala

INTRODUCCIÓN

URobocode ‘Robocode’ es un simulador de guerras entre tanques robóticos programados en java que posteriormente son cargados en un simulador donde se desarrolla el combate y donde al final solo debe quedar uno vivo. El simulador proporciona un API con una serie de objetos y métodos que dejan total libertad para programar el tanque. El jugador debe elegir la mejor estrategia pudiendo controlar el tanque con desplazamientos, giros, control de radar, control de cañón y disparo. Además debe controlar todos los eventos que se producen (ser impactado por una bala, detectar a un enemigo, chocar contra una pared,…).

UReglas del juego Existen dos modalidades de juego: batalla individual, en el que cada robot lucha contra todos los demás, y batalla en equipo, en el que un ejército de robots lucha por la victoria de modo colaborativo. Cuando arranca el torneo, los tanques son colocados aleatoriamente por todo el campo de batalla. Debido a que una mala situación inicial puede influir de manera decisiva en el desarrollo del juego, se suelen realizar varios torneo siendo el ganador el que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan con una determinada energía (100, excepto en lucha en equipo en la que aquellos tanques que no tienen la funcionalidad de radar – los Droids - tienen una energía extra de 20 y el líder del equipo tiene un total del 200). Esta energía disminuirá a medida que el robot sea impactado por balas procedentes de otros tanques, cuando el propio tanque dispare una bala, cuando se choque con otro robot y, si es un ‘Advanced Robot’ (explicado más adelante), cuando choque con alguna pared. Y la energía aumentará cuando un disparo del robot impacte sobre un enemigo. Cuando su energía sea cero ya no podrá efectuar ningún disparo quedando en estado ‘disabled’, y cuando vuelvan a impactar en él morirá. Solamente puede salir de ese estado si alguna de las balas que había lanzado anteriormente golpea en otro tanque (recuperaría algo de energía). La cantidad de energía ganada o perdida dependerá de varios factores como por ejemplo:

- En el caso de que una bala, golpee a un tanque, éste sufrirá un daño dado por: 4 * power; Si power es mayor que , el daño será 4 * power+ 2 * (power-1); Siendo ‘power’ la potencia con la que se lanza la bala, y tiene un valor entre 0.1 y 3. Asimismo, este valor de ‘power’ será restado en la energía del robot que lanza la bala.

Page 4: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

CAMPO DE BATALLA

El campo de batalla puede ser rectangular o cuadrado (cualquier tamaño entre 400x400 y 5000x5000) siendo el origen de coordenadas (0,0) el vértice inferior izquierdo. Para obtener las dimensiones del campo se pueden utilizar las siguientes funciones:

double getBattleFieldHeight() double getBattleFieldWidth()

En cualquier momento puedo obtener mi posición en el campo mediante las instrucciones:

double getX() double getY()

Una buena práctica para la implementación de robots es controlar cuando se choca contra una de las paredes, o bien, evitar el choque con las mismas. Si se produce un choque, produce el evento ‘HitWallEvent’.

ROBOTS

Descripción general Los robots pueden heredar de las clases ‘Robot’, ‘AdvancedRobot’ o ‘TeamRobot’. Se diferencian fundamentalmente en que la clase ‘Robot’ dispone únicamente de los métodos básicos para la implementación de un robot. ‘AdvancedRobot’ hereda a su vez de la clase Robot y permite, además de todas las funciones básicas, otras más avanzadas. Por último la clase ‘TeamRobot’ hereda de ‘AdvancedRobot’ y permite el intercambio de mensajes entre robots de un mismo equipo. Cada robot está formado por el vehículo que lo desplaza o cuerpo, el cañón con el que disparan, y un radar con el que son capaces de detectar a sus enemigos.

Figura 1.- Componentes de un tanque

Elena Alaña Salazar Página 4 de 24 Eduardo Fernández Matamala

Page 5: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Movimientos Al comenzar, todas las partes de las que se compone el tanque están alineadas y forman una unidad, es decir, cuando un tanque giran, el cañón y el radar harán el mismo movimiento a no ser que se le indique lo contrario. Esto viene del hecho de que el cañón está montado sobe el cuerpo y el radar sobre el cañón. Entonces si giro el cuerpo para la izquierda 45º, tanto el cañón como el radar, girar 45º para la izquierda. Si giro el cañón, el cuerpo no se mueve, pero si lo hace el radar. Y por último, si muevo el radar, no se mueve nada más. En caso de que queramos que el cañón no gire cuando lo haga el cuerpo y/o que el radar no gire cuando lo haga el cañón y/o el cuerpo, emplearemos las siguientes instrucciones: - void setAdjustGunForRobotTurn(boolean newAdjustGunForRobotTurn): para tener un movimiento del cañón independiente del cuerpo - void setAdjustRadarForGunTurn(boolean newAdjustRadarForGunTurn): para tener un movimiento del radar independiente del cañón. - void setAdjustRadarForRobotTurn(boolean newAdjustRadarForRobotTurn): para tener un movimiento del radar independiente del robot. Y para mover el radar y el cañón a derechas y a izquierdas un cierto ángulo:

- void turnGunLeft(double degrees) - void turnGunRight(double degrees) - void RadarLeft(double degrees)

- void RadarRight(double degrees) Un tanque puede realizar los siguientes movimientos:

o Moverse hacia delante o hacia atrás una determinada distancia: - void ahead(double distancia) - void back(double distancia) o Girar hacia la derecha o hacia la izquierda un determinado ángulo: - void turnLeft(double degrees) - void turnRight(double degrees)

Ninguna acción devuelve el control del programa hasta que termine de ejecutarse.

Elena Alaña Salazar Página 5 de 24 Eduardo Fernández Matamala

Page 6: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 6 de 24 Eduardo Fernández Matamala

UÁngulos U1.- Heading

UFigura 2.- Ángulo UHeading

Los movimientos se realizan tomando como punto de referencia el heading del tanque. Llamamos UheadingU a la dirección en la que está orientada la parte delantera del tanque. También denotaremos el Uángulo de headingU como aquel que forma la orientación de la parte delantera del tanque con respecto a la vertical. Abarca valores de 0º 360º

U2.- Bearing

UFigura 3.-Ángulo Bearing

El ángulo de UbearingU nos indica el ángulo que existe entre mi heading y la dirección en la que he detectado un enemigo. Este ángulo alcanza unos valores entre -180º y 180º. Por lo que si es positivo indica que el enemigo está a mi derecha y si es negativo a mi izquierda.

UAcciones U

Las acciones que puede realizar son:

o Scan: para detectar si existe algún enemigo. - void scan() o Disparar: contra un enemigo que hemos detectado. Cuando disparamos

lo podemos hacer con distintos niveles de potencia que se lo indicamos como parámetro.

- void fire(double power)

Page 7: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 7 de 24 Eduardo Fernández Matamala

UEventos Durante la partida se pueden producir los siguientes eventos:

ScannedRobotEvent (10): se produce cuando un robot detecta a otro. HitRobotEvent (20): evento que se produce cuando tu robot choca contra

otro robot. HitWallEvent (30): se produce cuando tu robot choca contra una pared. HitByBulletEvent (40): evento que se produce cuando tu robot es impactado

por una bala. BulletHitEvent (50): evento que se produce cuando una de las balas que

lanzó tu robot impacta a otro. BulletHitBulletEvent (50): evento que se produce cuando una de las balas

que lanzó tu robot impacta con otra bala que lanzó otro robot. BulletMissedEvent (60): evento que se produce cuando una de las balas que

lanzó tu robot se pierde, es decir, llega a impactar en una pared. RobotDeathEvent (70): evento que se produce cuando otro robot muere. CustomEvent (80): Son eventos creados por el usuario DeathEvent (100): evento que se produce cuando tu robot muere. WinEvent (100): evento que se produce cuando tu robot gana una batalla.

Entre paréntesis está indicada la prioridad de cada evento, siendo 10 la menos prioritaria y 100 la más prioritaria.

DECISIONES DE DISEÑO ROBOT INDIVIDUAL

Nuestro robot hereda de ‘AdvancedRobot’. La principal razón es que extendiendo de la clase ‘Robot’ todas las acciones que se ejecutan no devuelven el control al código hasta que finalizan, mientras que extendiendo de la otra, puedes concatenar acciones que se realizarán a la vez (se puede girar mientras avanzas y disparas – con ‘Robot’ primero giras estando quieto, cuando termines de girar avanzas y cuando termines de avanzar, disparas) En este caso todas las funciones básicas que disponía la clase ‘Robot’ pueden seguir siendo utilizadas. Sin embargo, ahora se añaden algunas funciones avanzadas. Por ejemplo además de las acciones de movimiento mencionadas anteriormente disponemos de las siguientes: - setTurnRight() - setTurnLeft() - setTurnGunRight() - setTurnGunLeft() - setTurnRadarRight() - setTurnRadarLeft() - setAhead() - setBack()

Page 8: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 8 de 24 Eduardo Fernández Matamala

Se diferencian básicamente en que todas estas instrucciones se van almacenando y solo se ejecutan cuando llamamos a la función execute(), lo que permite la realización de varias acciones a la vez.

UEstrategia U1.- Movimiento

• Durante el movimiento del robot siempre se mantienen alineados la orientación del cañón y del radar. Por el contrario su movimiento es independiente del movimiento que realice el tanque. Para ello usamos las instrucciones:

setAdjustGunForRobotTurn(true);

setAdjustRadarForRobotTurn(true);

• Una vez que definimos un objetivo comenzamos a desplazarnos con un

movimiento de balanceo (circular) avanzando progresivamente hacia él, llegando a una distancia límite (600) en la que no sigue avanzando, pero sí que se mantiene el movimiento de balanceo.

• Debido a que nuestro robot hereda de la clase ‘AdvancedRobot’ pierde energía si

se golpea contra alguna pared. Por ello, siempre le mantenemos a una distancia límite de ella, y cuando se acerca le hacemos que se aleje de ella. Este método nos dice si el robot está cerca de la pared y a la vez, el ángulo absoluto hacia el que tenemos que avanzar para alejarnos de ella.

public double inWall(double x,double y) { if(x<limit2) return 90; else if(x>(width-limit2)) return 270; else if (y<limit2) return 0; else if(y>(height-limit2)) return 180; return -1; }

Page 9: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 9 de 24 Eduardo Fernández Matamala

2.- Disparo

• Una vez que hemos determinado el objetivo al cual vamos a disparar, empleamos de forma general un disparo lineal.

o Cuando únicamente queda un solo objetivo vamos alternando el tipo de disparo. Utilizamos tanto un disparo lineal como uno circular. Cambiamos de un tipo de disparo a otro en el momento en el que hemos fallado un número determinado de balas.

Disparo Lineal

public void linearFire() { setTurnGunRight(normalRelativeAngle(getHeading()-getGunHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),getHeading()))); }

Disparo Circular public void circularFire(double power){ double x,y; long time = getTime() + (int)(enemigoInmediato.distance(getX(),getY())/(20-(3*power))) - enemigoInmediato.time; x = enemigoInmediato.x+Math.sin(Math.toRadians(enemigoInmediato.heading))*enemigoInmediato.velocity*time/1.5; y = enemigoInmediato.y+Math.cos(Math.toRadians(enemigoInmediato.heading))*enemigoInmediato.velocity*time/1.5; setTurnGunRight(normalRelativeAngle(getHeading()- getGunHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),x,y,getHeading()))); }

3.- Potencia de disparo

• La potencia de disparo se va variando dependiendo de la distancia a la que nos encontremos del objetivo. El criterio elegido es el siguiente:

o Obtenemos el resultado de la siguiente expresión:

valordiagonal

ciaDis=

2.0*tan

La distancia es a la que se encuentran ambos robots. Diagonal es el valor de la diagonal del campo de batalla (por

ejemplo para un tamaño de 800x600 es 1000) El resultado de la expresión anterior va a dar como resultado un

valor que es el que aplicamos como criterio de elección de la potencia del disparo.

valor Potencia del disparo

0 3 1 2.4 2 2 3 1 4 0.5

Page 10: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

Elena Alaña Salazar Página 10 de 24 Eduardo Fernández Matamala

• En el caso de que al robot enemigo le quede poca vida, nunca disparamos con

más potencia de la necesaria para matarle.

• En el momento en el que nos quede solamente 3 de nivel de energía ya no disparamos más y simplemente esquivamos las balas de los tanques contrarios. Cuando a los adversarios también les quede ese nivel de energía ya sí podemos volver a disparar.

• Si solamente queda un robot enemigo y su valor de energía es como mucho el

80% de la nuestra, nos acercamos hasta colocarnos a una distancia de 100. 4.- Otras consideraciones

• Siempre mantenemos almacenados los datos de un objetivo. Inicialmente lo elegimos de forma aleatoria, y una vez fijado, cambiamos a otro si falla un determinado número de balas.

o Si al cabo de un determinado tiempo no escaneo al robot que tenía como

objetivo, cambio de objetivo. o Si tenemos un objetivo y fallamos 5 o más balas que van dirigidas hacia

él, cambiamos de objetivo, seleccionando a otro tanque (estaríamos desperdiciando mucha energía, ya que fallamos mucho, así que nos vamos a por otro tanque)

o Si ha fallado más de dos balas hacia el tanque objetivo y chocamos contra otro robot, cambiamos inmediatamente de objetivo y desde ese momento lanzamos balas contra el robot contra el que hemos chocado (cambiamos a este nuevo objetivo más cercano que el otro, en previsión de que con el otro fallemos mucho)

o Si tenemos fijado un objetivo, pero otro tanque nos ha disparado 3 veces seguidas con balas que llevan más fuerza que las que dispara nuestro objetivo, cambiamos a ese otro robot, ya que nos está haciendo más daño.

Decisiones del Equipo

• El equipo está formado por cinco tanques tipo ‘Aplasteitor’. Los tanques saben reconocer que son miembros del mismo equipo para no dispararse entre ellos. Esto lo hacemos mediante este código cuando queremos seleccionar un objetivo:

if (isTeammate(e.getName())){ return; }

Page 11: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

BANCO DE PRUEBAS

Pruebas básicas Una vez finalizada la implementación del robot, lo pusimos a luchar contra los robots que venían de ejemplo en la herramienta de ‘Robocode’. En general, nuestro robot es bastante superior a todos ellos, y obtuvimos buenos resultados como el que se muestra a continuación.

Pruebas avanzadas

Después para comprobar como se comportaba frente a mejores robots, nos descargamos diversos robots de Internet implementados por otra gente. El resultado que obtuvimos no fue tan bueno como el anterior pero aun así se defendía adecuadamente. Un ejemplo del resultado de una batalla es el siguiente:

Elena Alaña Salazar Página 11 de 24 Eduardo Fernández Matamala

Page 12: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

CÓDIGO APLASTEITOR.JAVA

package Aplasteitor; import robocode.*; import java.awt.Color; /* JavaFile * * Fichero: Aplasteitor.java * * Descripción: Clase que implementa la estrategia y movimientos de un robot para poder enfrentarse * en una batalla contra otros robots. * *@author Elena Alaña Salazar & Eduardo Fernández Matamala *@version 1.0 */ public class Aplasteitor extends AdvancedRobot{ /***************** ** Variables ** ******************/ /* Altura, anchura y máxima longitud existente en el campo de batalla */ double height,width,maxLength; /* Tanque que va a ser el objetivo de nuestros disparos en un momento determinado */ Enemigo enemigoInmediato = new Enemigo(); /*Variable auxiliar que nos permitira seleccionar un objetivo */ String enemigoAnterior=""; /*Variable booleana que nos indica el tipo de disparo que queremos hacer en cada momento */ boolean linearFire= true; /*Numero de balas máximo que podemos fallar sobre un objetivo. En caso de fallar 'limitBullets' balas, *cambiamos de objetivo */ int limitBullets = 5; /*Numero de balas fallados sobre un objetivo */ int failedBullets=0; /*Número de enemigos que hay en la partida en cada momento*/ int numberRobots; /*Tiempo máximo que podemos estar sin ver a nuestro objetivo. Si entre dos escaneos al objetivo *pasa más de 'actTime' unidades de tiempo, cambiamos de objetivo */ double actTime = 8; /*Cuando localizamos un objetivo, le seguimos con el escáner, barriendo un ángulo que, tomando * como 0 gradosla direccion que nos une imaginariamente al enemigo, abarca desde +scanAngle *a –scanAngle*/ double scanAngle; /*Dirección en que movemos el radar cuando seguimos un objetivo. *+1 si giramos para la derecha, -1 si giramos para la izquierda */ int scanWay=1; /*Distancia hasta la pared del campo de batalla, que nuestro robot tratara de no sobrepasar. *Intentará estar siempre alejado de la pared al menos 'limit2' unidades de distancia */ double limit2 = 50; //factor para que nos avise de cuando estamos cerca de la pared /*Ángulo de giro cuando nos estamos moviendo en torno a un objetivo */ double turnAngle=30; /*Distancia que va a mantener nuestro robot con el objetivo */ double distance=500; /*Variable que nos indica si el sentido en el que nos movemos en cada instante. *+1 hacia delante y -1 hacia atrás. Ira alternando en toda la partida. Si en el instante t nos *movemos hacia adelante, en el t+1 lo haremos hacia atrás */

Elena Alaña Salazar Página 12 de 24 Eduardo Fernández Matamala

Page 13: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

int dir=1; /*Máxima distancia que recorreremos en cada sentido*/ double amplitude; /*Variable para modelar la distancia del movimiento del robot */ double a=13; /*Variable para modelar la distancia del movimiento del robot */ double b=17; /*Enemigo que nos ha disparado 3 veces seguidas */ String otherEnemy = ""; /*Numero de veces seguidas que un robot nos ha golpeado */ int numberHits= 0; /*Potencia de la bala de mi enemigo inmediato*/ double enemyBulletPower = 0; /*Variable que nos indica si cambiamos de enemigo porque otro robot nos esta dando mucho */ boolean change = false; /*Tiempo en el que damos la orden de cambiar de enemigo*/ long hitTime = -100000; /*Método principal del robot. Este es el método que ejecuta el robot nada mas crearse *Contiene la secuencia de movimientos, disparos, actuaciones... que modelan el *comportamiento del robot a lo largo de la partida. */ public void run(){ setAdjustGunForRobotTurn(true); //No queremos que el cañon gire cuando lo haga el cuerpo setAdjustRadarForRobotTurn(true);//No queremos que el radar gire cuando lo haga el cuerpo height = getBattleFieldHeight(); //Obtenemos la altura del campo width = getBattleFieldWidth(); //Obtenemos la anchura del campo /*Obtenemos la máxima distancia que puede haber en el campo de batalla, que será la *diagonal principal del mismo*/ maxLength=Math.sqrt(Math.pow(height,(double)2)+Math.pow(width,(double)2)); setColors(Color.pink,Color.pink,Color.pink);//Damos color a nuestro robot numberRobots = getOthers();//Obtenemos el número de enemigos iniciales que tenemos /*Establecemos la máxima distancia que nos vamos a mover en cada movimiento. *Si solo hay un robot, nos interesan movimientos mas largos*/ amplitude = numberRobots!=1 ? 200 : 300; /*Bucle infinito que se ejecutara el resto de partida, hasta que el robot gane o muera *Siempre realizamos las mismas acciones, consecutivamente. * *1.-Escaneamos el campo en busca de enemigos, o si ya tenemos un enemigo concreto, colocamos * el radar en el sitio adecuado para no perderle de vista *2.-Disparamos al objetivo, si es que tenemos alguno. */ while (true) { scanField();//Escaneamos shoot();//Disparamos (solo si es necesario) execute();//Ejecutamos las acciones } } /** *Método que nos permite escanear el campo de batalla *Hay dos tipos diferentes de escaneo: * *1.-Si no hemos fijado un objetivo todavía (o queremos busca otro distinto al que tenemos * actualmente) escaneamos el campo entero, 360 grados, para encontrar un objetivo 2.-Si ya tenemos fijado un objetivo, barremos un ángulo de 2*scanAngle en torno a el para poder * tenerle localizado en todo momento

Elena Alaña Salazar Página 13 de 24 Eduardo Fernández Matamala

Page 14: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

*/ public void scanField(){ if(enemigoInmediato.name == null){ /*No tenemos objetivo fijado, por lo que barremos todo el campo en busca de uno*/ scanAngle = 360; } else{ /*Ya tenemos objetivo*/ /*Giramos el escaner hacia el lado contrario al que habíamos girado en el escaneo anterior*/ scanWay=-scanWay; /*Giramos hacia el lado deseado*/ scanAngle = normalRelativeAngle(getHeading()-getRadarHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),getHeading())+scanWay*10); } /*Damos la orden de girar el el radar*/ setTurnRadarRight(scanAngle); } /** *Método que nos permite disparar hacia el objetivo. *Si tenemos un objetivo fijado, se calcula la potencia del disparo en función de la distancia a la que *estemos del mismo. También se tiene en cuenta la energía que tiene el enemigo. Si esta energía es tal *que disparando con menos fuerza de la establecida según la distancia, lograremos matarle, *disparamos con esta energía. *Asimismo, también se comprueba la energía que tenemos nosotros. Si nuestra energía es menor que *un cierto valor y la del enemigo es mayor que la nuestra, no le disparamos para evitar así entrar en el *estado 'Disabled', estado en el que seríamos muy vulnerables y no podríamos contraatacar. Si, por el *contrario, tanto el enemigo como nosotros estamos debajo del umbral limite de energía, disparamos. *Si nuestra energía es mayor que ese valor, disparamos sin problemas. */ public void shoot(){ /*Potencia con la que dispararemos*/ double power; /*Comprobamos que la información sobre nuestro objetivo esta actualizada. *Si no lo esta, no disparamos*/ if(getTime()-enemigoInmediato.time>actTime){ enemigoInmediato.name = null; failedBullets = 0; enemigoAnterior = ""; } if(enemigoInmediato.name != null){ /*Tenemos un objetivo al que disparar*/ /*Si el objetivo que tenemos es el ultimo enemigo con vida y su energía es menor *que un determinado tanto por ciento de la nuestra, establecemos que *la distancia al enemigo sea de 100, tratando de aprovechar la superioridad en energía*/ if(numberRobots==1 && 0.8*getEnergy() >= enemigoInmediato.energy) distance = 100; /*Establecemos la potencia con la que queremos disparar en función de la distancia a la que se *encuentre el objetivo*/ switch((int)Math.floor(((double)(enemigoInmediato.distance(getX(),getY())/maxLength))/(double)0.2)){ case 0: power = 3; break; case 1: power = 2.4; break; case 2: power= 2.0; break;

Elena Alaña Salazar Página 14 de 24 Eduardo Fernández Matamala

Page 15: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

case 3: power= 1.0; break; default: power=0.5; } /*Si la energía que tiene el enemigo es tan pequeña que con un disparo de menor potencia podemos *matarle, no es necesario disparar con mayor potencia*/ power = Math.min(power, enemigoInmediato.energy >= 4 ? (enemigoInmediato.energy + 2) / 6 : enemigoInmediato.energy / 4); /*Establecemos el método de apuntamiento del cañón*/ if(linearFire) linearFire(); else circularFire(power); /*Si nuestra energía es mayor que este valor, o si siendo menor, la del enemigo también es menor *que el mismo valor disparamos, si no, no*/ if(getEnergy()>=3 || (getEnergy()<3 && enemigoInmediato.energy < 3)){ setFire(Math.min(power,getEnergy())); } } } /** *Método que coloca el cañón apuntando a la posición en la que está el enemigo. */ public void linearFire() { setTurnGunRight(normalRelativeAngle(getHeading()-getGunHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),getHeading()))); } /** *Método que coloca el cañón apuntando a la posición en la que se prevee que esté el enemigo cuando la bala *impacte con el. *El calculo de la posición prevista se basa en la suposición de que el enemigo va a realizar un movimiento *circular, a una velocidad determinada, y teniendo en cuenta el tiempo que va a tardar la bala en llegar hasta el *punto. *@param power Potencia con la que se va a efectuar el disparo. A mas potencia, menos velocidad llevará la bala */ public void circularFire(double power){ double x,y; long time = getTime() + (int)(enemigoInmediato.distance(getX(),getY())/(20-(3*power))) - enemigoInmediato.time; x = enemigoInmediato.x+Math.sin(Math.toRadians(enemigoInmediato.heading))*enemigoInmediato.velocity*time/1.5; y = enemigoInmediato.y+Math.cos(Math.toRadians(enemigoInmediato.heading))*enemigoInmediato.velocity*time/1.5; setTurnGunRight(normalRelativeAngle(getHeading()-getGunHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),x,y,getHeading()))); } /** *Método que capta el evento que se produce cuando nuestro robot choca con otro robot *Identificamos al robot que ha chocado con nosotros y si no es al que tenemos como objetivo ahora, *y además ya hemos fallado más de 2 balas al disparar a nuestro objetivo, le cojemos como objetivo *@param e Evento que se produce cuando se choca con otro robot */

Elena Alaña Salazar Página 15 de 24 Eduardo Fernández Matamala

Page 16: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

public void onHitRobot(HitRobotEvent e){ //Identificamos al robot con el que hemos chocado if(enemigoInmediato.name!= null && !(e.getName()).equals(enemigoInmediato.name)){ //No es el que tenemos como objetivo //Si hemos fallado mas de dos balas, le cogemos como objetivo if(failedBullets > 2){ enemigoAnterior = ""; enemigoInmediato.energy = e.getEnergy(); enemigoInmediato.name = e.getName(); enemigoInmediato.time = getTime(); failedBullets = 0; //1a distancia es la mitad de la anchura del tanque enemigoInmediato.angleToPoints(getX(),getY(),getHeading(),e.getBearing(),getWidth()*2); setTurnRadarRight(normalRelativeAngle(getHeading()-getRadarHeading()+enemigoInmediato.pointsToBearing(getX(),getY(),getHeading()))); scan();//escaneamos para coger información } } } /** *Método que captura el evento que se produce cuando una bala nos golpea *Guardamos el nombre del robot que nos ha golpeado y el numero de veces seguidas que ese robot nos *ha golpeado. Si nos ha golpeado 3 veces con una potencia mayor que la nos *esta golpenado nuestro objetivo actual, le cogeremos como enemigo * *@param e Evento que se produce cuando una bala nos golpea */ public void onHitByBullet(HitByBulletEvent e) { /*Comprobamos quien nos ha dado*/ if( !(e.getName().equals(enemigoInmediato.name))){ /*Nos ha dado un robot que no es nuestro objetivo inmediato*/ if(e.getPower() > enemyBulletPower){ /* Si la potencia de su bala es mayor que la de nuestro objetivo inemdiato, *contamos el golpe*/ if(e.getName().equals(otherEnemy)){ numberHits++; } else{ otherEnemy=e.getName(); numberHits=1; change = false; } /*Si ya nos ha dado 3 o más veces con más potencia, le cogemos como enemigo*/ if(numberHits>=2){ numberHits=0; change = true; enemigoInmediato.name = null; hitTime = getTime(); } } } /*Si nos ha golpeado nuestro enemigo, actualizamos la potencia de su disparo*/ else{ enemyBulletPower = e.getPower(); }

Elena Alaña Salazar Página 16 de 24 Eduardo Fernández Matamala

Page 17: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

} /** *Método que captura el evento que se produce cuando se escanea un robot *Si tenemos objetivo, y no hemos fallado mas de 'limitBullets' *balas hacia el, actualizamos la información sobre él. Si no, *cogemos el primer robot que vemos *@param e Evento que se produce cuando se escanea un robot */ public void onScannedRobot(ScannedRobotEvent e){ //Si no tenemos enemigo, cojemos el nombre del primero que vemos if(enemigoInmediato.name == null){ enemigoInmediato.name = e.getName(); } /*Si ya hemos fallado 'limitBullets' hacia el anterior objetivo y *le volvemos a escanear, no le cogemos como objetivo*/ if((enemigoInmediato.name).equals(enemigoAnterior)){ enemigoInmediato.name = null; return; } /*Si volvemos a escanear al que tenemos como objetivo*/ if((enemigoInmediato.name).equals(e.getName())){ /*Si no hemos fallado el limite de balas actualizamos la información*/ if(failedBullets <= limitBullets){ enemigoAnterior = ""; enemigoInmediato.energy = e.getEnergy(); enemigoInmediato.velocity = e.getVelocity(); enemigoInmediato.time = getTime(); enemigoInmediato.heading = e.getHeading(); enemigoInmediato.angleToPoints(getX(),getY(),getHeading(),e.getBearing(),e.getDistance()); /*Si hemos terminado hacer el movimiento, cambiamos el sentido y nos movemos una cierta distancia*/ if(getDistanceRemaining() == 0){ dir = -dir; setAhead(dir*Math.abs(amplitude*(Math.sin(getTime()/a)*Math.cos(getTime()/b)))); } /*Si estamos cerca de la pared, giramos en el sentido correcto para alejarnos de ella*/ if(inWall(getX(),getY()) != -1){ turnAndMove(inWall(getX(),getY())+Math.random()*23,40); } /*Si no, nos movemos con un movimiento de tal foram que nos quedemos siempre a *'distance' unidades de distancia del objetivo*/ else{ setTurnRight(normalRelativeAngle(enemigoInmediato.pointsToBearing(getX(),getY(),getHeading())+90-turnAngle*dir*(enemigoInmediato.distance(getX(),getY())>distance ? 1 : -1))); } } /*Si hemos fallado 'limitBullets' cambiamos de objetivo*/ else{ enemigoAnterior = enemigoInmediato.name; enemigoInmediato.name = null; failedBullets = 0; } } else{ /*Si hemos escaneado otro robot que no es el que tenemos como objetivo y la información

Elena Alaña Salazar Página 17 de 24 Eduardo Fernández Matamala

Page 18: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

*que tenemos del objetivo está desactualizada o ya hemos fallado el limite de balas, *cogemos a este robot como objetivo*/ if(getTime()-enemigoInmediato.time > actTime || failedBullets > limitBullets ){ enemigoInmediato.name = e.getName(); enemigoInmediato.energy = e.getEnergy(); enemigoInmediato.velocity = e.getVelocity(); enemigoInmediato.time = getTime(); enemigoInmediato.heading = e.getHeading(); enemigoInmediato.angleToPoints(getX(),getY(),getHeading(),e.getBearing(),e.getDistance()); enemigoAnterior = ""; failedBullets = 0; } } } /** * Método publico que se ejecuta cuando nuestro robot gana la batalla, y lo celebra realizando una serie de giros *@param e Evento que se produce al ganar nuestro robot la batalla */ public void onWin(WinEvent e){ //Giramos a la derecha la pistola 2000º setTurnGunRight(2000); //Giramos a la izquierda el radar 2000º setTurnRadarLeft(2000); //Giramos el cuerpo a la izquierda 2000º setTurnLeft(2000); } /** *Método publico que se ejecuta cuando una bala lanzada por nuestro robot se pierde. Almacena el numero de *balas perdidas y en el caso de que solamente quede un robot mas cambia el tipo de disparo utilizado de lineal a *circular * *@param e Evento que se produce cuando una de las balas lanzadas por nuestro robot se pierde * (golpea contra una pared) */ public void onBulletMissed(BulletMissedEvent e) { //Actualizamos la variable de balas perdidas failedBullets++; //Si solo queda un robot cambiamos el tipo de disparo if(numberRobots == 1){ if(failedBullets==4){ failedBullets=0; linearFire=!linearFire; } } } /** *Método publico que se ejecuta cuando una bala lanzada por nuestro robot impacta en otro. Actualiza el valor de *las balas perdidas permitiendo 3 fallos por cada acierto contra el enemigo inmediato que tenemos *@param e Evento que se produce cuando una de las balas lanzadas por nuestro robot impacta en otro robot */ public void onBulletHit(BulletHitEvent e) { //Impactamos en el robot que tenemos almacenado como el enemigo inmediato if((e.getName()).equals(enemigoInmediato.name)){

Elena Alaña Salazar Página 18 de 24 Eduardo Fernández Matamala

Page 19: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

if(failedBullets>=3){ //Por cada una que acierto, permito 3 fallos failedBullets=failedBullets-3; } else{ failedBullets = 0; } } } /** *Método publico que detecta cuando un robot ha muerto. En el caso que lo tengamos registrado como el enemigo *inmediato al que tenemos que matar, lo borramos *@param e Evento que se produce cuando un robot muere */ public void onRobotDeath(RobotDeathEvent e){ if(enemigoInmediato.name!= null && enemigoInmediato.name == e.getName()){ enemigoInmediato.name = null; failedBullets = 0; enemigoAnterior =""; } numberRobots--; if (numberRobots == 1){ failedBullets = 0; enemigoAnterior = ""; amplitude = 300; } } /** *Método publico que indicándole las coordenadas del punto al que debe moverse el robot, realiza el movimiento *de manera que el giro que tiene que hacer hasta colocarse en esa dirección sea el mas corto y después *dependiendo de la posición del tanque avanzamos o retrocedemos *@param absAngle Indica el ángulo con respecto a la vertical del ángulo al que tengo que moverme *@param distance Distancia a la que se encuentra el punto de la posición actual del tanque */ public void turnAndMove(double absAngle, double distance){ //Obtengo el ángulo que existe entre el heading de mi tanque y la dirección a la que tengo que moverme double relativeAngle=normalRelativeAngle(absAngle-getHeading()); //En el caso de que ese ángulo este en el margen [-90º 90º] giro, y como el tanque se encuentra con el heading //correcto avanzamos la distancia indicada if(relativeAngle<90&&relativeAngle>-90){ setTurnRight(relativeAngle); setAhead(distance); } else{ //En el caso de que el ángulo sea mayor a |90º| giramos el complementario y nuestro tanque se encuentra en //sentido opuesto a la dirección a la que queremos llegar, así que avanzamos hacia atrás la distancia indicada setTurnRight(normalRelativeAngle(relativeAngle+180)); setBack(distance); } } /** *Método publico que dado un ángulo devuelve el ángulo normalizado entre [-180º 180º] * *@param angle Angulo que hay que normalizar *@return Angulo normalizado

Elena Alaña Salazar Página 19 de 24 Eduardo Fernández Matamala

Page 20: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

*/ public double normalRelativeAngle(double angle) { //En este caso el ángulo ya esta normalizado if (angle > -180 && angle <= 180) return angle; double fixedAngle = angle; //Si el ángulo es menor de -180º le vamos sumando 360º hasta obtener un ángulo que entre dentro del margen //normalizado while (fixedAngle <= -180) fixedAngle += 360; //Si el ángulo es mayor de -180º le vamos restando 360º hasta obtener un ángulo que entre dentro del margen //normal while (fixedAngle > 180) fixedAngle -= 360; return fixedAngle; } /** *Método publico que dada no permite acercarse al robot a las paredes del campo de batalla. *Dadas las coordenadas de la posición del robot comprueba si se encuentra próximo a una de las paredes y en *caso de estarlo le devuelve el ángulo absoluto al cual debe girar * *@param x Coordenada x de la posición del robot *@param y Coordenada y de la posición del robot *@return Dirección a la cual debe girar (Es la dirección perpendicular a la pared a la cual se encuentra próximo) */ public double inWall(double x,double y) { //Comprueba si se encuentra próximo a la pared izquierda if(x<limit2) return 90; //Comprueba si se encuentra próximo a la pared derecha else if(x>(width-limit2)) return 270; //Comprueba si se encuentra próximo a la pared inferior else if (y<limit2) return 0; //Comprueba si se encuentra próximo a la pared superior else if(y>(height-limit2)) return 180; //No se encuentra próximo a ninguna pared return -1; } }

Elena Alaña Salazar Página 20 de 24 Eduardo Fernández Matamala

Page 21: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

CÓDIGO DE ENEMIGO.JAVA

package Aplasteitor; /* JavaFile * * Fichero: Enemigo.java * * Descripción: Clase que almacena toda la información sobre el tanque que tenemos en un instante * como objetivo * *@author Elena Alaña Salazar & Eduardo Fernández Matamala *@version 1.0 */ public class Enemigo { /************************/ /* VARIABLES */ /************************/ //Nombre del robot enemigo public String name = null; //Velocidad que lleva el enemigo inmediato public double velocity; //Energía que le queda al tanque enemigo public double energy; //Dirección que lleva el tanque enemigo [0º 360º] public double heading; //Coordenada x de la posición del tanque enemigo public double x; //Coordenada y de la posición del tanque enemigo public double y; //Variable que almacena el tiempo en que detectamos por ultima vez al tanque enemigo public long time = -100000; /*Método constructor de la clase enemigo*/ public Enemigo(){ } /* *Método constructor de la clase enemigo que además almacena el nombre del tanque objetivo *@param name Nombre del tanque enemigo */ public Enemigo(String name){ this.name = name; } /* *Método publico que obtiene la distancia a la que esta el enemigo de nosotros partiendo de *nuestra posición *@param sourceX Coordenada x de la posición de nuestro tanque *@param sourceY Coordenada y de la posición de nuestro tanque *@return Distancia de nuestro tanque al tanque enemigo */

Elena Alaña Salazar Página 21 de 24 Eduardo Fernández Matamala

Page 22: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

public double distance(double sourceX,double sourceY){ return Math.sqrt((sourceX-x)*(sourceX-x)+(sourceY-y)*(sourceY-y)); } /* *Método publico que dada las coordenadas de un punto calcula la distancia a ese punto *@param sourceX Coordenada x de la posición de nuestro tanque *@param sourceY Coordenada y de la posición de nuestro tanque *@param targetX Coordenada x de la posición del punto al cual vamos a calcular la distancia *@param targetY Coordenada y de la posición del punto al cual vamos a calcular la distancia *@return Distancia de nuestro tanque a un punto del campo de batalla */ public double distance(double sourceX,double sourceY,double targetX,double targetY){ return Math.sqrt((sourceX-targetX)*(sourceX-targetX)+(sourceY-targetY)*(sourceY-targetY)); } /* *Método que calcula el bearing entre nuestro tanque y el tanque que tenemos como objetivo inmediato *@param sourceX Coordenada x de la posición de nuestro tanque *@param sourceY Coordenada y de la posición de nuestro tanque *@param heading Angulo de heading de nuestro tanque *@return Angulo de bearing entre nuestro tanque y el tanque enemigo */ public double pointsToBearing(double sourceX,double sourceY,double heading){ //Calculamos el inclinación de la recta que une a los dos tanques double angle = Math.toDegrees(Math.atan((x-sourceX)/(y-sourceY))); angle+=y<sourceY ? 180 : 0; //En el caso de que de un ángulo negativo lo pasamos al equivalente positivo en el intervalo [0º 360º] angle+=angle<0 ? 360 : 0; //Obtenemos el ángulo que existe entre nuestro heading y la dirección en la que hemos detectado //con el radar al tanque enemigo angle = angle-heading; //Lo transformamos en el ángulo equivalente en el intervalo [-180 180] if(angle>180) return (angle-360); if(angle<-180) return (angle+360); //Devolvemos el bearing respecto al enemigo return angle; } /* * Método que calcula el bearing entre nuestro tanque y un determinado punto *@param sourceX Coordenada x de la posición de nuestro tanque *@param sourceY Coordenada y de la posición de nuestro tanque *@param targetX Coordenada x de una determinada posición *@param targetY Coordenada y de una determinada posición *@param heading Heading de nuestro tanque *@return Bearing entre nuestro tanque y una determinada posición */ public double pointsToBearing(double sourceX,double sourceY,double targetX,double targetY,double heading){ //Calculamos el inclinación de la recta que une a nuestro tanque con el punto double angle = Math.toDegrees(Math.atan((targetX-sourceX)/(targetY-sourceY))); angle+=targetY<sourceY ? 180 : 0; //Pasamos el ángulo al equivalente en el intervalo [0º 360º] angle+=angle<0 ? 360 : 0;

Elena Alaña Salazar Página 22 de 24 Eduardo Fernández Matamala

Page 23: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

//Obtenemos el ángulo que existe entre nuestro heading y la dirección en la que se encuentra el otro // punto con respecto a nosotros angle = angle-heading; //Lo transformamos en el ángulo equivalente en el intervalo [-180º 180º] if(angle>180) return (angle-360); if(angle<-180) return (angle+360); //este es el bearing respecto al enemigo return angle; } /* *Método que dado el bearing y la distancia entre nuestro tanque y el enemigo y todos los datos sobre la *posición de nuestro tanque calcula la posición en la que se encuentra el tanque enemigo *@param sourceX Coordenada x de la posición de nuestro tanque *@param sourceY Coordenada y de la posición de nuestro tanque *@param sourceHeading Heading de nuestro tanque *@param angleBearing Bearing entre nuestro tanque y el tanque enemigo *@param dist Distancia que separa a ambos tanques */ public void angleToPoints(double sourceX,double sourceY,double sourceHeading,double angleBearing,double dist){ //Cálculo de la coordenada x de la posición del tanque enemigo x=sourceX+dist*Math.sin(Math.toRadians(angleBearing+sourceHeading)); //Cálculo de la coordenada y de la posición del tanque enemigo y=sourceY+dist*Math.cos(Math.toRadians(angleBearing+sourceHeading)); } }

Elena Alaña Salazar Página 23 de 24 Eduardo Fernández Matamala

Page 24: AAuuttoorreess EElleennaa AAllaaññaa SSaallaazzaarr ...jvillena/irc/practicas/04-05/3mem.pdf · que más batallas haya ganado a lo largo de todos los torneos. Todos los robots comienzan

Inteligencia en Redes de Comunicaciones ROBOCODE

BIBLIOGRAFÍA

- API de Robocode http://robocode.alphaworks.ibm.com/docs/robocode/index.html - API de java:

http://java.sun.com/j2se/1.4.2/docs/api/

- Robocode Proyect. http://robocode.alphaworks.ibm.com/home/home.html

Elena Alaña Salazar Página 24 de 24 Eduardo Fernández Matamala