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. Useful Tips for Beginners and for all the others too!
  2. The Shortest Effective Jrobot Ever Written
  3. A Pseudocode Template for Cadets
  4. Aiming Techniques
  5. The Making of... Platoon
  6. The Making of... Phalanx and Stinger

Useful Tips for Beginners - Author: Caos

The main purpose of this note is to analyze some characteristics of the game from a tactical point of view, without entering into implementation details.
Most of the advices included are very basic (but needed), and some of them involve more complex concepts that should be developed to get an effective advantage. I hope they could be useful for a wide spectrum of competitors, like they help me to reach the current status of Tango...
Consider they are just some personal opinions of what I've considered good practices when developing my robot.
I'm sure some people could have more effective advices, and different approaches to obtain good results in the game... and of course, I'm interested in them.

G. General

  1. Details matter

    The sum of small differences between bots, makes a big overall difference. Remember results are statistically measured...

    Sometimes I'm surprised of how a very small change in the movement pattern, or a small tuning in the weapon, result in a very different final result. It remembers me (in some sense) to the "butterfly effect" in complex systems...

    How distant are you from leaders? Consider 10 points of difference in a game, could be done just for a pair of good missiles.

  2. Develop your survivor instinct

    Agressivity is good, but it should decrease along the health... or, at least, conservative actions should be taken before the end.

    Some behaviors should calm down when death is near. Perhaps you can get a draw, or a partner could resolve the situation for you!

  3. Use the constants

    Each constant in the game sets limits to the calculations we make inside the robot processes (movements, targeting and shooting):
    Max range of shooting, missile's speed, size of the field, damage of the impact, max speed of the robots, min rational speed, total time, etc.

    It's very effective to filter the final calculated results, by the restrictions imposed by these constants.

    An easy example: the enemy never could go beyond the arena´s limits, nor your shooting estimation should exceed the max distance the target could travel at max speed.

  4. Take advantage of your supremacy

    Advantages could be measure by: damage, alive partners, axis positions, etc. If you are in a considerable advantage, attack!

    There are several ways to estimate the values that determine if you are in advantage, and some of them have been discussed in the group messages (read the Mailing List).

  5. Tie if you are in disadvantage

    Remember that your first option should be to win the game, and the second one... is to draw! Lose is not an option... it's a consequence.

  6. Share information among partners

    Be sure you can access the information of your partners when playing in Double and Team modes. They will help you to develop a cooperative strategy.

    At the initialization phase, you can create static attributes or a static array containing all your robots, to access directly their information (or methods)...

M. Movement

  1. Start quickly

    Weak robots frecuently lose at least 5 point of difference just at the very beginning, due to being quiet too much time. Start moving...

  2. Keep moving, ever!

    To stop completely is worst than being predictable. Speed never should go down the "minimum reasonable speed" of 15m/s.

  3. Avoid the walls

    A pair of points is a big difference when the competition is hard. And worst, your robot will be quiet for a while and it will be an easy target for the enemy. Define your own move() method, which test for potential collisions before calling the native drive().

  4. Flock is good, but avoid to be too near from partners

    Each enemy's missile will produce the double (or worse) of damage if 2 (or more) partners are in the range of the explosion. If two partners are too near, they have almost the same potential value than just one enemy, and therefore they lose the numerical advantage.

  5. 700m strategy is a must

    Every good robot has one... It's important in Single mode and vital in Team mode. If you choose an agressive one, remember don't insist until the death. Take care with corners... or you could be jailed.

  6. Precision decreases with distance

    That could be a good or bad thing depending on the situation and your strategy, ... but it's a fact. So, use it!

    Of course if you develop a good targeting algorithm, try to be far away from your opponent to take advantage of that. In general, there is an optimal distance that balance your shooting precision and the length of your movements.

  7. Going straight is very dangerous

    It's the most easy "pattern" to predict. Never expose an easy target to your enemy!

  8. Return over the track is dangerous too

    Some basic robots shoot to the position collected by the radar. When the missile arrives to the destination, you should be far away from there... but you could be in the wrong place if your bot has decided to return.

  9. Optimal time to turn

    Assuming that the most common estimation method is to fire ahead, the best moment to turn is when the enemy has fired the missile. You can estimate this precise moment assuming it is shooting at the maximum frequency (1 missile per second). So you can use the time of the last impact received by your robot and the distance, to estimate when he is ready to fire again.

  10. Optimal angle to turn?

    Maybe... but one thing it's true, turning 180 (or around 0) degrees, is not the best choice because it simplify the task of your opponent. Most of them estimate your movement as linear, therefore every position over the actual traveling line won't be safe. Some will shoot behind you, and other ahead you, so side turns is a smarter choice.

  11. Consider the distance

    When you are closer to the enemy, precision improves and missiles arrive quicker. So you have less time to run away... don't expose an easy target, change your position quickly.

  12. Protect weak partners

    A very damaged partner produces the SAME damage than a healthy one. A dead robot doesn't produce anything... so move them far away from enemies.

