INFO   Main   Docs   FAQ   News   Tutorials   Interviews   Forums   Mailing List
ONLINE    BATTLE ARENA   Accounts   Uploads   Downloads   Hall of Fame
|   No-Limits Challenge: JROBOTS FOREVER! (January 6th 2010)   ||   October-December Challenge: The End! (December 26th 2009)   ||   October-December Challenge: JROBOTS 2K9 Q4! (October 3rd 2009)   ||   September-October Challenge: JROBOTS 2K9 Q3! (July 4th 2009)   ||   April-June Challenge: JROBOTS 2K9 Q2! (March 28th 2009)   ||   Old News  |

MAKE a DONATION

GAME

Main

BATTLE ARENA
Hall of Fame

Downloads

Accounts
Uploads
 
INFO

News

Docs
F.A.Q.
Tutorials
Interviews

Forums
Mailing List
Contact leo
 
Visit the APOCALYX BLOG!

Jrobots Tutorials

[English] [Italiano] [Español]

  1. Técnicas para apuntar
  2. La construcción de Platoon
  3. La construcción de Phalanx y Stinger

Técnicas para apuntar - Autor: Leonardo Boselli

Las limitaciones de los robots más simples son claras: usan el radar para localizar el enemigo y disparan un misil a dicha ubicación. Generalmente fallan en su intento de impactar el objetivo porque el enemigo se ha movido mientras el misil viaja hasta el punto donde debe explotar.

Para obtener mejores resultados, un robot debe estimar la velocidad de su enemigo y luego disparar un misil a la posición futura que éste tendrá al momento de explotar. El siguiente algoritmo es usado por Phalanx y Stinger, y puede ser dividido en cuatro partes:

  1. Estimación de velocidad
    Para calcular la velocidad del enemigo, un robot debe usar el radar para identificar la ubicación del enemigo en diferentes momentos. Recuerde que las principales funciones (como el scan()) retornan valores enteros, lo que obliga a realizar rastreos cada cierto tiempo de tal manera de mejorar la precisión. Esta es la parte difícil del algoritmo y la dejaré al lector como ejercicio :)

     

  2. Cálculo del tiempo de vuelo
    Cuando ya tienes la ubicación y la velocidad del enemigo, el entrenamiento del cañón es sencillo.
    Antes que nada, el vuelo del misil es independiente de la velocidad del robot que lo dispara (esto es explicado en Info section). El misil siempre vuela a 300 m/s, por lo que tenemos que estimar el punto donde un misil volando a dicha velocidad interceptará al enemigo en movimiento.

    Puedes encontrar la fórmula exacta para calcular el tiempo de vuelo de esta manera:

    Digamos que P (usando notación vectorial) es el punto desconocido en el que el misil interceptará al enemigo. R es la ubicación del robot que realiza el disparo. T la ubicación inicial del objetivo y V su velocidad.
    El objetivo alcanzará el punto P en t segundos, de acuerdo con la fórmula:

    P = T + V t

    El misil recorrerá 300.t metros para alcanzar el punto P, que es igual a la distancia de P a R

    (P - R)2 = (300 t)2

    Ahora tenemos tres ecuaciones que podemos usar para encontrar el tiempo de vuelo t.
    Después de algunos cálculos algebraicos obtenemos:

    t = ( sqrt(3002 D2 - (DxV)2) + D·V ) / (3002 - V2)

    donde D = T - R, "x" es el producto vectorial de dos vectores y "·" su producto escalar.

    Si no estás familiarizado con la notación vectorial, quizás es más claro:

    Dx = Tx - Rx
    Dy = Ty - Ry
    t = ( sqrt(3002 (Dx2 + Dy2) - (DxVy - DyVx)2) + (DxVx + DyVy) ) / (3002 - (Vx2 + Vy2) )

  3. Cálculo del nuevo objetivo
    Para calcular la ubicación del objetivo luego del tiempo de vuelo del misil, simplemente debes sustituir t en las ecuaciones de movimiento del enemigo por:

    P = T + V t

    esto es:

    Px = Tx + Vx t
    Py = Ty + Vy t

  4. Entrenamiento del disparo
    Finalmente queda una tarea trivial: debes calcular los argumentos de la función cannon() (ángulo y distancia) usando Px, Py y las coordenadas de tu robot.
