[Home]FastTargeting

Robo Home | Changes | Preferences | AllPages

HeadOnTargeting
LinearTargeting
CircularTargeting
BearingOffsetTargeting
RandomTargeting
SprayTargeting

Describes targeting methods which fire which achieve their potential with only 1 or 2 scans. They typically use an algorithm to fire at, and will usually work against one type of movement much more than others.

HeadOnTargeting

Shoot where the target is right now. The simplest form of targeting, and yet often effective especially in melee.

LinearTargeting

A method of Targeting which assumes that the target will continue in the same direction at the same speed.

Implementations


CircularTargeting

Circular Targeting is used to hit bots that often move in circles or large arcs. The first step is to measure the turnrate of your target bot by subtracting it's current heading with it's previous one. If you do not get a fresh scan of your target, you need to divide this by the time between current scan and your last scan to obtain an average turnrate:
public void onScannedRobot(ScannedRobotEvent e)
{
	double turnrate=(e.getHeadingRadians()-lastEnemyHeading)/(getTime()-scantime);
	scantime=getTime();
	lastEnemyHeading=e.getHeadingRadians();
	...
	...
	...
}

Now we need to know the current position of the target bot. To keep things easy, we only calculate the position of your target relative to your position. Keep in mind that in Robocode, "north" is zero degrees(radians) and clockwise is a positive angle. This is exactly the inverse of unit-circle math, where the x-axis is zero degrees and anti-clockwise is a positive angle.

	absoluteBearing = e.getBearingRadians() + getHeadingRadians();
	double relativeX = e.getDistance()*Math.sin(absoluteBearing);
	double relativeY = e.getDistance()*Math.cos(absoluteBearing);

Since we assume the target will keep turning at the same turnrate every turn, we can predict it's position at any time by calculating a new velocity-vector, and add that to it's position. If we call the time that you scanned the target t=0, then it's position at t=1 will be:

 (this is not a java code snippet)
 ( 1 )	newX(1) = relativeX + enemyVelocity*sin(initialHeading + turnrate)
 ( 2 )	newY(1) = relativeX + enemyVelocity*cos(initialHeading + turnrate)

at time t=2, it will be

 (this is not a java code snippet)
 ( 3 )	newX(2) = relativeX + enemyVelocity*sin(initialHeading + turnrate) + enemyVelocity*sin(initialHeading + turnrate + turnrate)
 ( 4 )	newY(2) = relativeX + enemyVelocity*cos(initialHeading + turnrate) + enemyVelocity*cos(initialHeading + turnrate + turnrate)

You can see that you can calculate the new (relative) X/Y position at t=T by adding a newly calculated velocity-vector to its position on every t.

 (this is not a java code snippet)
 ( 5 )	newX(T) = relativeX +  enemyVelocity*sin(initialHeading + t*turnrate)
 ( 6 )	newY(T) = relativeY +  enemyVelocity*cos(initialHeading + t*turnrate)

Space and time is not continuous in Robocode, but the discreet steps are small enough, that we can approximate the above summation with an integral:

 (this is not a java code snippet)
 ( 7 )	newX(T) = relativeX + enemyVelocity *  sin(initialHeading + t*turnrate) dt
 ( 8 )	newY(T) = relativeY + enemyVelocity *  cos(initialHeading + t*turnrate) dt

integrating from t=0 to t=T wich results in: (watch the +/- signs!! and where you need cosine and sine)

 (this is not a java code snippet)
 ( 9 )	newX(T) = relativeX - (enemyVelocity/turnrate) * (cos(initialHeading + T*turnrate) - cos(initialHeading))
 ( 10 )	newY(T) = relativeY + (enemyVelocity/turnrate) * (sin(initialHeading + T*turnrate) - sin(initialHeading))

Just fill in T in the above and you can predict your circular-moving target's position at time T! Now to predict at wich time your bullet is going to hit your target. The time it would take for your bullet to travel to the target's current position is a good guess to start with. So your first guess would be T = enemyDistance/bulletSpeed. If we plug this T in formulae (9) and (10), we have a prediction of the target's new (relative) position at time T. But since the target will be moving around, rather than playing sittingDuck, this is a rather poor approximation of the time T we are after. We can improve our approximation by calculating the time it would take for your bullet to reach the previously predicted position. This new T can then in turn be used to calculate a better predicted position, which, in turn, can be used to calculate an even better approximation of the actual time T, etc...etc... I myself have never used this iteration technique, but I remember reading somewhere(RoboCodeRepository? forums?) that 4 or 5 of these iterations should be good enough. Alisdair Owens, the author of Nicator and the [SnippetBot tutorial], wrote an article for "Secrets of the Robocode master" about circular targeting with iteration. You can find it here: http://www-106.ibm.com/developerworks/library/j-circular/

Another method is to start at T=0, and keep increasing with T with 1. Every time you increase your T, compare the distance your bullet would travel in T timeframes, with the distance between you and the predicted position of your target at time T. Stop when your bullet reaches your target, and you'll have a predicted position! Because the position of the target is calculated step-by-step anyway, we don't need formulae (9) and (10) and will be performing the summations (5) and (6) step by step as well. You can find an example from this in CodeSnippets section. It's the source-code from my bot Nano Circular Linear Predictor, a bot I built just to prove that a circular predictor fits into a NanoBot. :-) Note that the step-by-step method can be used for both CircularTargeting and LinearTargeting, whereas the integrated formulae (9) and (10) are not suited for linear targeting. (Linear targeting means turnrate = 0)

--- Dummy

Related Links:


BearingOffsetTargeting?

- Firing at the angle that would have worked last time.

RandomTargeting

- Works on the assumption that the target can move a maximum of 46.6 degrees in either direction, and so fires randomly at an angle between -46.6 and 46.6. Provides an even (but low) probability of hitting, and can lead into StatisticalTargeting if you begin to weight more probable angles.

SprayTargeting?

- Also works on the assumption that the target can move a maximum of 46.6 degrees in either direction, but instead of fireing randomly you simply let your gun sweep over these angles firing bullets along the way, back and forth. Provides an uneven hit ratio since much is dependent on how your enemy moves, but you are almost guaranteed some hits.

These techniques yield different percentages based on the bots you are fighting. While most give a mediocre return at best, against the right bot they can be gold (just watch CircularTargeting against SpinBot). Some techniques improve by using an averaged value rather than the current data.


Question: Would you prefer a brief description with a link to a more detailed page, the detailed pages on here, or a full overview with a link to implementations of it. The HeadOnTargeting is an example of the first part, while circular targeting is an example of the second. Let me know which you prefer


Personally I prefer the first option, but I can live with the second one. By the way, is it possible to go more than two deep with subpages? -- GrubbmGait

I wish it was, but I dont think so. I am currently toying with that third option middle ground. Having the full description discussion etc on here and then code implementations and tutorials on a seperate page. It will probably be closer to the first option, but with the page being a bit more focused. Check out the LinearTargeting part to see how it would be. -- Jokester


Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited January 15, 2009 19:59 EST by Dummy (diff)
Search: