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:
-- David Alves
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
setTurnRadarRightRadians(Math.sin((targetBearing=e.getBearingRadians() + getHeadingRadians()) - getRadarHeadingRadians())*1.5);I took the idea of using Math.sin() from Duelist bots. -- Albert
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(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