Bullet Shielding
This is a strategy where your robot shoots down incoming bullets, thereby 'shielding' itself from enemy fire.
Contents |
How does it work?
The concept is very simple. The idea is to make your bullets collide with the enemy bullets. When the enemy fires a bullet, aim your gun to shoot that bullet down, but only fire bullets with 0.1 power. When intercepting a bullet, both bullets explode; but while the enemy is firing high-powered bullets in an attempt at hitting you, you are firing only 0.1 power bullets. The enemy's energy drains much faster than yours, and eventually the enemy runs out of energy and dies from inactivity time. Voila, you win!
How do you intercept a bullet?
To intercept a bullet, you need to know three things: its speed, its heading, and its position.
- Speed: first find the bullet power by taking the drop in the enemy's energy, then use the power formula to calculate its speed.
- Heading: simply assume the bullet is going to hit you. This assumption is valid because if the bullet isn't going to hit you, then it doesn't matter if your shield catches it because it will miss you anyway! The algorithm to assume this is explained below.
- Position. It's given by the enemy's position at the frame when it was fired, so one turn before you scanned it, and then iterated twice from there (i.e. it moved 2*speed pixels in the direction it's heading).
So now that you know its position, speed and heading, just use a linear lead fire algorithm to intercept it, the same way you would lead-fire an enemy; the only difference is that you are lead-firing a bullet rather than an enemy.
The actual implementation of intercepting the bullet is more complicated, and is explained below.
Intercepting Bullets
Bullet Collisions
Bullets in Robocode do not occupy any space; they are simply lines. The length of the line is the bullet's speed, and the direction of the line is in the reverse direction of where it's heading; in other words, the line the bullet 'occupies' is that of it's last displacement. Like so:
For bullets to collide, their last displacements must intersect. That's how bullets collide in Robocode.
Causing a Bullet Collision
Firstly and most importantly, you need to do ALL of the following calculations (except the power recalculation) one frame ahead of when you are planning to fire. This means that if you plan to fire the following turn, you need to iterate ahead a copy of your robot and a copy of the enemy bullet by one frame, then do the following calculations with that data. That will get your gun ready before it's time to fire it. On the frame when you will fire, redo the following calculations with the real robot and bullet positions; your gun should already be pointing at exactly the angle that the algorithm will give you. If it's not (within about 99.999% certainty), you'll need to start over from the top, iterating the robot and bullet ahead and getting the gun ready for the next turn.
To intercept a bullet, first you start off with a form of linear lead fire, just like you would if you were intercepting an enemy robot moving in a straight line. The difference is that rather than looking for the angle where to aim, you will need the coordinates where the bullets will collide. You can calculate this however you would like; if you are comfortable with traditional lead-fire formulas, you may find it easier to find the angle where you should aim your gun, and then find the linear intercept from there. Either way it's some simple trigonometry to find the coordinates of this point. Use a bullet power of 0.15, because you will need to adjust it later.
Once you've got the coordinates, you will need to adjust them. The idea here is to minimize your chance of missing the enemy bullet by making the displacements of both bullets intersect at their midpoints. The reason for this is that you do not know with absolute certainty the heading of the enemy's bullet. If the calculated intersect is near the edges of the bullet displacements and the actual enemy bullet heading is a bit off, the bullet displacements might not intersect, which means the enemy bullet would be missed and would hit you. To prevent this, you must recalculate your gun heading and bullet power.
Using the intercept coordinates you calculated earlier, slide them along the enemy bullet's trajectory to make them land at exactly the midpoint of a nearby displacement. To do this, use parametric (or vector) equations for your coordinates to calculate a parameter, then subtract 0.5 from your parameter and round it off, then add the 0.5 again and recalculate the coordinates. This should slide the coordinates like so:
Now find the heading to aim your gun to intersect these new coordinates using a simple arctangent. This is the heading to fire your gun.
Lastly, you need to find what bullet power to fire your gun. The original calculations were done for a bullet power of 0.15; you need to adjust the power to make your own bullet's displacement intercept at its midpoint also. You don't actually need to perform this step a frame ahead like the rest of the calculations, because it isn't necessary to know the power beforehand; this step can be performed when you are firing. To do this, divide the distance from your position to the intercept coordinates by the calculated parameter (rounded to nearest 0.5) above. This will give you the speed your bullet will need to travel; simply use the speed formula backwards to find the power you need to fire. Voila!
The bullets should now collide at the midpoints of their last displacements. This is the complete algorithm for bullet shielding; the intercept recalculation gives you the most chance to intercept an enemy bullet. With this, you can protect the most of your robot by maximizing the enemy angle you intercept.