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. Tecniche di puntamento
  2. Jrobot: Platoon
  3. Jrobot: Phalanx and Stinger

Tecniche di puntamento - Autore: Leonardo Boselli

I limiti dei robot forniti come esempio sono evidenti: utilizzano lo scanner per individuare il nemico e sparano un missile verso il punto che hanno trovato. Spesso mancano il bersaglio perché il nemico è in movimento ed il missile impiega un certo tempo per raggiungere la distanza a cui esploderà

Per ottenere risultati migliori, un robot deve stimare la velocità del suo nemico e sparare il missile verso il punto in cui si troverà il bersaglio dopo qualche istante. Qui di seguito viene presentato l'algoritmo utilizzato da Phalanx. Può essere suddiviso in quattro parti:

  1. Stima della velocità
    Per calcolare la velocità del nemico occorre utilizzare lo scanner per individuarne la posizione in istanti differenti. Bisogna ricordare che i metodi di sistema (come scan()) restituiscono valori interi, così è opportuno che passi un tempo sufficiente tra una lettura e l'altra per migliorare la precisione.
    Questa è la parte più critica dell'algoritmo e la lascio al lettore come esercizio :)

  2. Calcolo del tempo di volo
    Dopo aver stabilito la posizione e la velocità del nemico, il puntamento del cannone è praticamente immediato.
    Prima di tutto, bisogna ricordare che il volo del missile è indipendente dal moto del robot che lo spara. Il missile viaggia sempre a 300 m/s, così occorre prevedere il punto in cui un missile che viaggia a tale velocità incontrerà il nemico in movimento.

    E' possibile determinare la formula esatta in questo modo:

    Sia P (in notazioni vettoriali) il punto sconosciuto in cui il missile incontrerà il nemico, R la posizione iniziale del nostro robot, T la posizione iniziale del bersaglio e V la sua velocità.
    Il punto P sarà raggiunto dal bersaglio in t secondi, secondo la formula

    P = T + V t

    Il punto P sarà raggiunto dal missile nello stesso tempo, dopo aver percorso 300·t metri, che è la distanza tra R e P

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

    Ora abbiamo tre equazioni che possono essere utilizzate per ricavare il tempo di volo t.
    Dopo alcuni calcoli algebrici si ottiene

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

    dove D = T - R, "x" è il prodotto vettoriale e "·" il prodotto scalare di due vettori.

    Chi non ha dimestichezza con la notazione vettoriale, può forse comprendere meglio queste formule

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

  3. Calcolo della nuova posizione
    Per determinare la nuova posizione del bersaglio, è possibile sostituire il tempo precedentemente calcolato nelle equazioni del moto del nemico

    P = T + V t

    cioè

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

  4. Puntamento del cannone
    Infine, non rimane che calcolare gli argomenti del metodo cannon() (angolo e distanza) usando Px, Py e le coordinate del nostro robot.

E' tutto! Per domande o commenti, mandami un email.


Jrobot: Platoon - Autore: Leonardo Boselli

Questo è il codice sorgente del mio primo robot, Platoon. Può essere utile per imparare alcuni trucchi sui combattimenti tra Jrobots. Questo robot è molto semplice ed ottiene i migliori risultati nei combattimenti a squadre.

Per maggiori informazioni su Jrobots vai alla sezione Info.
Se vuoi scrivere un tutorial sul tuo robot, mandami un email.

Vediamo il codice sorgente:

public class __Platoon_ extends JJRobot {
/*
Il nome di ogni Jrobot deve iniziare con due underscore e terminare con uno. Nel mezzo sono ammessi solo caratteri alfanumerici. Deve estendere la classe JJRobot
*/
private static int count;
/*
Questa variabile conta i robot amici presenti nell'arena
*/
private static int[] cornerX = {50,950,950,50};
private static int[] cornerY = {50,50,950,950};
/*
Questi array contengono i valori del percorso seguito dal robot
*/
private static int targetX = 500;
private static int targetY = 500;
/*
Coordinate dell'ultimo bersaglio individuato
*/
private static int locX[] = new int[8];
private static int locY[] = new int[8];
/*
Posizione dei robot amici
*/
private static int corner1;
/*
Primo angolo scelto
*/
private int nCorner;
private int scan;
private int id;

void main() {
  if((id = id()) == 0) {
    count = 1;
    corner1 = rand(4);
  } else {
    count = id+1;
  }
/*
Nell'ultimo blocco if vengono contati i robot amici e vengono resettate le variabili statiche nel caso si tratti del primo robot creato. Il metodo id() restituisce un numero intero che identifica l'ordine in cui i robot vengono creati
*/
  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);
/*
Il robot comincia ad avvicinarsi all'angolo scelto
*/
  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;
  }
