One on One Radar
One on One Radars are radars that are used for One on One battles. They usually produce a perfect lock by scanning an enemy every turn.
Contents
Simple Radar Locks
These radars are the simplest to write and usually produce the smallest bytecode, which is useful with codesize restrictions.
Spinning radar
A simple spin of the radar, this is very ineffective in one on one, but still used in NanoBots.
Here is an example of this type of radar:
public void run() {
// ...
do {
turnRadarRightRadians(Double.POSITIVE_INFINITY);
} while (true);
}
A slightly smaller implementation can be achieved with using onStatus(..) instead of run(). This saves the bytes for the loop and can also be used for turn multiplier and width lock radars.
public void onStatus( StatusEvent e) {
// you can also put all setAdjustXX(..) methods here
setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
}
The Infinity Lock
The infinity lock is the simplest radar lock and it is used frequently in NanoBots. It has the disadvantage of "slipping" and losing its lock frequently. But is a much better alternative to the Spinning radar in one on one combat.
Here is an example of this type of radar:
public void run() {
// ...
turnRadarRightRadians(Double.POSITIVE_INFINITY);
}
public void onScannedRobot(ScannedRobotEvent e) {
// ...
setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
}
Perfect Radar Locks
There are several "perfect" radar locks that will not slip once they have a lock.
Turn Multiplier Lock
Point the radar at the enemy's last known location. This results in a thin beam which follows the enemy around the battlefield. Many recent one on one bots use this type of radar. This radar lock is similar to, and considered an enhancement on the wide radar lock described below.
If implemented correctly, it is not possible for the enemy escape this lock. A robot's width is 36px (that's 18px from the middle) and it can only move at up to 8px/turn, so if your beam is pointing at its centre, it won't be able to move entirely out of it in one turn. However, a robot will only automatically scan for enemies if its radar is turning, which might not happen if you are using a Narrow Lock and your enemy decides to stay still for 2 turns. For this reason, if you decide to use an unmultiplied lock, you must call scan()
yourself to avoid losing lock. Furthermore, if you skip turns, your enemy might be able to move out from your radar beam before you recover.
To overcome these issues, a Narrow Lock is often multiplied by a factor (as described below) to keep the radar moving and ensure the enemy does not escape the scan arc.
Here is an example of this kind of radar:
import robocode.util.Utils;
public void run() {
// ...
turnRadarRightRadians(Double.POSITIVE_INFINITY);
do {
// Check for new targets.
// Only necessary for Narrow Lock because sometimes our radar is already
// pointed at the enemy and our onScannedRobot code doesn't end up telling
// it to turn, so the system doesn't automatically call scan() for us
// [see the javadocs for scan()].
scan();
} while (true);
}
public void onScannedRobot(ScannedRobotEvent e) {
double radarTurn =
// Absolute bearing to target
getHeadingRadians() + e.getBearingRadians()
// Subtract current radar heading to get turn required
- getRadarHeadingRadians();
setTurnRadarRightRadians(Utils.normalRelativeAngle(radarTurn));
// ...
}
The following factors affect the behaviour in the following ways (eg. factor * Utils.normalRelativeAngle(radarTurn)
)
- 1.0 - Thin radar lock. Must call scan() to avoid losing lock. God help you if you ever skip a turn.
- 1.9 - Radar arc starts wide and slowly narrows as much as possible while staying on target.
- 2.0 - Radar arc sweeps through a fixed angle. Exact angle chosen depends on positions of enemy and radar when enemy is first picked up. Angle will be increased if necessary to maintain a lock. Most used corrective factor.
Width Lock
The Width Radar Lock or Wide Radar Lock tries to scan a fixed distance to either side of the enemy. It was to the best of knowledge created before the Turn Multiplier or Narrow Radar Lock. Its constant motion means the radar will not slip as long as you don't miss any turns.
Here is an example of this type of radar:
import robocode.util.Utils;
public void run() {
// ...
do {
// ...
// Turn the radar if we have no more turn, starts it if it stops and at the start of round
if ( getRadarTurnRemaining() == 0.0 )
setTurnRadarRightRadians( Double.POSITIVE_INFINITY );
execute();
} while ( true );
// ...
}
public void onScannedRobot(ScannedRobotEvent e) {
// ...
// Absolute angle towards target
double angleToEnemy = getHeadingRadians() + e.getBearingRadians();
// Subtract current radar heading to get the turn required to face the enemy, be sure it is normalized
double radarTurn = Utils.normalRelativeAngle( angleToEnemy - getRadarHeadingRadians() );
// Distance we want to scan from middle of enemy to either side
// The 36.0 is how many units from the center of the enemy robot it scans.
double extraTurn = Math.min( Math.atan( 36.0 / e.getDistance() ), Rules.RADAR_TURN_RATE_RADIANS );
// Adjust the radar turn so it goes that much further in the direction it is going to turn
// Basically if we were going to turn it left, turn it even more left, if right, turn more right.
// This allows us to overshoot our enemy so that we get a good sweep that will not slip.
if (radarTurn < 0)
radarTurn -= extraTurn;
else
radarTurn += extraTurn;
//Turn the radar
setTurnRadarRightRadians(radarTurn);
// ...
}
You can replace 36.0
with any distance you want covered.