INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void...

18
INTELIGENCIA EN REDES DE COMUNICACIONES 5º Ingeniería de Telecomunicación TRABAJO FIN DE ASIGNATURA Realizado por: Juan Manuel Carrero Leal Alberto Heredia García Carlos Lapuente Iribas

Transcript of INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void...

Page 1: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

INTELIGENCIA EN REDES DE COMUNICACIONES

5º Ingeniería de Telecomunicación

TRABAJO FIN DE ASIGNATURA

Realizado por: Juan Manuel Carrero Leal

Alberto Heredia García Carlos Lapuente Iribas

Page 2: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

1

ÍNDICE

Página 1. Introducción a Robocode 2

1.1. ¿Qué es Robocode? 2 1.2. Descripción de un robot de Robocode 2 1.3. Comandos del robot 2 1.4. Ejemplo de robot básico 4 1.5. Robots avanzados 4

2. Nuestros robots 5 2.1. WallsRobot 5 2.2. TrackerRobot 5

3. Nuestros equipos de robots 5 3.1. WallsTeam 5 3.2. TrackerTeam 5

4. Apéndices 6 4.1. Código del robot WallsRobot 6 4.2. Código del robot TrackerRobot 8 4.3. Código del equipo WallsTeam 10 4.4. Código del equipo TrackerTeam 12

5. Referencias 17

Page 3: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

2

1. Introducción a Robocode1.1. ¿Qué es Robocode?

Robocode es un simulador de combate donde tanques programados en Java luchan en un escenario preparado para ello, siendo el vencedor aquel que quede vivo. Dicho proyecto fue creado por Mathew Nelson, ingeniero en IBM, en un intento de convencer a la comunidad de que Java está preparado para ser utilizado en juegos y además, ser una metodología adictiva de aprendizaje del lenguaje. La arquitectura de la máquina de simulación queda representada por la siguiente imagen:

1.2. Descripción de un robot de Robocode

Como todo agente software, los robots podrán detectar el estado del entorno a través de sensores (radar colocado en su cima) y dispondrá de un repertorio de acciones prediseñadas (descritas más adelante) para actuar autónomamente dentro de dicho entorno desplazándose o usando su cañón rotatorio. La siguiente figura ilustra el robot:

1.3. Comandos del robot

Movimiento del robot • turnRight(double degree) y turnLeft(double degree): giran el robot el número de grados

especificado. • ahead(double distance) y back(double distance): mueven el robot el número de píxeles

especificado. Al chocar con otro robot o con la pared, la acción finaliza. • turnGunRight(double degree) y turnGunLeft(double degree): giran el cañón,

independientemente del movimiento del vehículo. • turnRadarRight(double degree) y turnRadarLeft(double degree): giran el radar,

independientemente del movimiento del vehículo y del cañón.

Page 4: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

3

Ninguna de estas acciones devolverá el control al programa hasta que terminen de ejecutarse. Además, cuando giramos el vehículo, también giramos la dirección del cañón y del radar. Este comportamiento se puede modificar con: • setAdjustGunForRobotTurn(boolean flag): activa/desactiva que el cañón se mantenga

en la misma dirección mientras el vehículo gira. • setAdjustRadarForRobotTurn(boolean flag): activa/desactiva que el radar se mantenga

en la misma dirección mientras el vehículo gira. • setAdjustRadarForGunTurn(boolean flag): activa/desactiva que el radar se mantenga

en la misma dirección mientras el cañón gira.

Obtención de información sobre el robot • getX() y getY(): nos dan las coordenadas del robot. • getHeading(), getGunHeading(), y getRadarHeading(): nos dan los ángulos en grados

hacia donde apuntan el tanque, el cañón y el radar, respectivamente. • getBattleFieldWidth() y getBattleFieldHeight(): dan las dimensiones del terreno.

Disparando Cada robot comienza con un nivel de energía predeterminado y será destruido en el