Eso es todo! Por preguntas o comentarios, envía un email.

Jrobot: Platoon - Autor: Leonardo Boselli

Estos son lo secretos de Platoon, el cual fue mi primer Jrobot. Esta guía puede ser útil para aprender algunos trucos sobre los combates con Jrobots. Este robot es muy simple y funciona mejor en el modo de equipos (Team).

Por más información sobre Jrobots ver la sección de información.
Si deseas escribir un manual sobre tu propio robot, envíalo por email.

Veamos el código fuente:

public class __Platoon_ extends JJRobot {
/*
El nombre de cada robot debe comenzar con 2 underscores y terminar con 1. Solo caracteres alfanuméricos son permitidos en el nombre. Tu clase debe ser una extensión de la clase JJRobot.
*/
private static int count;
/*
La variable contendrá la cantidad de robots amigos involucrados en el combate
*/
private static int[] cornerX = {50,950,950,50};
private static int[] cornerY = {50,50,950,950};
/*
Estos arreglos contienen las coordenadas de las esquinas que usará el robot.
*/
private static int targetX = 500;
private static int targetY = 500;
/*
Coordenadas del último enemigo encontrado
*/
private static int locX[] = new int[8];
private static int locY[] = new int[8];
/*
Ubicaciones de los robots amigos
*/
private static int corner1;
/*
Selección de la primer esquina
*/
private int nCorner;
private int scan;
private int id;

void main() {
  if((id = id()) == 0) {
    count = 1;
    corner1 = rand(4);
  } else {
    count = id+1;
  }
/*
El último bloque if cuenta los robots amigos y inicializa las variables estáticas cuando el primer robot es creado. El método id() retorna un número que identifica cada robot según sus orden de creación.
*/
  nCorner = corner1;
  int dx = cornerX[nCorner]-(locX[id]=loc_x());
  int dy = cornerY[nCorner]-(locY[id]=loc_y());
  int angle;
  if(dx == 0) {
    angle = dy > 0? 90: 270;
  } else {
    angle = atan(dy*100000/dx);
  }
  if(dx < 0) angle += 180;
  drive(angle,100);
/*
Los robots comienzan el camino hacia la esquina seleccionada
*/
  switch(nCorner) {
    default:
    case 0: while(locX[id] > 150 || locY[id] > 150) fire2(); break;
    case 1: while(locX[id] < 850 || locY[id] > 150) fire2(); break;
    case 2: while(locX[id] < 850 || locY[id] < 850) fire2(); break;
    case 3: while(locX[id] > 150 || locY[id] < 850) fire2(); break;
  }
/*
En este bloque switch el robot dispara misiles mientras llega a la esquina
*/
  do {
    drive(0,0);
    while(speed() >= 50) fire1();
/*
El robot dispara mientras espera frenar hasta el 50% de velocidad. Luego...
*/
    if(++nCorner == 4) nCorner = 0;
    dx = cornerX[nCorner]-loc_x();
    dy = cornerY[nCorner]-loc_y();
    if(dx == 0) {
      angle = dy > 0? 90: 270;
    } else {
      angle = atan(dy*100000/dx);
    }
    if(dx < 0) angle += 180;
    drive(angle,100);
/*
... el robot elige la próxima esquina y ...
*/
    switch(nCorner) {
      default:
      case 0: while(locY[id] > 150) fire1(); break;
      case 1: while(locX[id] < 850) fire1(); break;
      case 2: while(locY[id] < 850) fire1(); break;
      case 3: while(locX[id] > 150) fire1(); break;
/*
... dispara misiles esperando llegar a dicha esquina
*/
    }
  } while(true);
}
private void fire1() {
/*
En este método el robot escanea el lado opuesto a la pared
*/
  switch(nCorner) {
    default:
    case 0: if(++scan > 470 || scan < 240) scan = 250; break;
    case 1: if(++scan > 200 || scan < -30) scan = -20; break;
    case 2: if(++scan > 290 || scan <  60) scan = 70; break;
    case 3: if(++scan > 380 || scan < 150) scan = 160; break;
  }
  fire();
}

private void fire2() {
/*
En este método el robot escanea todo a su alrededor
*/
  if(++scan > 360) scan = 0;
  fire();
}

private void fire() {
  locX[id] = loc_x();
  locY[id] = loc_y();
/*
El robot actualiza su posición
*/
  int range;
  if((range = scan(scan,1)) > 40 && range <= 740) {
/*

El radar detecta un robot en una rango de distancia conveniente

*/
    if (count > 1) {
/*
El robot no está solo (tiene amigos)
*/
      boolean shot = true;
      int shotX = locX[id]+range*cos(scan)/100000;
      int shotY = locY[id]+range*sin(scan)/100000;
      for(int ct = 0; ct < count; ct++) {
/*
Es el robot encontrado un enemigo?
*/
        if(ct != id) {
          int dx = shotX-locX[ct];
          int dy = shotY-locY[ct];
          if(dx*dx+dy*dy < 1600) {
            shot = false;
            break;
          }
        }
      }
      if(shot) {
/*
Es un enemigo! Dispara e informa a sus amigos sobre el enemigo encontrado
*/
        targetX = shotX;
        targetY = shotY;
        cannon(scan,range);
        scan -= 10;
/*
Gira el radar un poco hacia atrás
*/
      } else {
/*
Es un amigo! Disparar al último enemigo encontrado en su lugar
*/
        int dx = targetX-locX[id];
        int dy = targetY-locY[id];
        int dist2 = dx*dx+dy*dy;
        if(dist2 > 1600 && dist2 <= 547600) {
          int angle;
          if(dx == 0) {
            angle = dy > 0? 90: 270;
          } else {
            angle = atan(dy*100000/dx);
            if(dx < 0) angle += 180;
          }
          cannon(angle,sqrt(dist2));
        }
      }
    } else {
/*
El robot está solo. Disparar sin preocupación.
*/
      cannon(scan,range);
      scan -= 10;
    }
  }
}

}

