Robocode/FAQ

From Robowiki
< Robocode
Revision as of 23:35, 6 December 2007 by FlemmingLarsen (talk | contribs) (→‎Programming your robot: Added links to Robocode/Robot Console)
Jump to navigation Jump to search

Frequently asked questions about Robocode.

Installing and using

I can't install Robocode.
First make sure you have Java installed on your computer. To check it, run the command: java -version It should execute and show a version 1.5 or higher. If not, go to Sun site and download the last version. After, make sure you have downloaded the correct file (robocode-setup-X.X.X.jar, where X.X.X is the version number). Execute the file by double-clicking on it, or if you want to do it manually, execute the following command: java -jar robocode-setup-X.X.X.jar. It will launch an installer that will install Robocode. The installer creates the icons to execute Robocode, but you can execute it manually by running the robocode.bat or robocode.sh file in the /robocode directory.
I have downloaded a robot from the Web, but I don't know how to use it, because it doesn't appear anywhere.
By default, robots are read from the /robocode/robots directory. You can select "Robot -> Import Downloaded Robot" to copy a robot JAR to this directory from another location. Also, you can configure Robocode to read robots from additional locations using the Properties dialog.
What do I have to do to see the source code of a robot?
You can do two things. The first option is to open the Editor Window in Robocode and use the command in the File menu. The second option is to open the robot ".jar" file with a zip utility and find the source code there (assuming, of course, the robot is open source).
Can I play Robocode online?
Robocode is not an "online" game, so you can't, for example, share a battle with your friends in real time over the Internet. But you can upload your bots into the Robocode Repository and join any of the existing competitions (or organize one with your friends).
I have seen that many bots are packaged into ".jar" files. How do I package my bot?
Select, "Robot --> Package robot for upload" from the menu, then enter your robot's details when prompted.
When I test my bots, Robocode is slow. Is there a way to execute the battles faster?
When you are testing your robot, you want to execute many battles in a short time. Minimize the Robocode main screen to make it execute the battles at full speed.

Game physics

Can I fire bullets with power higher than 3.0 or lower than 1.0?
No and yes. You can't fire bullets with power greater than 3.0, but you can fire bullets with power as low as 0.1. If you call a firing function (i.e. setFire()) with a value greater than 3.0, Robocode will adjust it to 3.0, and if you call it with a power lower than 0.1 it will adjust it to 0.1.
How fast does a bullet travel?
A bullet travels at a speed between 11.0 and 19.7 depending on the power. The more powerful the bullet, the slower. The formula to calculate it is velocity = 20 - (3 * power).
Does the robot velocity get added to the bullet velocity on firing?
No, bullet velocity is not affected by robot velocity. It's kind of like the speed-of-light thing. =)
Which is the range of a bullet?
A bullet has no range. It keeps going until it hits a robot or a wall.
I want to fire a bullet every turn, but I can't. Why?
Every time you fire, the gun generates some heat. You must wait till it is cool again to fire. If you give a fire order when your gun is hot, it will do nothing. The heat generated by a shot is 1 + (firepower / 5). The gun cools down at a default rate of 0.1 per turn (note that you can change this parameter when you run the battle, but nobody usually does). It means you can fire a bullet every 16 ticks.
How much damage does a bullet do?
How do I gain or lose energy?
You lose energy every time you hit a wall, you are hit by an enemy bullet, ram an enemy, or you fire your gun. The amount of energy you lose by being hit is 4 * bullet power + 2 * max(bullet power - 1 , 0). So the maximum amount is 16.0. When you fire, you spend a quantity of energy equal to the power of the bullet fired. When one of your bullets hits an enemy, you collect back 3 * bullet power energy. When you hit an enemy bot, each bot takes 0.6 damage. If an AdvancedRobot (but not a Robot or JuniorRobot) hits a wall, it will take max(abs(velocity) * 0.5 - 1, 0) damage.
Some times I get disabled. What happens?
You can't kill yourself, so when your energy drops to zero because you hit a wall or you fire, your bot gets disabled. It will not be able to move nor fire. If you are lucky enough and one of your bullets in the air hits an enemy, you will get some energy back and recover from disabled status.
I get disabled, but I my energy > 0. Why?
You may have called a getXXX() - for example getVelocity() - function too many times a turn. The limit is 10000 getXXX() function calls per turn. To avoid disabling in such situations, store returned values in variables for future use. Another case in which you can get disabled is throwing an exception. Sometimes this will disable your bot, even if you catch the exception.
How fast do I move?
You can move at a maximum speed of 8.0 units/tick. You can modify (down) your maximum velocity by using setMaxVelocity(...). Note that your bot will always accelerate to reach it's maximum velocity.
How fast do I accelerate?
You accelerate at 1 unit/tick, and you decelerate at 2 units/tick. For example, if you are moving at an speed of 8.0 and reverse your direction your velocities will be [6.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0].
How fast do I turn?
The faster you go, the slower you turn. The formula to calculate it in degrees is 10 - 0.75 * abs(velocity).
What is the size of a bot?
The size of a bot is 36x36. It is modeled as a non rotating square, so it's always the same regardless of its heading.
It seems that Robocode doesn't follow standard physics. If my velocity is 0 and I accelerate (acceleration = 1) my final velocity is 1, but it should be 0.5. What happened?
Time in Robocode, rather than being continuous, is in discrete "ticks". First acceleration is calculated, then velocity, and then position. So if you are stopped at a position 0 and you accelerate 1, your velocity next turn will be 1 and your position also 1.
How can I detect when an enemy has fired?
There is no direct way to detect when an enemy fired, but you can deduce it by monitoring the enemy energy drop. A drop between 0.1 and 3 usually means that it fired a bullet (there can be other reasons, such as a low energy bullet hit or a wall hit). Wall hits are (more or less) detectable as well. A deceleration > 2 means the bot hit a wall (or another bot). A deceleration <= 2 may be simple a bot hitting the brakes, or hitting a wall at velocity = 2, but since hitting a wall at that speed won't cause any damage, you can ignore that. AdvancedRobots take abs(velocity) / 2 - 1 (Never < 0) damage when hitting a wall, so by detecting (significant) wall-hits and adjusting the enemy drop accordingly, wall hits can be filtered out most of the time. This method fails when the enemy hits another robot.
How can I detect the position and heading of an enemy bullet?
You can't. There is no way to know it, directly or indirectly. But of course, you can always guess...
How fast can I turn my gun?
The gun turns at 20 degrees per tick.
How fast can I turn my radar?
It turns 45 degrees per tick.
Can I know the heading of the enemy gun/radar?
No.
Can I specify the initial position of my bot?
No. The bots are randomly placed in the field at the beginning of each round.