momento que se quede sin energía. Cuando un robot dispara, puede usar hasta tres unidades de su energía. Cuanta más energía tenga el disparo, más daño provocará al robot que alcance. Los métodos fire(double power) y fireBullet(double power) disparan un misil con la energía indicada. El segundo método devuelve una referencia a un objeto robocode.Bullet, usado en los robots avanzados.

Eventos Durante el transcurso de la batalla se irán produciendo eventos, tales como la

detección de un robot en el radar, chocar con una pared o con otro robot, etc. En función del evento que se produzca, nuestro robot podrá ejecutar un método que previamente habremos implementado. Los eventos más destacables son: • void onScannedRobot(ScannedRobotEvent event): se llama a este método cuando el

radar detecta un robot en su rango. • void onHitByBullet(HitByBulletEvent event): se llama a este método cuando nuestro

robot es alcanzado por un misil. • void onHitRobot(HitRobotEvent event): se llama a este método cuando chocamos con

otro robot.

Page 5: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

4

• void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Cada uno de los objetos que reciben como parámetro estos métodos contiene a su

vez una serie de métodos que nos permitirán hallar el ángulo con respecto al robot que acabamos de detectar, quién disparó el misil que nos acaba de dar, dónde está el muro con el que hemos chocado, etc.

1.4. Ejemplo de robot básico

package nombrePaquete; import robocode.Robot; import robocode.ScannedRobotEvent; public class MiPrimerRobot extends Robot {

public void run() { while (true) {

ahead(100); turnGunRight(360); back(100); turnGunRight(360);

}}

public void onScannedRobot(ScannedRobotEvent e) { fire(1);

}}

Como podemos ver en el código, el robot se encuentra en un bucle infinito donde se desplaza 100 píxeles hacia delante, gira el cañón 360º intentando localizar algún robot enemigo, y vuelve hacia atrás 100 píxeles, volviendo a girar 360º el cañón, así hasta que sea vencedor o bien se quede sin energía. En el caso que el radar detecte un robot, se activará la ejecución del método onScannedRobot, el cual lo único que hará será disparar un misil en la dirección que tiene el cañón en ese momento.

1.5. Robots avanzados

El mayor problema de la clase Robot es que todas las acciones no devuelven el control al código hasta que finalizan. La clase robocode.AdvancedRobot fue desarrollada para resolver este problema de manera que los métodos que en ella se implementan realizan acciones asíncronas. De esta forma, todas las llamadas que realicemos se irán encolando y solamente se ejecutarán cuando devolvamos el control a Robocode con un execute() o utilizando cualquier método bloqueante de la clase Robot.

Aparte de la clase AdvancedRobot, para el diseño específico de equipos de robots también disponemos de una clase robocode.TeamRobot que hereda de la anterior. Esta clase añade métodos específicos para comunicación entre robots del mismo equipo.

Page 6: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

5

2. Nuestros robots2.1. WallsRobot

WallsRobot es un tipo de robot básico (extiende de Robot) que, partiendo de una posición cualquiera, se moverá al muro que se encuentre a su izquierda. Una vez allí, comenzará su rutina en la que se moverá por el borde del terreno (pegado a la pared) y se irá parando de vez en cuando para hacer un barrido del terreno. En caso de detectar algún robot disparará una cantidad de energía en función de la vida de nuestro robot, de la distancia al objetivo y de si este se mueve o no. Otro evento tenido en cuenta es el producido al chocar con un enemigo; ese momento será ideal para apuntarle y disparar con la máxima energía. Por último, este robot incluye varios modos de combate de forma que, si está bajo de vida, el robot huirá por el borde intentando que los enemigos se queden sin vida y poder tener así una oportunidad (el enfrentamiento directo sería derrota casi segura).

2.2. TrackerRobot

TrackerRobot es un tipo de robot avanzado (extiende de AdvancedRobot) que realiza un barrido nada más comenzar y busca un objetivo. Si dicho objetivo se encuentra alejado de su posición actual, el robot se acercará hacia él; una vez cerca, se realiza un cálculo aproximado de hacia dónde hay que disparar para alcanzar al objetivo (ya que este se encontrará posiblemente en movimiento). En el caso de chocar con otro robot, lo tomaremos como nuestro objetivo ya que será el más cercano. Por otro lado, si recibimos un impacto de misil, comprobamos si provenía de nuestro objetivo y si la energía de dicho misil era grande. En este caso, suponiendo que haya más rivales vivos, consideraremos que nuestro objetivo es peligroso para nosotros y tomaremos otro diferente como objetivo.

