Difference between revisions of "Radar"
(Adding code snippet to Oldest Scanned Melee Radar (!! untested !!) (asking for someone to expand this code without breaking it)) |
(add melee radar lock) |
||
Line 44: | Line 44: | ||
==== Narrow lock ==== | ==== Narrow lock ==== | ||
− | Point the radar at the enemy's last known location. This results in a thin beam which follows the enemy around the battlefield. It works because most of the time, the enemy isn't able to move entirely outside our radar beam in the space of a single turn. This might not be true in some extreme cases, and radar lock can occasionally be lost. | + | Point the radar at the enemy's last known location. This results in a thin beam which follows the enemy around the battlefield. It works because most of the time, the enemy isn't able to move entirely outside our radar beam in the space of a single turn. This might not be true in some extreme cases, and radar lock can occasionally be lost but this can be fixed by factor describe below. Most top bot (that I figure out) use this kind of radar. |
Here is an example of this kind of radar: | Here is an example of this kind of radar: | ||
Line 76: | Line 76: | ||
* 1.0 Just gives the same behaviour as above. | * 1.0 Just gives the same behaviour as above. | ||
* 1.99 Gives a lock that slowly narrows down to the minimal necessary to stay on target. | * 1.99 Gives a lock that slowly narrows down to the minimal necessary to stay on target. | ||
− | * 2.0 Keeps sweeping a little bit ahead and behind the target to stay locked on. | + | * 2.0 Keeps sweeping a little bit ahead and behind the target to stay locked on. This is factor which most top bot used. |
==== Wide lock ==== | ==== Wide lock ==== | ||
Line 125: | Line 125: | ||
==== Corner Arc ==== | ==== Corner Arc ==== | ||
− | A variation on the spinning radar, if the robot is in a corner it scans back and forth across the 90 degree arc away from the corner, as not to waste time scanning where there cannot be any robots. | + | A variation on the spinning radar, if the robot is in a corner it scans back and forth across the 90 degree arc away from the corner, as not to waste time scanning where there cannot be any robots. Typically, this is not popular in melee, and those bots use kind of radar below instead. |
=== Oldest Scanned === | === Oldest Scanned === | ||
Line 172: | Line 172: | ||
} | } | ||
</pre> | </pre> | ||
+ | With above code, the radar will spin passed every bot, and then reverse it's direction until passed all bots and repeat again. if spin take more than 4 ticks, Radar will continue spinning like spinning radar above. This kind of radar are use in many top bots include Shadow and Phoenix. I prefer you to use this kind of radar unless you need a melee radar lock or your targeting system require you to have enemy scan every 8 ticks. | ||
+ | |||
+ | === Melee Radar Lock === | ||
+ | A technique use first by Coriantumr I think ;). This radar allow you to lock on target when low gunheat. | ||
+ | <pre> | ||
+ | |||
+ | public void run() { | ||
+ | // ... | ||
+ | setTurnRadarRightRadians(Double.POSITIVE_INFINITY); | ||
+ | } | ||
+ | |||
+ | public void onScannedRobot(ScannedRobotEvent e) { | ||
+ | // ... your own target selection | ||
+ | double absoluteBearing = getHeadingRadians() + e.getBearingRadians(); | ||
+ | if (isCurrentTarget && getGunHeat() < 0.5) { // Lock for 5 ticks | ||
+ | setTurnRadarRightRadians(3.5 * Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians())); | ||
+ | else | ||
+ | setTurnRadarRightRadians(Double.POSITIVE_INFINITY); | ||
+ | } | ||
+ | </pre> | ||
+ | The code above use Narrow Lock but the simple Infinity Lock works well as well. For narrow lock, I recommend you to multiply by large factor to continue scan another robots while locking. This technique is recommend if you use GuessFactor Targeting in melee battle. | ||
== Notes == | == Notes == |
Revision as of 15:12, 25 January 2009
The radar is one of the most vital components of your robot. Without it, targeting is effectively impossible and movement is purely random. Just as with movement and targeting, there are many simple and complex algorithms for radar control. In most robots the radar takes up the smallest portion of code.
In robots that do a lot of processing, it is best to place the radar code near the beginning of the processing loop for each tick, as this will allow the radar to avoid slipping if the robot skips a turn due to too much processing.
Contents
Technical Information
A radar in Robocode has a maximum of 45° or π/4rad in a single tick. The radar can scan robots up to 1200 units away. The angle the radar rotates between two ticks creates a radar arc, and every robot detected within the arc is sent to the onScannedRobot()
method in order of distance from the scanning bot - the closest bot is detected first, while the furthest bot is detected last. By default, the onScannedRobot()
method has the lowest event priority of all the event handlers in Robocode, so it is the last one to be triggered each tick.
1-vs-1 Radars
1-vs-1 radars are the smallest of the bunch and many can get a scan in every turn, producing a perfect lock.
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); }
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.
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.
Narrow lock
Point the radar at the enemy's last known location. This results in a thin beam which follows the enemy around the battlefield. It works because most of the time, the enemy isn't able to move entirely outside our radar beam in the space of a single turn. This might not be true in some extreme cases, and radar lock can occasionally be lost but this can be fixed by factor describe below. Most top bot (that I figure out) use this kind of radar.
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 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 problem of the odd slippage can be resolved by multiplying the sweep angle by a factor, eg. factor*Utils.normalRelativeAngle(radarTurn)
- 1.0 Just gives the same behaviour as above.
- 1.99 Gives a lock that slowly narrows down to the minimal necessary to stay on target.
- 2.0 Keeps sweeping a little bit ahead and behind the target to stay locked on. This is factor which most top bot used.
Wide lock
The wide radar locks are used to avoid the rare slipping of the narrow lock. They scan a wider portion of the battlefield and will not slip. This type of lock is generally the largest of the 1-vs-1 radars.
Here is an example of this type of radar:
import robocode.util.Utils; public void run() { // ... while(true) { turnRadarRightRadians(Double.POSITIVE_INFINITY); } } public void onScannedRobot(ScannedRobotEvent e) { double absoluteBearing = getHeadingRadians() + e.getBearingRadians(); double radarTurn = Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()); // Width of the bot, plus twice the arc it can move in a tick, limit it to the max turn double arcToScan = Math.min(Math.atan(36.0 / e.getDistance()), PI/4.0); // We want to sent the radar even further in the direction it's moving radarTurn += (radarTurn < 0) ? -arcToScan : arcToScan; setTurnRadarRightRadians(radarTurn); // ... }
Melee radars
Melee radars are more complex and take up considerable more room inside a robot. Since the field of opponents does not usually fall within a 45° area, compromises must be made between frequent data of one bot (e.g., the firing target) and consistently updated data of all bots.
Spinning radar
Just as with one on one, there is the generic spinning radar. This is the most used melee radar as it is by far the easiest to implement.
public void run() { // ... while(true) { turnRadarRightRadians(Double.POSITIVE_INFINITY); } }
Corner Arc
A variation on the spinning radar, if the robot is in a corner it scans back and forth across the 90 degree arc away from the corner, as not to waste time scanning where there cannot be any robots. Typically, this is not popular in melee, and those bots use kind of radar below instead.
Oldest Scanned
This type of melee radar spins towards the robot it hasn't seen in the longest amount of time. Here is an example of this type of radar.
import java.util.*; import robocode.*; import robocode.util.*; // ... Within robot class static LinkedHashMap<String, Double> enemyHashMap; static double scanDir; static Object sought; public void run() { scanDir = 1; enemyHashMap = new LinkedHashMap<String, Double>(5, 2, true); // ... while(true) { setTurnRadarRightRadians(scanDir * Double.POSITIVE_INFINITY); scan(); } } public void onRobotDeath(RobotDeathEvent e) { enemyHashMap.remove(e.getName()); sought = null; } public void onScannedRobot(ScannedRobotEvent e) { String name = e.getName(); LinkedHashMap<String, Double> ehm = enemyHashMap; ehm.put(name, getHeadingRadians() + e.getBearingRadians()); if ((name == sought || sought == null) && ehm.size() == getOthers()) { scanDir = Utils.normalRelativeAngle(ehm.values().iterator().next() - getRadarHeadingRadians()); sought = ehm.keySet().iterator().next(); } // ... }
With above code, the radar will spin passed every bot, and then reverse it's direction until passed all bots and repeat again. if spin take more than 4 ticks, Radar will continue spinning like spinning radar above. This kind of radar are use in many top bots include Shadow and Phoenix. I prefer you to use this kind of radar unless you need a melee radar lock or your targeting system require you to have enemy scan every 8 ticks.
Melee Radar Lock
A technique use first by Coriantumr I think ;). This radar allow you to lock on target when low gunheat.
public void run() { // ... setTurnRadarRightRadians(Double.POSITIVE_INFINITY); } public void onScannedRobot(ScannedRobotEvent e) { // ... your own target selection double absoluteBearing = getHeadingRadians() + e.getBearingRadians(); if (isCurrentTarget && getGunHeat() < 0.5) { // Lock for 5 ticks setTurnRadarRightRadians(3.5 * Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians())); else setTurnRadarRightRadians(Double.POSITIVE_INFINITY); }
The code above use Narrow Lock but the simple Infinity Lock works well as well. For narrow lock, I recommend you to multiply by large factor to continue scan another robots while locking. This technique is recommend if you use GuessFactor Targeting in melee battle.
Notes
For most of these radar locks, you will need to add one of the following to your run()
method:
setAdjustRadarForRobotTurn(true); setAdjustGunForRobotTurn(true); setAdjustRadarForGunTurn(true);