T. Targeting

  1. Save a history of samples

    You will need them to estimate the target's future position, and to act in consecuence. It's obvious when you think about shooting, but sometimes it could be useful to determine your own movements too...

  2. Take care about time consumption

    To make 360 scans too often could take too much time, specially if your robot needs a lot of calculations inside the scanning process. You can remember target's last position and search around it, or use a kind of dichotomic search.

    At the beginning, it originated a delay in Tango that affected its overall performance.

    Moreover, if you have an efficient (time) robot, you can use faster speeds in the Arena to improve the debug process.

  3. Improve the precision

    The native scan gives you a maximum precision of 1 degree. The error it could contain at long distance is important.

    Once found the target, you can play with a pair of consecutive readings with small variations of angles and beam width to double the precision.

  4. Use several samples to approximate the real position

    Don't believe just in one reading. Use a combination of 2 (or more) consecutive readings to get a more approximated position.

    Try to find a sampling frecuency that gives you some meaningful information between samples.

    Sampling too often could slow down your bot, and the variation could be too small to be useful.

  5. Share information among partners

    Precision increases with a pair of different points of view. You can use 2 (or more) partners to combine information to improve the precision.

    Moreover, you can give preponderant value to scans of robots nearer to target.

  6. Signal processing?

    Assume you are sampling a signal wich have "noise", so you should "absorb" it. You can try some known function, or to invent your own...

    Fortunately here things are simpler than the general problem. In the game, the signal is not arbitrary... It's compounded of broken lines, so you could "aling" the samples (just take care of angles)

  7. Iterative targeting

    Remember, your estimation should consider that the target will be moving while the missile is travelling. So you could need an iterative process (or a mathematical model) to estimate the most approximated target position when the missile arrive.

    Iteration is a worth and easy technique... but general experience shows that 2 cycles are enough to obtain a reasonable precision. There are mathematical models to simplify it too. (Read previous explanation about it, in the Mailing List).

  8. Improve your scanning alone

    To test my scanning algorithm, I used to collect, in a simultaneous way, the estimations obtained by my scan algorithm and the real positions of the target.

    After that, I estimated the overall (quadratic) error comparing estimated vs. real in a spreadsheet, so I can evaluate the precision of different targeting methods.

    To collect the real position, you can fight against a robot prepared for testing, that just save its real path... or other way: modifying the scope of the array "jr" in the JJRobots class, and then simply call the enemy methods loc_x() and loc_y() to get the target's real position.

S. Shooting

  1. Care your friends and yourself...

    It's a very obvious advice, but surprisingly it's common to find bots with self destructive behavior... To recognize a friend, compare the estimated position with the real positions (previously saved in a shared array?) of your partners.

  2. Quicker is better

    Don't miss time between shots, every ms can make the vital difference in the last shot of the game if things come tight... so synchronize your weapon.

  3. Sinchronize shared target

    Eat the cake, bite by bite. It's more productive to join fire power against shared targets than to fire in a separate way.

  4. Be persistent

    Insist with your targets. A very damaged enemy produces the SAME damage than a healthy one. So finish your work before change the target.

  5. If you doubt, be conservative

    To "overestimate" the movement of your opponent in general works fine just with "linear" robots. Good robots change of direction frequently, so a less predictive estimation could work better.

  6. Put "hard" limits to estimations

    Your estimations never should break the "physical" rules, so put a filter before call the cannon() function.

    For example, a target never could advance more than 30 m/s so you can limitate your estimation considering the missile flight time. If you have estimated the current target's speed, you could adjust and improve this limit... Consider that in general they never advance less than 15m/s neither, and the estimated position never could be out of arena's limits. Etc.

    If the target is in the explosion (40m) range, what should we do? You can optimize the benefit considering the enemy´s damage and your own self damage.

  7. Pattern prediction works!

    Some robots have a predictable pattern... and in general other too ;-)

    Some of them have a very deterministic pattern (e.g. Dragon, etc.), and other have more complex patterns... but if you are patient you should find some relationship among coordinates (x,y,t). Use these patterns to improve your estimations...

  8. Scenarios

    You can use several techniques (or parameters) to estimate the target future position, and you will note each technique (or parameters) works well with some enemies but not as well with other...

    It's possible to use a kind of "what if" analysis during the game, to decide which technique is better against the current robot.