/*
In questo blocco switch il robot spara missili ed aspetta di raggiungere il primo angolo
*/
  do {
    drive(0,0);
    while(speed() >= 50) fire1();
/*
Il robot aspetta che la velocità scenda al 50% e spara a ripetizione. Poi...
*/
    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);
/*
... sceglie il prossimo angolo e...
*/
    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;
/*
... spara missili aspettando di raggiungere l'angolo successivo
*/
    }
  } while(true);
}
private void fire1() {
/*
In questo metodo il robot sonda la zona dell'arena opposta al muro
*/
  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() {
/*
In questo metodo il robot sonda l'arena a 360 gradi
*/
  if(++scan > 360) scan = 0;
  fire();
}

private void fire() {
  locX[id] = loc_x();
  locY[id] = loc_y();
/*
Il robot aggiorna la sua posizione
*/
  int range;
  if((range = scan(scan,1)) > 40 && range <= 740) {
/*
Lo scanner ha individuato un bersaglio
*/
    if (count > 1) {
/*
Il robot non è solo
*/
      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++) {
/*
Il bersaglio è un nemico?
*/
        if(ct != id) {
          int dx = shotX-locX[ct];
          int dy = shotY-locY[ct];
          if(dx*dx+dy*dy < 1600) {
            shot = false;
            break;
          }
        }
      }
      if(shot) {
/*
Si, è un nemico! Spara e avvisa i robot amici della posizione del nemico individuato
*/
        targetX = shotX;
        targetY = shotY;
        cannon(scan,range);
        scan -= 10;
/*
Arretra di 10 gradi l'angolazione dello scanner
*/
      } else {
/*
No, è un amico! Spara all'ultimo bersaglio individuato
*/
        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 {
/*
Il robot è solo. Fuoco a volontà
*/
      cannon(scan,range);
      scan -= 10;
    }
  }
}

}

Il codice sorgente di Platoon si può scaricare dalla pagina dei downloads.

Per domande o commenti, mandami un email.


Jrobot: Phalanx and Stinger - Author: Leonardo Boselli

Platoon si comporta bene soprattutto nei Team Match, ma i robot che usano buone tecniche di puntamento possono batterlo facilmente perché i suoi movimenti sono prevedibili. Con lo scopo di scrivere un robot con prestazioni migliori, ho creato Phalanx e Stinger.

I migliori robot calcolano la velocità dei nemici per aumentare i danni causati dai missili. Questa tecnica funziona bene quando i nemici mantengono una velocità costante; in queste condizioni è semplice prevedere la posizione del nemico quando il missile giungerà alla fine della sua corsa. Una possibile contromisura consiste nel far muovere il proprio robot avanti ed indietro; così facendo i robot più precisi sono ingannati, ma quelli meno intelligenti potrebbero essere abbastanza fortunati da colpire il robot quando cambia direzione. Una soluzione migliore è sicuramente quella di seguire un percorso a zig-zag come quello di Phalanx.

Stinger usa la stessa tecnica di tiro di Phalanx, ma segue un differente algoritmo di movimento. Cerca il nemico più vicino e lo segue come un'ombra. Quando è molto vicino (meno di 40 metri), spara ripetutamente verso la sua preda ad una distanza di 45 metri, colpendo così il suo bersaglio senza provocare alcun danno a se stesso.

Attualmente Phalanx combina le cinque tecniche principali utilizzate dai robot più forti. Le regole che segue sono:

  1. Non sparare agli amici: ottimo per gli incontri Double e Team
  2. Mantieni un'alta velocità e cambia direzione rapidamente: questo permette di evitare i missili sparati senza calcoli
  3. Segui un percorso a zig-zag: questo riduce i danni dei missili dei robot più intelligenti
  4. Corri in branchi per unire la potenza di fuoco: ottimo per gli incontri di tipo Team
  5. Calcola il tempo di volo dei missili per correggere la mira e seguire i nemici: per colpire veramente duro

Stinger sostituisce le regole 3 e 4 con:

  1. Segui il nemico più vicino: questo confonde gli avversari
  2. Spara sul nemico evitando di auto-danneggiarti: ottimo se la distanza è inferiore ai 40 metri

Il codice sorgente di Phalanx e Stinger si può scaricare dalla pagina dei downloads.

Per domande o commenti, mandami 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.