3. Nuestros equipos de robots3.1. WallsTeam

Este equipo está formado simplemente por 3 robots WallsRobot, por lo que será un equipo de robots básicos que actúan independientemente unos de otros. Simplemente se ha modificado ligeramente el código para añadir unas condiciones que eviten que disparemos a nuestros propios compañeros.

3.2. TrackerTeam

Este equipo está formado por robots que extienden de RobotTeam, por lo que podrán comunicarse entre ellos. Un robot TrackerRobot ligeramente modificado hará de líder y su misión será buscar un objetivo para irle siguiendo y disparando. Cuando el líder localice un objetivo, mandará un mensaje a los TeamDroid del equipo que le apoyarán disparando también a dicho objetivo. Cabe destacar que un robot tipo Droid no tiene radar, lo cual le da una bonificación extra en su energía disponible.

Page 7: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

6

4. Apéndices4.1. Código del robot WallsRobot

package robocodePackage; import robocode.*; public class WallsRobot extends Robot {

boolean stopWhenSeeRobot = false; // Don't stop when we're turning

/** run: Move around the walls */ public void run() { setColors(java.awt.Color.red, java.awt.Color.yellow, java.awt.Color.red);

// Move to a wall goWall();

while (true) {if (getGunHeading() < getHeading())

turnGunRight(getHeading() - getGunHeading()); else

turnGunLeft(getGunHeading() - getHeading());

// Scan if we have enough energy if (getEnergy() > 15) { // Move along the wall and scan ahead(100); // Scan turnGunLeft(180); turnGunRight(180); }

// If we don't have enough energy, just run!! else

ahead(Math.max(getBattleFieldWidth(),getBattleFieldHeight())); }

}

/** onHitRobot: Aim at it and set combat mode */ public void onHitRobot(HitRobotEvent e) { double turnGunAmt = normalRelativeAngle(e.getBearing() + getHeading() - getGunHeading()); turnGunRight(turnGunAmt); combatMode(0,0,e.getEnergy()); }

/** onScannedRobot: Set combat mode to destroy it */ public void onScannedRobot(ScannedRobotEvent e) { // Fire if we have enough energy if (getEnergy() > 15 || (getOthers() == 1 && e.getEnergy() < 5)) combatMode(e.getDistance(),e.getVelocity(),e.getEnergy()); }

/** onHitWall: Turn left */ public void onHitWall(HitWallEvent e) { // We're running, but we scan when we get a corner if (getEnergy() <= 15 && getOthers() == 1) { turnGunLeft(180);

Page 8: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

7

turnGunRight(180); }

// Don't stop now stopWhenSeeRobot = false;

// Turn to the next wall turnLeft(90); // We can stop now stopWhenSeeRobot = true;

}

/** goWall: Our way to get to a wall */ public void goWall() { // Turn left to face a wall turnLeft(getHeading() % 90); // Move the maximum distance to move ahead ahead(Math.max(getBattleFieldWidth(),getBattleFieldHeight())); }

/** normalRelativeAngle: Returns angle such that -180 < angle <= 180 */ public double normalRelativeAngle(double angle) { if (angle > -180 && angle <= 180) return angle; while (angle <= -180) angle += 360; while (angle > 180) angle -= 360; return angle; }

/** combatMode: Destroy it !! */ public void combatMode(double robotDistance, double robotVelocity, double robotEnergy) { if (robotVelocity == 0) { fire(3); // Don't stop unless it's safe if (stopWhenSeeRobot && (getOthers() < 4 || getGunHeading() == getHeading())) { stop(); scan(); }

}else if (robotDistance > 200)

fire(1); else if (robotDistance > 50) fire(2); else { fire(3); // Don't start moving util the wall is clear if (stopWhenSeeRobot) { stop(); scan(); }

}

if (stopWhenSeeRobot) resume(); }

/** onWin: Do a victory dance */ public void onWin(WinEvent e) { turnLeft(36000); } }

Page 9: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

8

4.2. Código del robot TrackerRobot

package robocodePackage; import robocode.*; public class TrackerRobot extends AdvancedRobot {

String targetRobot; // Name of the robot we're currently tracking double gunTurnAmt; // Degrees that we have to turn the gun

private static final double BULLET_SPEED = 20 - 3 * 3; private static final double GUN_TURNING_RATE = 40.0 / 180.0 * Math.PI; // Radians per tick

/** run: Search targets */ public void run() { setColors(java.awt.Color.red, java.awt.Color.yellow, java.awt.Color.red); setAdjustGunForRobotTurn(true);

while (true) {setTurnGunLeft(360);

execute(); }

}

/** onScannedRobot: Track it! */ public void onScannedRobot(ScannedRobotEvent e) { // If we have a target, and this isn't it, return if (targetRobot != null && !e.getName().equals(targetRobot)) return;

// If we don't have a target, now we do if (targetRobot == null) targetRobot = e.getName();

// If our target is too far away if (e.getDistance() > 150) { gunTurnAmt = normalRelativeAngle(e.getBearing() + getHeading() - getRadarHeading()); setTurnGunRight(gunTurnAmt); setTurnRight(e.getBearing()); setAhead(e.getDistance() - 140); execute(); return;

}

// Our target is close enough double de = e.getDistance(); // Distance to enemy double be = e.getBearingRadians(); // Angle to enemy double ed = e.getHeadingRadians() - this.getHeadingRadians(); // Enemy's direction double ev = e.getVelocity(); // Enemy speed double ett = amountToTurn(be) / GUN_TURNING_RATE; // Estimated time to turn double hit_time = 20; double actual_time = -1.0; double fire_angle; int count = 0;

// Improved fire do { if (count != 0) hit_time = actual_time;

Page 10: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

9

count ++;

// Enemy location Point enemy = new Point(de * Math.sin(be), de * Math.cos(be));

// Take enemy movement into account enemy.x += hit_time * ev * Math.sin(ed); enemy.y += hit_time * ev * Math.cos(ed);

// Take our movement into account enemy.y -= ett * this.getVelocity();

double fire_time = enemy.distanceFromOrigin() / BULLET_SPEED; fire_angle = Math.atan(enemy.x / enemy.y);

if (enemy.y < 0) fire_angle += Math.PI;

ett = amountToTurn(fire_angle) / GUN_TURNING_RATE; actual_time = fire_time + ett; } while (Math.abs(actual_time - hit_time) > 0.5 && count < 10);

turnGunRightRadians(amountToTurn(fire_angle)); fire(3); }