Unfortunatly, as corresponding to every rule, most of those included here have small exceptions... and I'm sure these exceptions are exploited by good robots. At least Tango does it ;-)
Anyway, I think general rules are a good beginning, and exceptions could be discussed further.
I hope some of you find these advices useful to improve your robots.

    See you in the arena, Caos (the author of Tango, I mean the jrobot not the dance :-> )


The Shortest Effective Jrobot Ever Written - Author: Angsuman

JROBOTS is an extremely addictive Java game where you develop robots in java to fight against other jrobots in a monthly battle royale. I will present you with a simple sample jrobot to encourage you to participate in this contest. It kicks the butt of all sample jrobots provided in the download bundle and even some veterans.

JROBOTS developers are hesitant to provide actual code because of two reasons;

  1. It will lead to proliferation of copy-cat jrobots with a different name which are just a waste of time for all.

  2. Nobody likes to reveal their secrets
I have considered them over the years. I have come to the conclusion that the benefits of providing simple code for developers to begin with far outweighs other concerns. So here is a simple jrobot which despite its simplicity can really kick butt of many jrobots. It was initially released as CounterStrike. However now the CounterStrike code is slightly more sophisticated. So I am releasing this jrobot named Simple.
public class __Simple_ extends JJRobot {
    void main() {
        int distance, angle = 0;
        while (true) {
            while((distance = scan(angle, 1)) == 0) angle++;
            cannon(angle, distance);
            drive(angle, 100);
        }
    }
}
You can see how easy it is to start coding jrobots. What are you waiting for?

    See you in the arena, Angsuman (author of Bizarro, Janeway, Shrike, CounterStrike)


A Pseudocode Template for Cadets - Author: GregM

The following example of pseudocode is an outline of a complex bot. You can read detailed explanations below.

public void main() {       - this function runs your bot
     while(true) {         - this loop executes once per second
          find and record the position of the enemy
          move in a random direction  at 15 m/s
          wait one second
          find and record the position of the enemy again
          use the linear targetting formula to determine how to shoot
          fire at that spot   -make sure a full second has elapsed!
     }
}
So what this bot does is it finds the enemy at intervals of a second, figures out what direction it's moving in and shoots to intercept it. Meanwhile, our bot moves randomly, turning once every second, which makes it hard to hit with the kind of linear targetting we're using here.

You will want to split up these tasks into different functions that are called from main(). Notice that you need to remember a position twice in this example. An easy way to do this is with a JJVector, which combines an x-coordinate, a y-coordinate, and a time into one object that is easy to use.

This bot uses linear targetting, which is devastating against bots that go straight but fails badly against bots that turn frequently. If you know the enemy is moving randomly, you should not use linear targetting, which will often miss completely, but try firing directly at the enemy's current position. Or something in between linear and direct targetting might work best. The best bots look at the enemy's movement and try to figure out which shooting strategy will work best in the current fight."

    See you in the arena, GregM (author of StrangeMatter)


Aiming Techniques - Author: Leonardo Boselli

The limitations of the simpler robots are clear: they use the scanner to locate the enemy and then fire a missile to that location. Often they miss the target because it moves away and the missile takes some time to reach the range where it explodes.

To get better performances, a robot must estimate the speed of its enemy and then it must fire the missile to a location some step forward the target. The following is the algorithm used by Phalanx and Stinger. It can be divided into four parts:

  1. Speed Estimation
    To calculate the speed of the enemy a robot must use the scanner to take the location of the enemy at different instants. Remember that the main system methods (such as scan()) return integers, so you need to scan locations when some time has elapsed to improve precision.
    This is the difficult part of the algorithm and I leave it to the reader as an exercise :)

  2. Flight Time Computation
    When you have the location and speed of the enemy the training of the cannon is straightforward.
    First of all, the flight of the missile is independent from the speed of the shooting robot (this is explained in the Info section). The missile always flies at 300 m/s, so we have to forecast the point where a missile flying at such a speed will meet the moving enemy.

    You can find the exact formula to compute the flight time this way:

    Say P (using vector notation) the unknown point in which the missile meets the enemy, R the starting location of your robot, T the starting location of the target and V its velocity.
    The target will reach the point P in t seconds, according to the formula

    P = T + V t

    The missile will reach the point P in the same time after flying for 300·t meters, that is the distance of R from P

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

    Now we have three equations that we can use to find the flight time t.
    After some algebraic computations we get

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

    where D = T - R, "x" is the cross product of two vectors and "·" their dot product.

    If you are not familiar with vector notation, maybe this is clearer

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

  3. New Target Computation
    To calculate the target location after the flight time, simply substitute t in the equations of motion of the enemy

    P = T + V t

    that is

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

  4. Training the Cannon
    Finally, there is a trivial task: you must compute the arguments of the cannon() method (angle and range) using Px, Py and the coordinates of your robot.