Puedes encontrar el código fuente de Platoon en la página de downloads.

Por preguntas o comentarios, envía un email.


Jrobot: Phalanx y  Stinger - Autor: Leonardo Boselli

Platoon funciona bien en el modo por equipos (Team), pero algunos robots con buenas técnicas de detección le ganan fácilmente en los modos Single y Double, porque sus movimientos son fácilmente previsibles. Para mejorar el comportamiento de Platoon, he escrito Phalanx y Stinger.

Los mejores robots usan el seguimiento de la velocidad del enemigo para aumentar el daño causado por sus misiles. Esta técnica es útil cuando el enemigo usa una velocidad constante, y facilita la estimación de la ubicación del enemigo al final del vuelo del misil. Si el robot se mueve hacia atrás y hacia adelante, los enemigos más inteligentes son confundidos, pero los menos inteligentes tiene suerte, ya que sus disparos no predictivos, pueden tener suerte e impactar al robot en los cambios de dirección. Una mejor solución es seguir una ruta en zigzag como lo hace Phalanx.

Stinger usa la misma técnica de disparo de Phalanx, pero tiene algoritmos de movimientos diferentes. Busca el enemigo más cercano y lo sigue como una sombra. Cuando está realmente cerca (menos de 40 metros) dispara misiles a una distancia de 45 metros, de tal manera de dañar al enemigo sin dañarse a si mismo.

Ahora Phalanx combina las 5 principales técnicas de los robots más desarrollados. Las reglas que sigue son:

  1. No disparar a los amigos: aplica a los modos Double y Team
  2. Mantener alta velocidad y cambiar de dirección rápidamente: esto evita misiles disparados al lugar del escaneo
  3. Seguir una ruta en zigzag: esto evita misiles disparados por robots más inteligentes
  4. Correr en grupos para acumular poder de disparo: un excelente valor en el modo Team
  5. Calcular tiempo de vuelo de los misiles y estimar correctamente la posición futura del enemigo: bueno si deseas golpear duro a alguien

Stinger cambia las reglas 3 y 4 por:

  1. Seguir al enemigo más cercano muy de cerca: esto confunde al enemigo
  2. Dispara hacia el enemigo evitando daños propios: bueno si la distancia es menor que 40 metros

Puedes encontrar el código fuente de Phalanx y Stinger en la página de downloads.

Por preguntas o comentarios, envía un email.

For more information
send an email to
TETRACTYS Software
Project Hosted by SourceForge Copyright © 1999-2009 Leonardo Boselli
All Rights Reserved. Legal Terms.