/** amountToTurn: Radians to turn the gun */ private double amountToTurn(double heading) { double res = heading + getHeadingRadians() - getGunHeadingRadians(); while (res > Math.PI) res -= 2 * Math.PI; while (res < -Math.PI) res += 2 * Math.PI; return res; }

/** normalRelativeAngle: Returns angle such that -180 < angle <= 180 */ public double normalRelativeAngle(double angle) { if (angle > -180 && angle <= 180) return angle; while (angle <= -180) angle += 360; while (angle > 180) angle -= 360; return angle; }

/** onRobotDeath: Check if it was our target */ public void onRobotDeath(RobotDeathEvent e) { if (e.getName().equals(targetRobot)) { // Our target is dead targetRobot = null; // Wait for next tick execute(); }

}

/** onHitRobot: Set him as our new target */ public void onHitRobot(HitRobotEvent e) { // Set the target targetRobot = e.getName(); // Back up a bit

Page 11: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

10

gunTurnAmt = normalRelativeAngle(e.getBearing() + getHeading() - getRadarHeading()); setTurnGunRight(gunTurnAmt); fire(3); setBack(50); execute(); }

/** onHitByBullet: Search less dangerous targets */ public void onHitByBullet(HitByBulletEvent e) { if (e.getName().equals(targetRobot) && e.getPower() > 2 && getOthers() != 1) targetRobot = null; }

/** onWin: Do a victory dance */ public void onWin(WinEvent e) { setTurnLeft(36000); setTurnGunRight(36000); execute(); } }

