setTurnRadarLeftRadians(((getOthers() == 1 && timeSinceLastScan? < 3)?robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians?() - enemyAbsoluteBearing?):Double.POSITIVE_INFINITY)<0?(((getOthers() == 1 && timeSinceLastScan? < 3)?robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians?() - enemyAbsoluteBearing?):Double.POSITIVE_INFINITY)*0.98:(((getOthers() == 1 && timeSinceLastScan? < 3)?robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians?() - enemyAbsoluteBearing?):Double.POSITIVE_INFINITY)*1.02); |
double radaroffset = (getOthers() == 1 && timeSinceLastScan? < 3)?robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians?() - enemyAbsoluteBearing?):Double.POSITIVE_INFINITY); setTurnRadarLeftRadians(radaroffset * (radaroffset > 0 ? 1.02 : 0.98 )); |
-- Kinsen |
-- Kinsen |
public class RadarBot extends AdvancedRobot { private int timeSinceLastScan = 10; static double enemyAbsoluteBearing; do { doScanner(); execute(); } while true; public void onScannedRobot(ScannedRobotEvent e) { enemyAbsoluteBearing = getHeadingRadians() + e.getBearingRadians(); timeSinceLastScan = 0; } private void doScanner() { timeSinceLastScan++; double radarOffset = Double.POSITIVE_INFINITY; if(getOthers() == 1 && timeSinceLastScan < 3) { radarOffset = robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians() - enemyAbsoluteBearing); radarOffset += sign(radarOffset) * 0.02; } setTurnRadarLeftRadians(radarOffset); } int sign(double v) { return v > 0 ? 1 : -1; } }This is not by any means a radar meant for minibots since it consumes way to much codesize for that. Still, it's the radar used by Tityus, which leaves some room for imporvement of that bot. -- PEZ
Thanks for the code example pez, this will be easy enough to get into my Micro, I have like 150 codesize to burn :) but I know I should shrink some of the stuff I have down. It isnt very compressed as it is. -- Dan724
why do you need to keep track of "timeSinceLastScan" ? --SSO?
Sometimes the radar "slips" and then I need to spin the radar full turn. Or that's the theory. I have not tried without this. Does it work? -- PEZ
If you don't do that, you need to account for the beginning of the round. -- Kawigi
What does the sign function do? I'm not familiar with the syntax. Thanks. -- Tango
It just returns 1 for positive numbers and -1 for negative numbers or zero. It's good for knowing in what "direction" this or that observation is going. -- PEZ
Is that some kind of special java short version of if/then/else? :-/ I really should learn java properly... -- Tango
You could see it as a short for if/then/else. But it's nothing specifically Java about it. The function is actually defined last in that code snippet. Look closer. =) I would say that it's more a math thing if it wasn't that I think you should return zero for a zero value then. I could have used an if/then/else structure, but I don't think it would have been as readable. -- PEZ
I was looking at the function definition. I just don't recognise the syntax with question marks and colons and suchlike. :-/ As i say, i should probably learn java. -- Tango
Ah! Sorry, I misunderstood the question. The question-mark and colon is sort-of a Java short for if/then/else indeed. It's called the trinary condition operator. It's inherited from C. Since lots and lots of programming languages take a lot of inspiration from the C syntax this operator exists in many languages. A similar thingy exists in the macro language of Excel if you are more familiar with that. There it's a function "immediate if()" named IIF(condition, result-if-true, result-if-false). So you read the statement in that sign() function like so: "If the value ''v" is greater than 0 - return 1, else return -1. -- PEZ
Unlike an if/then/else this does not /do/ anything, it merely selects between which of two values to "show" to the statement outside it. Ie:
if(blah) do_something();is legal.
blah?do_something:do_somethingelse();is not, unless do_something() and do_somethingelse() return values, and even then the trinary condition needs to be assigned somewhere, it can't be a standalone statement. -- Kuuran
Anyone thought of squeezing the code into a smaller space? :
private void doScanner() { timeSinceLastScan++; double radaroffset = (getOthers() == 1 && timeSinceLastScan < 3)?robocode.util.Utils.normalRelativeAngle(getRadarHeadingRadians() - enemyAbsoluteBearing):Double.POSITIVE_INFINITY); setTurnRadarLeftRadians(radaroffset * (radaroffset > 0 ? 1.02 : 0.98 )); }
-- nfwu
I do not think this is smaller in codesize, and certainly not more readable. -- GrubbmGait
I mainly use a radar that determines how much it should turn to be exactly aimed at the enemy and then add a few degrees to keep it from slipping. I have only seen it completely slip once or twice (I do have some anti-radar slip code so that accounts for a few). I am not sure about the exact codesize but it is around 80. Of course the following code is the core of mine but...
double turnRadar = Utils.normalRelativeAngle(Utils.angleFromPoint(myX, myY, enemyX, enemyY) - radarHeading); if (others == 1) turnRadar += ((turnRadar >= 0)? 2: -2); else turnRadar += ((turnRadar >= 0)? 45: -45); return turnRadar;
It does not work to well for melee but the if statement can be changed from having a very large angle to spinning like this:
double turnRadar = Utils.normalRelativeAngle(Utils.angleFromPoint(myX, myY, enemyX, enemyY) - radarHeading); if (others == 1) turnRadar += ((turnRadar >= 0)? 2: -2); else turnRadar = 360; return turnRadar;
(Note: The code uses degrees.)
-- Kinsen