Difference between revisions of "Robocode/Game Physics"
(→Robocode Processing Loop: Explained event handler cancellation) |
|||
Line 83: | Line 83: | ||
Most of this can be gleamed by following the method calls from BaseBattle.runRound() and Battle.runTurn() in the robocode.battle module. | Most of this can be gleamed by following the method calls from BaseBattle.runRound() and Battle.runTurn() in the robocode.battle module. | ||
+ | |||
+ | Event dispatch happens from within commands that take a turn. So the call stack | ||
+ | when an event is delivered usually looks like this: | ||
+ | |||
+ | Robocode internals → Robot's run method → Robocode internals → Event handler | ||
+ | |||
+ | However, event handlers can themselves make calls that take turns. If one of | ||
+ | these happens to generate an event, we might suspect a call stack like | ||
+ | |||
+ | Robocode internals → Robot's run method → Robocode internals → First event handler → Robocode internals → Second event handler | ||
+ | |||
+ | But, as this could lead to a stack overflow or even just undesirable robot | ||
+ | behavior, Robocode takes special steps for events generated within event | ||
+ | handlers; these measures are implemented in EventManager.processEvents(). In | ||
+ | particular, the call stack will get as far as | ||
+ | |||
+ | Robocode internals → Robot's run method → Robocode internals → First event handler → Robocode internals | ||
+ | |||
+ | until processEvents detects the impending nesting and throws an | ||
+ | EventInterruptedException, which unwinds the stack to | ||
+ | |||
+ | Robocode internals → Robot's run method → Robocode internals | ||
+ | |||
+ | effectively canceling whatever the running event handler was up to. The outer | ||
+ | event loop catches the exception and resumes delivering events, letting the | ||
+ | second event handler execute unnested: | ||
+ | |||
+ | Robocode internals → Robot's run method → Robocode internals → Second event handler | ||
=== Firing Pitfall === | === Firing Pitfall === |
Revision as of 01:04, 20 November 2014
This page describes the game physics of Robocode.
Contents
Coordinates and Direction Conventions
Coordinates System: | Robocode is using the Cartesian Coordinate System, which means that that the (0, 0) coordinate is located in the bottom left of the battle field. |
---|---|
Clockwise Direction: | Robocode is using a clockwise direction convention where 0 / 360 deg is towards "North", 90 deg towards "East", 180 deg towards "South", and 270 deg towards "West". |
Figure 1:
http://www.ibm.com/developerworks/java/library/j-robocode2/fig2.gif
Time and distance measurements in Robocode
Time (t): | Robocode time is measured in "ticks". Each robot gets one turn per tick. 1 tick = 1 turn. |
---|---|
Distance Measurement: | Robocode's units are basically measured in pixels, with two exceptions. First, all distances are measured with double precision, so you can actually move a fraction of a pixel. Second, Robocode automatically scales down battles to fit on the screen. In this case, the unit of distance is actually smaller than a pixel. |
Robot Movement Physics
Acceleration (a): | Robots accelerate at the rate of 1 pixel/turn/turn. Robots decelerate at the rate of 2 pixels/turn/turn. Robocode determines acceleration for you, based on the distance you are trying to move. |
---|---|
Velocity Equation(v): | v = at. Velocity can never exceed 8 pixels/turn. Note that technically, velocity is a vector, but in Robocode we simply assume the direction of the vector to be the robot's heading. |
Distance Equation (d): | d = vt. That is, distance = velocity * time |
Robot, Gun, and Radar rotation
Max rate of rotation of robot: | (10 - 0.75 * abs(velocity)) deg / turn. The faster you're moving, the slower you turn. |
---|---|
Max rate of rotation of gun: | 20 deg / turn. This is added to the current rate of rotation of the robot. |
Max rate of rotation of radar: | 45 deg / turn. This is added to the current rate of rotation of the gun. |
Bullets
Damage: | 4 * firepower. If firepower > 1, it does an additional damage = 2 * (power - 1). |
---|---|
Velocity: | 20 - 3 * firepower. |
GunHeat generated: | 1 + firepower / 5. You cannot fire if gunHeat > 0. All guns are hot at the start of each round. |
Power returned on hit: | 3 * firepower. |
Collisions
With Another Robot: | Each robot takes 0.6 damage. If a robot is moving away from the collision, it will not be stopped. |
---|---|
With a Wall: | AdvancedRobots take abs(velocity) * 0.5 - 1; (Never < 0). |
Robocode Processing Loop
The order that Robocode runs is as follows:
- Battle view is (re)painted.
- All robots execute their code until they take action (and then paused).
- Time is updated (time = time + 1).
- All bullets move and check for collisions. This includes firing bullets.
- All robots move (gun, radar, heading, acceleration, velocity, distance, in that order).
- All robots perform scans (and collect team messages).
- All robots are resumed to take new action.
- Each robot processes its event queue.
Most of this can be gleamed by following the method calls from BaseBattle.runRound() and Battle.runTurn() in the robocode.battle module.
Event dispatch happens from within commands that take a turn. So the call stack when an event is delivered usually looks like this:
Robocode internals → Robot's run method → Robocode internals → Event handler
However, event handlers can themselves make calls that take turns. If one of these happens to generate an event, we might suspect a call stack like
Robocode internals → Robot's run method → Robocode internals → First event handler → Robocode internals → Second event handler
But, as this could lead to a stack overflow or even just undesirable robot behavior, Robocode takes special steps for events generated within event handlers; these measures are implemented in EventManager.processEvents(). In particular, the call stack will get as far as
Robocode internals → Robot's run method → Robocode internals → First event handler → Robocode internals
until processEvents detects the impending nesting and throws an EventInterruptedException, which unwinds the stack to
Robocode internals → Robot's run method → Robocode internals
effectively canceling whatever the running event handler was up to. The outer event loop catches the exception and resumes delivering events, letting the second event handler execute unnested:
Robocode internals → Robot's run method → Robocode internals → Second event handler
Firing Pitfall
Because bullets are fired before the gun is moved, calling setFire() will cause the bullet to leave at the current gun heading. This may seem counter-intuitive if you are used to thinking in terms of pointing a gun, then shooting. It is also inconvenient because you can't call setTurnGun(...)
and setFire(...)
right after each other (not if you need perfect accuracy, anyway). Most of the time, the error will be so small you won't notice it, but if you're testing a pattern matcher against sample.Walls
, you will occasionally spot the bug.
To get the bullet to leave after turning the gun, you will need to use code like this:
long fireTime = 0;
void doGun() {
if (fireTime == getTime() && getGunTurnRemaining() == 0) {
setFire(2);
}
// ... aiming code ...
setTurnGunRight(...);
// Don't need to check whether gun turn will complete in single turn because
// we check that gun is finished turning before calling setFire(...).
// This is simpler since the precise angle your gun can move in one tick
// depends on where your robot is turning.
fireTime = getTime() + 1;
}
See also
Robot API
Tutorials
- System Requirements for Robocode
- How to download and install Robocode
- The anatomy of a robot
- Getting started with Robocode
- My First Robot Tutorial
- Scoring in Robocode
- Using the robot console
- Downloading other robots
- Learning from other robots
- Package your robot
- Frequently Asked Questions (FAQ)
- Articles about Robocode
- Starting Robocode from the command line
- Graphical debugging
- Using Eclipse as IDE
- Creating a project for your robots
- Creating a robot in Eclipse
- Running your robot from Eclipse
- Debugging your robot with Eclipse