package robocodePackage; /** Point: Represents a coordinate on the battlefield */ class Point { public double x, y;

public Point(double x, double y) { this.x = x; this.y = y; } public double distanceFromOrigin() { return Math.sqrt((x * x) + (y * y)); } }

4.3. Código del equipo WallsTeam

package robocodePackage; import robocode.*; public class WallsTeamRobot extends Robot {

boolean stopWhenSeeRobot = false; // Don't stop when we're turning

/** run: Move around the walls */ public void run() { setColors(java.awt.Color.red, java.awt.Color.yellow, java.awt.Color.red);

// Move to a wall goWall();

while (true) {if (getGunHeading() < getHeading())

turnGunRight(getHeading() - getGunHeading()); else

turnGunLeft(getGunHeading() - getHeading());

Page 12: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

11

// Scan if we have enough energy if (getEnergy() > 15) { // Move along the wall and scan ahead(100); // Scan turnGunLeft(180); turnGunRight(180); }

// If we don't have enough energy, just run!! else

ahead(Math.max(getBattleFieldWidth(),getBattleFieldHeight())); }

}

/** onHitRobot: Aim at it and set combat mode */ public void onHitRobot(HitRobotEvent e) { if (!e.getName().startsWith("robocodePackage.WallsTeamRobot")) { double turnGunAmt = normalRelativeAngle(e.getBearing() + getHeading() - getGunHeading()); turnGunRight(turnGunAmt); combatMode(0,0,e.getEnergy()); }

}

/** onScannedRobot: Set combat mode to destroy it */ public void onScannedRobot(ScannedRobotEvent e) { // Fire if we have enough energy if (!e.getName().startsWith("robocodePackage.WallsTeamRobot") && (getEnergy() > 15 || (getOthers() == 1 && e.getEnergy() < 5))) combatMode(e.getDistance(),e.getVelocity(),e.getEnergy()); }

/** onHitWall: Turn left */ public void onHitWall(HitWallEvent e) { // We're running, but we scan when we get a corner if (getEnergy() <= 15 && getOthers() == 1) { turnGunLeft(180); turnGunRight(180); }

// Don't stop now stopWhenSeeRobot = false;

// Turn to the next wall turnLeft(90); // We can stop now stopWhenSeeRobot = true;

}

/** goWall: Our way to get to a wall */ public void goWall() { // Turn left to face a wall turnLeft(getHeading() % 90); // Move the maximum distance to move ahead ahead(Math.max(getBattleFieldWidth(),getBattleFieldHeight())); }

/** normalRelativeAngle: Returns angle such that -180 < angle <= 180 */ public double normalRelativeAngle(double angle) { if (angle > -180 && angle <= 180) return angle; double fixedAngle = angle; while (fixedAngle <= -180) fixedAngle += 360;

Page 13: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

12

while (fixedAngle > 180) fixedAngle -= 360; return fixedAngle; }

/** combatMode: Destroy it !! */ public void combatMode(double robotDistance, double robotVelocity, double robotEnergy) { if (robotVelocity == 0) { fire(3); // Don't stop unless it's safe if (stopWhenSeeRobot && (getOthers() < 4 || getGunHeading() == getHeading())) { stop(); scan(); }

}else if (robotDistance > 200)

fire(1); else if (robotDistance > 50) fire(2); else { fire(3); // Don't start moving util the wall is clear if (stopWhenSeeRobot) { stop(); scan(); }

}

if (stopWhenSeeRobot) resume(); }

/** onWin: Do a victory dance */ public void onWin(WinEvent e) { turnLeft(36000); } }

4.4. Código del equipo TrackerTeam

package robocodePackage; import robocode.*; import java.io.*; public class TrackerTeamRobot extends TeamRobot {

String targetRobot; // Name of the robot we're currently tracking double gunTurnAmt; // Degrees that we have to turn the gun

private static final double BULLET_SPEED = 20 - 3 * 3; private static final double GUN_TURNING_RATE = 40.0 / 180.0 * Math.PI; // Radians per tick

/** run: Search targets */ public void run() { setColors(java.awt.Color.red, java.awt.Color.yellow, java.awt.Color.red); setAdjustGunForRobotTurn(true);

while (true) {

Page 14: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

13

setTurnGunLeft(360); execute(); }

}

/** onScannedRobot: Track it! */ public void onScannedRobot(ScannedRobotEvent e) { // Don't fire on teammates if (isTeammate(e.getName())) return;

// If we have a target, and this isn't it, return if (targetRobot != null && !e.getName().equals(targetRobot)) return;

teamFire(e.getBearing(),e.getDistance());

// If we don't have a target, now we do if (targetRobot == null) targetRobot = e.getName();

// If our target is too far away if (e.getDistance() > 150) { gunTurnAmt = normalRelativeAngle(e.getBearing() + getHeading() - getRadarHeading()); setTurnGunRight(gunTurnAmt); setTurnRight(e.getBearing()); setAhead(e.getDistance() - 140); execute(); return;

}

// Our target is close enough double de = e.getDistance(); // Distance to enemy double be = e.getBearingRadians(); // Angle to enemy double ed = e.getHeadingRadians() - this.getHeadingRadians(); // Enemy's direction double ev = e.getVelocity(); // Enemy speed double ett = amountToTurn(be) / GUN_TURNING_RATE; // Estimated time to turn double hit_time = 20; double actual_time = -1.0; double fire_angle; int count = 0;

// Improved fire do { if (count != 0) hit_time = actual_time;

count ++;

// Enemy location Point enemy = new Point(de * Math.sin(be), de * Math.cos(be));

// Take enemy movement into account enemy.x += hit_time * ev * Math.sin(ed); enemy.y += hit_time * ev * Math.cos(ed);

// Take our movement into account enemy.y -= ett * this.getVelocity();

double fire_time = enemy.distanceFromOrigin() / BULLET_SPEED; fire_angle = Math.atan(enemy.x / enemy.y);

Page 15: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

14

if (enemy.y < 0) fire_angle += Math.PI;

ett = amountToTurn(fire_angle) / GUN_TURNING_RATE; actual_time = fire_time + ett; } while (Math.abs(actual_time - hit_time) > 0.5 && count < 10);

turnGunRightRadians(amountToTurn(fire_angle)); fire(3); }

/** amountToTurn: Radians to turn the gun */ private double amountToTurn(double heading) { double res = heading + getHeadingRadians() - getGunHeadingRadians(); while (res > Math.PI) res -= 2 * Math.PI; while (res < -Math.PI) res += 2 * Math.PI; return res; }

/** normalRelativeAngle: Returns angle such that -180 < angle <= 180 */ public double normalRelativeAngle(double angle) { if (angle > -180 && angle <= 180) return angle; while (angle <= -180) angle += 360; while (angle > 180) angle -= 360; return angle; }

/** teamFire: Send enemy position to teammates */ public void teamFire(double eBearing, double eDistance) { // Calculate enemy bearing double enemyBearing = this.getHeading() + eBearing; // Calculate enemy's position double enemyX = getX() + eDistance * Math.sin(Math.toRadians(enemyBearing)); double enemyY = getY() + eDistance * Math.cos(Math.toRadians(enemyBearing)); try { // Send enemy position to teammates broadcastMessage(new TeamPoint(enemyX,enemyY)); } catch (IOException ex) { System.out.println("Unable to send order: " + ex); }

}

/** onRobotDeath: Check if it was our target */ public void onRobotDeath(RobotDeathEvent e) { if (e.getName().equals(targetRobot)) { // Our target is dead targetRobot = null; // Wait for next tick execute(); }

}

/** onHitRobot: Set him as our new target */ public void onHitRobot(HitRobotEvent e) { // Don't fire on teammates if (isTeammate(e.getName())) { back(50);

Page 16: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

15

return;}// Set the target

targetRobot = e.getName(); // Back up a bit gunTurnAmt = normalRelativeAngle(e.getBearing() + getHeading() - getRadarHeading()); setTurnGunRight(gunTurnAmt); fire(3); setBack(50); execute(); }

/** onHitByBullet: Search less dangerous targets */ public void onHitByBullet(HitByBulletEvent e) { if (e.getName().equals(targetRobot) && e.getPower() > 2 && getOthers() != 1) targetRobot = null; }

/** onWin: Do a victory dance */ public void onWin(WinEvent e) { setTurnLeft(36000); setTurnGunRight(36000); execute(); } }

package robocodePackage; import robocode.*; public class TeamDroid extends TeamRobot implements Droid {

boolean leaderAlive = true;

/** run: Droid's default behavior */ public void run() { setColors(java.awt.Color.red, java.awt.Color.yellow, java.awt.Color.red); }

/** onMessageReceived: What to do when our leader sends a message */ public void onMessageReceived(MessageEvent e) { // Fire at a point if (e.getMessage() instanceof TeamPoint) { TeamPoint p = (TeamPoint) e.getMessage(); // Calculate x and y to target double dx = p.getX() - this.getX(); double dy = p.getY() - this.getY(); // Calculate angle to target double theta = Math.toDegrees(Math.atan2(dx,dy)); // Turn gun to target turnGunRight(normalRelativeAngle(theta - getGunHeading())); // Fire hard! fire(0.1); }

}

/** normalRelativeAngle: Returns angle such that -180 < angle <= 180 */ public double normalRelativeAngle(double angle) { if (angle > -180 && angle <= 180) return angle; while (angle <= -180)

Page 17: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

16

angle += 360; while (angle > 180) angle -= 360; return angle; }

/** onRobotDeath: Check if it was our leader */ public void onRobotDeath(RobotDeathEvent e) { if (e.getName().startsWith("robocodePackage.TrackerTeamRobot")) { leaderAlive = false;

}}

/** onHitRobot: Destroy it!! */ public void onHitRobot(HitRobotEvent e) { // Don't fire on teammates if (!isTeammate(e.getName())) { setTurnGunRight(normalRelativeAngle(e.getBearing() + getHeading() - getGunHeading())); fire(3); execute(); }

}

/** onHitByBullet: Fire all around */ public void onHitByBullet(HitByBulletEvent e) { if (!leaderAlive) { setTurnGunRight(36000); setFire(0.1); execute(); }

}

/** onWin: Do a victory dance */ public void onWin(WinEvent e) { setTurnLeft(36000); setTurnGunRight(36000); execute(); } }

package robocodePackage; /** TeamPoint: A serializable point class */ public class TeamPoint implements java.io.Serializable { private double x = 0.0; private double y = 0.0;

public TeamPoint(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } }

Page 18: INTELIGENCIA EN REDES DE COMUNICACIONES · Inteligencia en Redes de Comunicaciones Robocode 4 void onHitWall(HitWallEvent event): se llama a este método cuando chocamos con una pared.

Inteligencia en Redes de Comunicaciones Robocode

17

5. Referencias

�AlphaWorks (web oficial de Robocode): http://robocode.alphaworks.ibm.com/home/home.html

�Rock 'em, sock 'em Robocode! (tutorial): http://www-106.ibm.com/developerworks/java/library/j-robocode/index.html

�Rock 'em, sock 'em Robocode: Round 2 (tutorial): http://www-106.ibm.com/developerworks/library/j-robocode2/

� Secrets from the Robocode masters (trucos y consejos): http://www-106.ibm.com/developerworks/library/j-robotips/index.html

� The Robocode Tutorials (tutorial y ejemplos): http://www.ug.cs.usyd.edu.au/~csled/biwf/robocode/

�Battle bots (robots de competición): http://www.robocoderepository.com/Categories.jsp