That's all, folks! For questions or comments, send me an email.

Jrobot: Platoon - Author: Leonardo Boselli

This is the "making of..." Platoon, which is my first Jrobot. This tutorial may be useful to learn some tricks about Jrobots fights. This robot is really simple and performs better in team matches.

For more information about Jrobots see the Info section.
If you want to write a tutorial about your own robot, send me an email.

Let's see the source code:

public class __Platoon_ extends JJRobot {
/*
The name of every Jrobot must start with two underscores and end with one. Only alphanumeric characters are allowed in the middle. Your class must extend the JJRobot class
*/
private static int count;
/*
This variable counts the friend robots involved in the fight
*/
private static int[] cornerX = {50,950,950,50};
private static int[] cornerY = {50,50,950,950};
/*
These arrays contain values for the path followed by robots
*/
private static int targetX = 500;
private static int targetY = 500;
/*
Coordinates of the last target found
*/
private static int locX[] = new int[8];
private static int locY[] = new int[8];
/*
Locations of friend robots
*/
private static int corner1;
/*
First corner chosen
*/
private int nCorner;
private int scan;
private int id;

void main() {
  if((id = id()) == 0) {
    count = 1;
    corner1 = rand(4);
  } else {
    count = id+1;
  }
/*
The latter if-block counts the friend robots and reset static variables when the first robot is created. The built-in id() method returns a number that identifies the order of creation of robots.
*/
  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);
/*
The robot starts a route to the chosen corner
*/
  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 this switch-block the robot fires missiles waiting for the first corner
*/
  do {
    drive(0,0);
    while(speed() >= 50) fire1();
/*
The robot waits for a 50% speed fall firing. Then...
*/
    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);
/*
... the robot chooses the next corner and...
*/
    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;
/*
... it fires missiles waiting for the next corner
*/
    }
  } while(true);
}
private void fire1() {
/*
In this method the robot scans the side opposite the wall
*/
  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 this method the robot scans all around
*/
  if(++scan > 360) scan = 0;
  fire();
}

private void fire() {
  locX[id] = loc_x();
  locY[id] = loc_y();
/*
The robot updates its location
*/
  int range;
  if((range = scan(scan,1)) > 40 && range <= 740) {
/*
The scanner finds a target
*/
    if (count > 1) {
/*
The robot is not alone
*/
      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++) {
/*
Is the target an enemy?
*/
        if(ct != id) {
          int dx = shotX-locX[ct];
          int dy = shotY-locY[ct];
          if(dx*dx+dy*dy < 1600) {
            shot = false;
            break;
          }
        }
      }
      if(shot) {
/*
Yes, it is an enemy! Fire and notify friend robots about the enemy found
*/
        targetX = shotX;
        targetY = shotY;
        cannon(scan,range);
        scan -= 10;
/*
Turn back the scanner a bit
*/
      } else {
/*
No, it is a friend! Fire to the last target found instead
*/
        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 {
/*
The robot is alone. Don't worry, fire!
*/
      cannon(scan,range);
      scan -= 10;
    }
  }
}

}

You can find the source code of Platoon in the downloads page.

For questions or comments, send me an email.


Jrobot: Phalanx and Stinger - Author: Leonardo Boselli

Platoon works fine in Team Match, but some robots with strong aiming techniques win against it in Single and Double Match, because its movement if easily foreseeable. To improve the behaviour of Platoon, I've written Phalanx and Stinger.

The best robots use enemy speed tracking to improve damages caused by fired missiles. This technique needs a constant speed to forecast the location of the enemy at the end of the flight of the missile. If the robot moves back and forth, smart enemies are confused, but less smart robots are luck enough to hit it when it changes direction. A better solution is to follow a zigzag path as Phalanx do.

Stinger uses the same shooting technique of Phalanx, but it follows a different movement algorithm. It looks for the nearest enemy and follows it like a shadow. When it's really close (less than 40 meters) it always fires missiles towards the enemy at a distance of 45 meters, so it damages the enemy without damaging itself.

Now Phalanx combines the five main fight techniques of the strongest robots. The rules it follows are:

  1. Don't shoot to friends: good for Double and Team play
  2. Keep high speed and change direction quickly: this avoids missiles fired in place
  3. Follow a zigzag path: this avoids missiles fired by smart robots
  4. Run in flocks to join fire power: a real value in Team play
  5. Compute flight time of missiles and rectify the aim to track enemies: good if you want to hit something very hard

Stinger changes rules 3 and 4 with:

  1. Follow the nearest enemy very close: this confuses the enemy
  2. Fire towards the enemy avoiding self damaging: good if the distance is below 40 meters

You can find the source code of Phalanx and Stinger in the downloads page.

For questions or comments, send me an email.

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