double getRadarSweepTurn(double direction) { if (numRecent == robot.getOthers() && oldestEnemy != null) { double radarTurn = oldestEnemy.getAbsoluteBearing() - robot.getRadarHeading(); return Rutils.normalRelativeAngle(radarTurn + Rutils.sign(radarTurn) * Math.min(Math.abs(oldestEnemy.getAbsoluteBearingDelta()) * 5, 22.5)); } else { return 180 * direction; } }The line containing the magic number 22.5 makes sure that if I have a small bearingDelta to the oldestEnemy I go shortly past it and if the bearingDelta is large I go at least 22.5 degrees past it. This magic number was explained in that article I mentioned above as being half the distance the radar travels in one tick. It works, so I have accepted it. =) In the beginning of each round (id est; in the beginning of the run() method, before the while (true) loop) I register a RadarTurnCompleteCondition custom event which executes the following code:

double sweepTurn = school.getRadarSweepTurn(radarDirection); setTurnRadarRight(sweepTurn); radarDirection = Math.sign(sweepTurn);"school" being the school of Enemies. If you're even considering competing in Melee battles I guess you'll eventually end up with a collection like that anyway. This radar management works quite OK in Melee battle as far as I can judge and it isn't all that bad in OneOnOne battle either. Though you might want to experiment with drastically shrinking that magic number 22.5 when you have only one enemy. Marshmallow doesn't do that. It uses a completely different, and even simpler, management of the radar in OneOnOne situations.

-- PEZ

double scan() { double radarOffset; Enemy target = environment.getTarget(); double scanArcWidth = .05; if (me.getTime() - target.getLastScannedTime() > 8){ //Scan out of date, sweep radar in full circle return QUARTERCIRCLE; } //Find angle to move radar so that it points directly at the enemy radarOffset = angularDifferenceBetween(me.getRadarHeading(),me.getAbsoluteAngleTo(environment.getTarget())); //Move radar so it sweeps a little past him. if (radarOffset < 0) radarOffset -= scanArcWidth; else radarOffset += scanArcWidth; return radarOffset; }

In case it isn't clear, here's what the variables and functions are:

- radarOffset: How much we should turn the radar on this turn.
- scanArcWidth: How wide the scan ard should be. I use a narrow one because I think it looks cooler but it makes no difference in 1-v-1.
- Enemy: a class used to represent the enemy. "target" is an instance of enemy with our current target.
- QUARTERCIRCLE: a constant representing a quarter of a circle.
- angularDifferenceBetween(double a, double b): the shortest way to turn from angle "a" to angle "b"
- getAbsoluteAngleTo(Enemy e): The angle to our enemy, NOT relative to our current heading. Note that when you do ScannedRobotEvent.getBearing() the number is relative to your current heading, so you need to adjust for this...

-- David Alves

Here's the current OneOnOne radar of Marshmallow (inside onScannedRobot()):

if (isOneOnOne) { setTurnRadarRight(RUtils.normalRelativeAngle(getHeading() + e.getBearing() - getRadarHeading()) * 1.6); }Works pretty well, but at times it the radar "slips" off of the enemy. I'd be grateful to anyone who can help in minimizing that, my pattern matcher is sensitive to these glitches. -- PEZ

The one for Aspid is like follows:

setTurnRadarRightRadians(Math.sin((targetBearing=e.getBearingRadians() + getHeadingRadians()) - getRadarHeadingRadians())*1.5);I took the idea of using Math.sin() from Duelist bots. -- Albert

x = Math.asin(Math.sin(x)) is a well-known way to normalize an angle in Minibots. It will find the equivalent angle between -pi/2 and pi/2. For example, 6 radians becomes -.28... Radians. So a basic radar would be

setTurnRadarRightRadians(Math.asin(Math.sin(e.getBearingRadians?() + getHeadingRadians() - getRadarHeadingRadians?())).

What I did was drop the Math.asin() since for angles close to 0, sin(x) is approximately equal to x. Since the angle to the enemy is roughly 0, Math.sin(x) alone is close enough to the correct normalized angle to work. If you then multiply this by a number, you're having the radar sweep past the target, so that on the next turn it will sweep back, and so on. Multiplying by less than two will give a scan arc that gets smaller and smaller (with both bots stationary), equal to 2 will give a constant size scan arc, and larger than two will give a scan arc that gets larger and larger, up to the limit of 45 degrees per tick. I use 3, which makes the scan arc get larger over time, and makes the arc wide enough that I don't need to use setAdjustRadarForGunTurn(true), which costs 5 bytes. --David Alves

//------------------------------------------------------------------------------- // Scan all bots. Reverse when complete. Does a real good job. (From mld.Steel) //------------------------------------------------------------------------------- public void onScannedRobot(ScannedRobotEvent e) { if(!botNameList.contains(e.getName())) { botNameList.add(e.getName()); if(botNameList.size() >= me.getOthers()) { botNameList.clear(); me.setTurnRadarLeft(me.getRadarTurnRemaining()); } } }

-- Miked0801

public class ScanBot extends AdvancedRobot { public void run() { setTurnRadarRight(Double.POSITIVE_INFINITY); } public void onScannedRobot(ScannedRobotEvent e) { if (getOthers() == 1) setTurnRadarLeft(getRadarTurnRemaining()); } }-- Vuen

If you dont care too much about codesize ive got a method that works 99.999% of the time and never slips. Works in both OneOnOne and Melee but it completley ignores all other bots in Melee. Make this your while(true) loop:

if(lastScanned >= 3) { haveTarget = false; } scan(); if(haveTarget) { //put all of your robot behavior here setTurnRadarRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearingRadians -getRadarHeadingRadians())); } else { setTurnRadarRight(360); } lastScanned++; execute();Then Add "haveTarget = true;" and "absoluteBearingRadians? = getHeadingRadians() + e.getBearingRadians?();" to the beginning of onScannedRobot and add "lastScanned = 0;" to the end of it. Oh... and create "int lastScanned", "boolean haveTarget", "double absoluteBearingRadians?".

-- Dan724?

I think that the code for the radar lock only turns the radar to the exact location of the other robot. Then it would not work all the time if the other robot is not moving and occaisionally when the other robot is moving in the same direction as the radar.

setTurnRadarRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearingRadians -getRadarHeadingRadians()));The easiest way to fix it is to add a degree to the radar in the same direction so that it goes past the target a little. -- Kinsen