Programming your robot

What is the difference between the setXXX() (e.g. setFire()) and the XXX() (e.g. fire()) methods?
Basically, the setXXX() methods just notify Robocode to take some action at the end of the turn. The XXX()-type methods end the turn when you call them, and they block your robot's thread until the command finishes. Unless you have a good reason, you should almost always use the setXXX() version when writing AdvancedRobots.
How can I avoid my gun/radar turning when my bot turns?
You can use setAdjustGunForRobotTurn(), setAdjustRadarForGunTurn(), and setAdjustRadarForRobotTurn() methods to control this. If you call setAdjustGunForRobotTurn() and setAdjustRadarForGunTurn(), you don't need to call setAdjustRadarForRobotTurn().
Why are there two functions for getBearing() for example - one in radians and one in degrees? Is there any performance gain if I use radians instead of degrees?
There is no real advantage to using one or the other. Just use the one you prefer. Usually, people start using degrees (just because they feel more comfortable with them) and later they switch to radians (because calculations are easier since you can use the built-in Java trigonometric functions). Just remember to use always radians or always degrees; mixing them up is not a good idea.
I need to trace my bots actions and variables. I saw that everybody uses out.println("..."), but where is that printed?
It prints to the robot console. When you execute the battle, just click on the button on the right of the screen that shows the name of your robot to open its console.
How do you get your radar to stay focused on a robot that you have defined as your target?
You just turn the radar the other way around when you scan the bot. You lock your radar by not turning it 45 degrees, but only the arc needed to stay focused. See the Radar page for some example code.
How can I know how many enemies are in the battle field?
You can use the getOthers() method to know how many live enemies are in the battlefield.
I'm trying to recognize an enemy/teammate from its name (using e.getName()) but the condition always fails. What's happening?
Because of Java's funky way of interpreting references to Strings (not to mention a lack of operator overloading), you can't use an expression like if (e.getName() == testname) to check for equality. You have to use the String.equals() method, as in if (e.getName().equals(testname)).
How do I keep data from round to round and battle to battle?
The easiest way is to save data between rounds of a battle is to make the variables in the bot class static. Because Robocode uses a separate classloader for every robot, the variables will not conflict even when you have more than one copy of a robot in a battle. Note that this will save data between rounds, not between battles. To save between battles you will have to save to a file. The maximum allowed disk space for files is 200k. Look at the Robocode API for more details.
I get the following message when I run my bot, and I don't know how to solve it.
SYSTEM: You have made 10000 calls to getXX methods without calling execute()
SYSTEM: Robot disabled: Too many calls to getXX methods.
Robocode prevents you from calling functions like getX() or getVelocity() too many times during a single tick. So if you are using them in a long loop, it will raise this error. Actually, 95% of the time, this error is a symptom of an infinite loop in your bot. If you know you have a long-but-finite loop and you get this error, just assign the values you want to use to a variable and then use this variable in your loop instead of the functions.
I'm using bulletObject = setFireBullet(power) to fire, and then I want to get the bullet coordinates. But when I try to print them using System.out.println(bulletObject.getX() + bulletObject.getY()) I get an error. What's wrong?
setFireBullet() creates a Bullet object, but the bullet doesn't actually leave your bots gun until the next tick, so you can't do getX() or getY() on the bullet until then. If you change it to fireBullet() you should be OK, because the function won't return until the bullet is in the air. If fireBullet() won't work for you, you'll have to devise another method of making sure that you don't do getX() and getY() on bullets until the turn after you fire. For example, you could store Bullets in an ArrayList, and print out their coordinates before you fire in your main loop, so that a given bullet will be added to the vector on one turn, but won't be accessed until the next turn when your main loop starts over.
I want to reverse my direction when my movement is about to finish. I use something like if (getDistanceRemaining() < minimum), but the bot behaves in a strange way.
The getDistanceRemaining() method (and in general all methods returning remaining movements of the body, gun, or radar) can return a positive or a negative value, depending on the direction of your movement. Use if (Math.abs(getGetDistanceRemaining()) < minimum) instead.

See also