From Robowiki
Jump to navigation Jump to search

Author(s) Skotty
Extends AdvancedRobot
Targeting Bullet_Shielding
Movement None
Released 2013-2-19 (v 1.0)
Best Rating #535 (v 1.3.2)
Current Version 1.4
Code Size 32,572
Code License GCWCD


Spitfire is a robot that only uses bullet shielding. It provides an interesting point of reference for the technique, and also serves as a base for the bullet shielding mode in my robot XanderCat. It is built on top of my Xander Framework, which makes it's size rather large, but also made it easy for me to develop.

Spitfire does not fire unless fired upon. This generally results in poor scores against other robots who do not fire or who wait for Spitfire to fire first.

Spitfire will fire a head-on shot against disabled opponents to finish them off.

Spitfire never moves, with the exception of a very slight twitch against stationary opponents to ensure shielding works properly.

Version Notes

Version 1.1

  • Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.
  • Fix bug that was causing Spitfire to not shoot against some opponents.

Version 1.2

Framework Updates

  • Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet.

Spitfire Updates

  • Allow bullet power to go up to 1.5 for better shielding coverage. Limitations: bullet power used will not exceed the power of the bullet being shielded; bullet power will not exceed minimum if opponent has more energy.

Version 1.3

  • Add ability to to shield against multiple targeting methods.
  • Add secondary guess on opponent targeting method.

Version 1.3.1

  • Move less when shielding against stationary opponent. Previous movement was apparently too much; enough to cause a shift in opponent aim.

Version 1.3.2

  • Further reduce move distance when shielding against stationary opponent by a factor of 25.

Version 1.4

Framework Updates:

  • Reworked how opponent gun fire detection works when opponent has collision with wall. If opponent is assumed to have gun heat remaining, assume no bullet was fired unless the previous shot happened on a known collision. A known collision is any time a velocity change exceeds the maximum deceleration rate. If no heat remaining on a known collision, assume a bullet was fired, but skip the gun heat check the next time an energy drop is detected. There is no way to know for sure what the bullet power is, so assume the bullet power is the same as the previous shot. The following possible errors remain from this approach:
    • A slow collision when gun heat is 0 will not be detected as a collision. This will result in a false wave. Furthermore, the next real wave will likely be missed as the system will assume a shot could not have been fired due to assumed gun heat remaining after the previous wave.
    • A correctly detected collision when gun heat is 0 will assume a bullet of the previous fire power has been fired. It may be that no bullet was fired, or possibly a bullet with a different firepower. I don't see any way to resolve this. However, the next wave should not get missed if no bullet or a lower power bullet was fired because the system skips the gun heat check for the next wave after a collision.
  • Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.
  • Updated Graph Data and CPU Utilization painting to allow graph to be resized, fix a bug in the data end points, and allow CPU constant to be graphed.

Spitfire Updates:

  • Add workaround for rare bug where bullet shielding system gets stuck with the drive in the Firing state but the gun requesting a wave to shield against. Previously the controller would just return null when a wave was requested if the drive wasn't in Standing state. This is now updated so that if a wave is requested when the drive is in Firing state, the controller requests the drive return to Standing state (normally this happens when the gun fires, but somehow this fails on rare occasions).
  • Update move to standing steps in the drive to immediately switch to Standing state if the drive shift was 0. This saves an extra tick on most shielding shots. This was previously done for the move to firing step, but was previously overlooked for the move back to standing.

Example Code

The main robot class; short and sweet:

public class Spitfire extends AbstractXanderRobot {

	protected void configure(Configuration configuration) {

	protected void addComponents(ComponentChain componentChain) {
		componentChain.addDefaultComponents(new BasicRadar(45, 3));
		BulletShieldingFactory.addBulletShieldingComponentsAsDefault(componentChain, 0.1d);	

Above, the call setAutoFireOnDisabledOpponents seems a little backwards, as Spitfire does fire on disabled opponents. The Xander Framework auto-fire functionality (which this setting turns on and off) is set up to fire a head-on shot immediately on a disabled opponent. However, with Spitfire, it needs to be sure that all opponent shots have been shielded before firing on a disabled opponent. For now, I just handle this in the bullet shielding gun. In the future, I may update the framework to make this a little more configurable to handle either approach.

Below, a look at the BulletShieldingFactory method for setting up the bullet shielding components:

public static void addBulletShieldingComponentsAsDefault(ComponentChain chain, double maxAdjustedFirePower) {
	BulletShieldingDrive bulletShieldingDrive = new BulletShieldingDrive();
	BulletShieldingController bulletShieldingController 
		= new BulletShieldingController(bulletShieldingDrive);
	BulletShieldingGun bulletShieldingGun = null;
	if (maxAdjustedFirePower < RCPhysics.MIN_FIRE_POWER) {
		bulletShieldingGun = new BulletShieldingGun(bulletShieldingController, getCommonBulletTargeters());
	} else {
		bulletShieldingGun = new BulletShieldingGun(bulletShieldingController, maxAdjustedFirePower, getCommonBulletTargeters());
	chain.addDefaultComponents(bulletShieldingDrive, bulletShieldingGun);		

My current design uses a "controller" to deal with tracking shots, and it serves as an intermediary between the drive and gun. The gun requests waves from the controller, and the controller tells the drive what to do and lets the gun know when it's okay to fire.

For v1.0, I'm not utilizing the max adjusted fire power functionality. I just always use 0.1 shots. If I ever turn it on, it will vary the fire power up to the given amount in an attempt to improve the shielding overlap.