http://robowiki.net/w/api.php?action=feedcontributions&user=Skotty&feedformat=atomRobowiki - User contributions [en]2024-03-28T10:19:24ZUser contributionsMediaWiki 1.34.1http://robowiki.net/w/index.php?title=XanderFramework&diff=36381XanderFramework2017-04-16T17:01:44Z<p>Skotty: /* Events */ updated notes for framework v3.0</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Version Notes ==<br />
<br />
Some interesting notes about each version of the framework.<br />
<br />
=== Version 1.0 ===<br />
<br />
Version 1.0 had the basics complete, but lacked some of the more advanced functionality like tracking wave history.<br />
<br />
=== Version 2.0 ===<br />
<br />
Version 2.0 added more advanced functionality like wave history and has been the main version from about 2013 up through 2017. Version 2.0 was tailored primarily for 1 vs 1 combat, and had certain deficiencies when attempting to use it for other purposes. It was structured to have 1 of each framework component, and only some of them were written to accommodate more than 1 opponent on the battlefield.<br />
<br />
=== Version 3.0 ===<br />
<br />
Version 3.0 is under development in 2017. It's purpose is to add full melee or multi-opponent support, simplify some of the code, reduce code size, and improve performance in a few areas. Version 3.0 takes on a new component strategy where some components that can apply to a single robot now only apply to a single robot. This means some main framework components will now have 1 instance for each known robot, instead of a single instance that must handle all robots. One of the challenges with this approach is that robot specific opponents are now generated as knowledge of their existence is gained, instead of existing from the very beginning of the battles. This is a challenge because you can no longer always fully construct your robot at the very beginning, because some parts must be created or expanded as new robots are scanned. The framework is being rewritten to support this in as convenient a fashion as possible.<br />
<br />
The main framework components that will now have 1 for every robot (including self) include the SnapshotHistory, WaveHistory, and GunStats components.<br />
<br />
Any listeners for robot specific components (anything that implements WaveListener, ScannedRobotListener, etc) must now implement an additional method getOpponentFocus() that tells the framework what robots to associate the component with. Focus options include:<br />
* ALL_ROBOTS: Component will receive events for all robots.<br />
* TARGETED_ROBOT: Component will only receive events from the currently targeted robot (the targeted robot determined by what your radar is returning).<br />
* SPECIFIC_ROBOT_SCANNED: Component will only receive events for one specific robot. That robot will be the last scanned robot at time listener is added, or the next scanned robot if there is no last scanned robot.<br />
* SPECIFIC_ROBOT_TARGETED: Component will only receive events for one specific robot. That robot will be the last targeted robot at time listener is added, or the next targeted robot if there is no current target.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events accessed through the RobotEvents class (v3.0):<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Opponent Focusable?<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| Yes<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| No<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| WaveListener<br />
| Yes<br />
| Handles events related to a robot's bullet waves. The WaveHistory stores two sets of WaveListeners, one for actual bullet waves, and one for virtual bullet waves. If listening for both, you can tell the difference between the two by the Wave method isVirtual().<br />
|-<br />
| Painter <br />
| No<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| No<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| No<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| Yes<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| Yes<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| No<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderFramework&diff=36380XanderFramework2017-04-16T16:58:50Z<p>Skotty: /* Events */</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Version Notes ==<br />
<br />
Some interesting notes about each version of the framework.<br />
<br />
=== Version 1.0 ===<br />
<br />
Version 1.0 had the basics complete, but lacked some of the more advanced functionality like tracking wave history.<br />
<br />
=== Version 2.0 ===<br />
<br />
Version 2.0 added more advanced functionality like wave history and has been the main version from about 2013 up through 2017. Version 2.0 was tailored primarily for 1 vs 1 combat, and had certain deficiencies when attempting to use it for other purposes. It was structured to have 1 of each framework component, and only some of them were written to accommodate more than 1 opponent on the battlefield.<br />
<br />
=== Version 3.0 ===<br />
<br />
Version 3.0 is under development in 2017. It's purpose is to add full melee or multi-opponent support, simplify some of the code, reduce code size, and improve performance in a few areas. Version 3.0 takes on a new component strategy where some components that can apply to a single robot now only apply to a single robot. This means some main framework components will now have 1 instance for each known robot, instead of a single instance that must handle all robots. One of the challenges with this approach is that robot specific opponents are now generated as knowledge of their existence is gained, instead of existing from the very beginning of the battles. This is a challenge because you can no longer always fully construct your robot at the very beginning, because some parts must be created or expanded as new robots are scanned. The framework is being rewritten to support this in as convenient a fashion as possible.<br />
<br />
The main framework components that will now have 1 for every robot (including self) include the SnapshotHistory, WaveHistory, and GunStats components.<br />
<br />
Any listeners for robot specific components (anything that implements WaveListener, ScannedRobotListener, etc) must now implement an additional method getOpponentFocus() that tells the framework what robots to associate the component with. Focus options include:<br />
* ALL_ROBOTS: Component will receive events for all robots.<br />
* TARGETED_ROBOT: Component will only receive events from the currently targeted robot (the targeted robot determined by what your radar is returning).<br />
* SPECIFIC_ROBOT_SCANNED: Component will only receive events for one specific robot. That robot will be the last scanned robot at time listener is added, or the next scanned robot if there is no last scanned robot.<br />
* SPECIFIC_ROBOT_TARGETED: Component will only receive events for one specific robot. That robot will be the last targeted robot at time listener is added, or the next targeted robot if there is no current target.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events (v3.0):<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Events Issued By (Register With)<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| RobotEvents<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| RobotEvents<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| WaveListener<br />
| RobotEvents<br />
| Handles events related to a robot's bullet waves. The WaveHistory stores two sets of WaveListeners, one for actual bullet waves, and one for virtual bullet waves. If listening for both, you can tell the difference between the two by the Wave method isVirtual().<br />
|-<br />
| Painter <br />
| RobotEvents<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| RobotEvents<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| RobotEvents<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| RobotEvents<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| RobotEvents<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| RobotEvents<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderFramework&diff=36379XanderFramework2017-04-16T16:55:22Z<p>Skotty: /* Version 3.0 */ added some info on how robot focus works for events</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Version Notes ==<br />
<br />
Some interesting notes about each version of the framework.<br />
<br />
=== Version 1.0 ===<br />
<br />
Version 1.0 had the basics complete, but lacked some of the more advanced functionality like tracking wave history.<br />
<br />
=== Version 2.0 ===<br />
<br />
Version 2.0 added more advanced functionality like wave history and has been the main version from about 2013 up through 2017. Version 2.0 was tailored primarily for 1 vs 1 combat, and had certain deficiencies when attempting to use it for other purposes. It was structured to have 1 of each framework component, and only some of them were written to accommodate more than 1 opponent on the battlefield.<br />
<br />
=== Version 3.0 ===<br />
<br />
Version 3.0 is under development in 2017. It's purpose is to add full melee or multi-opponent support, simplify some of the code, reduce code size, and improve performance in a few areas. Version 3.0 takes on a new component strategy where some components that can apply to a single robot now only apply to a single robot. This means some main framework components will now have 1 instance for each known robot, instead of a single instance that must handle all robots. One of the challenges with this approach is that robot specific opponents are now generated as knowledge of their existence is gained, instead of existing from the very beginning of the battles. This is a challenge because you can no longer always fully construct your robot at the very beginning, because some parts must be created or expanded as new robots are scanned. The framework is being rewritten to support this in as convenient a fashion as possible.<br />
<br />
The main framework components that will now have 1 for every robot (including self) include the SnapshotHistory, WaveHistory, and GunStats components.<br />
<br />
Any listeners for robot specific components (anything that implements WaveListener, ScannedRobotListener, etc) must now implement an additional method getOpponentFocus() that tells the framework what robots to associate the component with. Focus options include:<br />
* ALL_ROBOTS: Component will receive events for all robots.<br />
* TARGETED_ROBOT: Component will only receive events from the currently targeted robot (the targeted robot determined by what your radar is returning).<br />
* SPECIFIC_ROBOT_SCANNED: Component will only receive events for one specific robot. That robot will be the last scanned robot at time listener is added, or the next scanned robot if there is no last scanned robot.<br />
* SPECIFIC_ROBOT_TARGETED: Component will only receive events for one specific robot. That robot will be the last targeted robot at time listener is added, or the next targeted robot if there is no current target.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events:<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Events Issued By (Register With)<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| RobotEvents<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| RobotEvents<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| WaveListener<br />
| WaveHistory<br />
| Handles events related to a robot's bullet waves. The WaveHistory stores two sets of WaveListeners, one for actual bullet waves, and one for virtual bullet waves. If listening for both, you can tell the difference between the two by the Wave method isVirtual().<br />
|-<br />
| Painter <br />
| RobotEvents<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| RobotEvents<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| RobotEvents<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| RobotEvents<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| RobotEvents<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| RobotEvents<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderFramework&diff=36376XanderFramework2017-04-13T21:38:14Z<p>Skotty: Add some notes about different versions of the framework</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Version Notes ==<br />
<br />
Some interesting notes about each version of the framework.<br />
<br />
=== Version 1.0 ===<br />
<br />
Version 1.0 had the basics complete, but lacked some of the more advanced functionality like tracking wave history.<br />
<br />
=== Version 2.0 ===<br />
<br />
Version 2.0 added more advanced functionality like wave history and has been the main version from about 2013 up through 2017. Version 2.0 was tailored primarily for 1 vs 1 combat, and had certain deficiencies when attempting to use it for other purposes. It was structured to have 1 of each framework component, and only some of them were written to accommodate more than 1 opponent on the battlefield.<br />
<br />
=== Version 3.0 ===<br />
<br />
Version 3.0 is under development in 2017. It's purpose is to add full melee or multi-opponent support, simplify some of the code, reduce code size, and improve performance in a few areas. Version 3.0 takes on a new component strategy where some components that can apply to a single robot now only apply to a single robot. This means some main framework components will now have 1 instance for each known robot, instead of a single instance that must handle all robots. One of the challenges with this approach is that robot specific opponents are now generated as knowledge of their existence is gained, instead of existing from the very beginning of the battles. This is a challenge because you can no longer always fully construct your robot at the very beginning, because some parts must be created or expanded as new robots are scanned. The framework is being rewritten to support this in as convenient a fashion as possible.<br />
<br />
The main framework components that will now have 1 for every robot (including self) include the SnapshotHistory, WaveHistory, and GunStats components.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events:<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Events Issued By (Register With)<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| RobotEvents<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| RobotEvents<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| WaveListener<br />
| WaveHistory<br />
| Handles events related to a robot's bullet waves. The WaveHistory stores two sets of WaveListeners, one for actual bullet waves, and one for virtual bullet waves. If listening for both, you can tell the difference between the two by the Wave method isVirtual().<br />
|-<br />
| Painter <br />
| RobotEvents<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| RobotEvents<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| RobotEvents<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| RobotEvents<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| RobotEvents<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| RobotEvents<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderFramework&diff=36375XanderFramework2017-04-08T23:44:36Z<p>Skotty: /* Events */ Some v3.0 updates</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events:<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Events Issued By (Register With)<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| RobotEvents<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| RobotEvents<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| WaveListener<br />
| WaveHistory<br />
| Handles events related to a robot's bullet waves. The WaveHistory stores two sets of WaveListeners, one for actual bullet waves, and one for virtual bullet waves. If listening for both, you can tell the difference between the two by the Wave method isVirtual().<br />
|-<br />
| Painter <br />
| RobotEvents<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| RobotEvents<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| RobotEvents<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| RobotEvents<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| RobotEvents<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| RobotEvents<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderFramework&diff=36374XanderFramework2017-04-08T23:40:30Z<p>Skotty: Updated with some framework v3.0 notes</p>
<hr />
<div>= Xander Framework =<br />
<br />
The Xander framework is an AdvancedRobot framework that makes it easy to build new bots by combining different guns, radars, and drives. It is based on an abstract class named AbstractXanderRobot that extends AdvancedRobot. All basic framework classes are in the package xander.core. As an optional add-on to the framework, some more advanced yet less mature guess factor and wave surfing classes are in package xander.gfws. When looking at any of my Xander robots, anything outside of the xander.core and xander.gfws packages are components built for the Xander framework, not part of the Xander framework itself.<br />
<br />
With a Xander robot, the main robot class need only set up a ''component chain'' populated with your guns, radars, and drives. It can also optionally override methods to change basic configuration options and write battle statistics to disk.<br />
<br />
Guns, radars, and drives must use the corresponding framework interfaces and can make use of a variety of framework resources and events.<br />
<br />
The current framework version available for the last few years is considered v2.0. Version 3.0 is current in development. Version 3.0 brings several advancements over the older version through a revised component structure, including:<br />
* Full melee support.<br />
* Simplified components, but without losing any prior functionality.<br />
* Reduced code size.<br />
* Improved performance.<br />
<br />
== Base Robot Class == <br />
Xander robots extend the '''AbstractXanderRobot''' class, which in turn extends the Robocode '''AdvancedRobot''' class. The '''AbstractXanderRobot''' class contains basic robot setup code and a basic processing loop. <br />
<br />
'''The basic setup code performs as follows:'''<br />
* set all setXxxForRobotXxx values to true.<br />
* if first round:<br />
** call configure(Configuration)<br />
** call style(RobotStyle)<br />
** initialize Resources<br />
** call addComponents(ComponentChain)<br />
* apply robot styling (done every round in case win code changes styling)<br />
* issue round begin event<br />
<br />
'''The basic processing loop performs as follows:'''<br />
* issue turn begin event<br />
* Process component chain to select radar, drive, and gun<br />
* Query radar for target<br />
* If no target is locked...<br />
** Tell drive to drive without a target<br />
* Otherwise...<br />
** Tell drive to drive with given target<br />
** If target is disabled and configuration allows...<br />
*** Fire on target with Head-On gun<br />
** Otherwise...<br />
*** Fire on target with gun<br />
* issue turn end event<br />
* call execute()<br />
<br />
'''A Xander robot ''must'' implement the following methods:'''<br />
* addComponents(ComponentChain) - for setting up component chain<br />
<br />
'''In addition, a Xander robot may optionally override the following methods:'''<br />
* void configure(Configuration) - allows basic configuration of the robot to be changed<br />
* void style(RobotStyle) - allows setting styling options like robot colors<br />
* boolean recordBattleStats(Map<String, String>) - allows robot to save battle statistics to file; key is statistic name, value is statistic value as String. Statistics are saved in the '''BattleStats''' class which is written to file as a Java object using an ObjectOutputStream.<br />
<br />
== Components / Component Chain ==<br />
In a Xander robot, guns, drives, and radars are referred to as ''components''. Components are managed within a ''component chain'' represented by the '''ComponentChain''' class. The component chain follows the general concepts of the ''Chain of Responsibility'' design pattern. It consists of a series of '''ComponentScenario''' objects that are responsible for selecting a radar, drive, and gun to use for each turn. The chain is followed from the beginning to the end, each '''ComponentScenario''' passing off to the next, until a radar, drive, and gun have all been selected for the current turn.<br />
<br />
The component chain is set up at the beginning of the first round by a call to the abstract method <pre>addComponents(ComponentChain)</pre>. Each link in the chain has a '''Scenario''' that is responsible for deciding whether or not the components for that link should be used or not. This design makes it easy to handle situations where more than one component should be used in combination. All specialized scenarios should be set up by calls to <pre>addComponents(...)</pre>, while main or default components to be used when no specialized scenario applies should be set up by a call to <pre>addDefaultComponents(...)</pre>.<br />
<br />
'''Example:'''<br />
<br />
Assume you have a mainRadar, mainDrive and mainGun for a robot. Assume you also have a ramDrive and ramGun that should be used together against robots who use a ramming strategy. For this, a Scenario ramScenario could be written to test if a robot is using a ramming strategy. The component chain would then be set up as follows:<br />
<pre><br />
protected void addComponents(ComponentChain chain) {<br />
...<br />
chain.addComponents(ramScenario, ramDrive, ramGun);<br />
chain.addDefaultComponents(mainRadar, mainDrive, mainGun);<br />
}<br />
</pre><br />
<br />
== Resources ==<br />
Classes within a Xander robot have easy access to a number of resources which can be accessed through the '''Resources''' class. <br />
<br />
=== DriveStats ===<br />
Statistics related to the drives of your robot, such as drive time usage.<br />
<br />
=== GunStats ===<br />
Statistics related to the guns, including hit ratios and virtual gun hit ratios. As of v3.0, one GunStats will be created for each robot in the battle.<br />
<br />
=== RobotEvents ===<br />
Manages all major event listeners, including all of the repackaged AdvancedRobot events. <br />
<br />
=== RobotProxy ===<br />
Access to all robot getXxx methods outside of the main robot class itself should be accessed via the RobotProxy object. <br />
<br />
=== SnapshotHistory ===<br />
Robot history is available through the '''SnapshotHistory'''. Robot history for a particular point in time is stored in a ''snapshot'' via the '''Snapshot''' class, an immutable snapshot of a robot at a particular point in time. As of v3.0, One SnapshotHistory will be created for each robot in the battle.<br />
<br />
Each turn, a Xander robot takes a new snapshot for itself and stores it in the history. Each scan, a new snapshot for the scanned robot is generated and stored in the history. Robot history allows the robot to look back at snapshots of itself and it's opponents back a set number of turns and scans.<br />
<br />
=== WaveHistory ===<br />
History of all bullet waves. As of v3.0, one WaveHistory is created for each robot.<br />
<br />
== Controllers ==<br />
Radars, guns, and drives control the robot through ''controller'' classes. The controllers for radar, gun, and drive provide access to the radar, gun, and drive related setXxx methods of the robot. This approach helps to prevent components from doing operations that are outside their area of responsibility, and also prevents components from calling the basic '''Robot''' control methods, or any methods that would immediately cause a turn to end. Controllers may also have other helper methods. <br />
<br />
== Radar ==<br />
Radars must implement the '''Radar''' interface. In a Xander robot, the radar is responsible for operating the radar and selecting a Snapshot of a robot for the drive and gun to focus on.<br />
<br />
<pre><br />
public interface Radar extends Component {<br />
<br />
/**<br />
* Prepare next sweep of radar and return snapshot of robot currently<br />
* being focused upon.<br />
* <br />
* @param radarController radar controller<br />
* <br />
* @return snapshot of robot to attack<br />
*/<br />
public Snapshot search(RadarController radarController);<br />
}<br />
</pre><br />
<br />
== Drive ==<br />
Drives must implement the '''Drive''' interface.<br />
<br />
<pre><br />
public interface Drive extends Component {<br />
<br />
/**<br />
* Drive into optimal firing range of the given robot.<br />
* <br />
* @param opponentSnapshot robot to drive against<br />
* @param driveController drive controller<br />
*/<br />
public void driveTo(Snapshot opponentSnapshot, DriveController driveController);<br />
<br />
/**<br />
* Drive without any specific target.<br />
* <br />
* @param driveController drive controller<br />
*/<br />
public void drive(DriveController driveController);<br />
}<br />
</pre><br />
<br />
=== Drive Array ===<br />
<br />
In cases were the robot should choose between a variety of drives based on some common criteria, a ''drive array'' can be set up using the '''DriveArray''' class. A drive array must have a ''drive selector'', defined by the '''DriveSelector''' interface.<br />
<br />
== Gun ==<br />
Guns must implement the '''Gun''' interface. However, rather than creating a gun class and directly implementing the gun interface, the recommended approach for a Xander robot is to use the '''XanderGun''' class. The '''XanderGun''' class relies on two other interfaces: '''Targeter''' and '''PowerSelector'''. A '''PowerSelector''' decides on what fire power to use, while the '''Targeter''' determines how to aim the gun based on what the bullet velocity will be. When using a '''XanderGun''', you create classes that implement '''Targeter''' and '''PowerSelector''', and the XanderGun takes care of the rest, including:<br />
* Preparing information for self and target. This takes the latest snapshots and predicts them one turn into the future (necessary for a more accurate aim due to how the Robocode processing loop operates), and passes those to the '''Targeter''' for aiming.<br />
* Calling the setXxx methods to aim the gun and fire bullets.<br />
* Auto-adjusting the fire power for low energy situations (so long as the '''PowerSelector''' allows it). Fire power is modified based on the current state of the target and self. Power selection steps are as follows:<br />
** Get preferred fire power from the '''PowerSelector'''.<br />
** If power is more than is required to kill the target, reduce firepower to what is needed for a kill.<br />
** If target is not disabled and firing bullet would disable self, reduce firepower such that it will not disable self.<br />
<br />
<pre><br />
public interface Gun extends Component {<br />
<br />
/**<br />
* Aim and fire upon the given opponent. Since guns are also required<br />
* to have the getFiringVector method, this method can generally call that <br />
* method to get the aim. The only extra work in this method is <br />
* actually turning the gun and firing.<br />
* <br />
* @param target snapshot of opponent<br />
* @param myself snapshot of self<br />
* @param gunController gun controller<br />
* <br />
* @return whether or not a bullet was fired<br />
*/<br />
public boolean fireAt(Snapshot target, Snapshot myself, GunController gunController);<br />
<br />
/**<br />
* Returns the aim information for the given opponent. <br />
* <br />
* @param target the opponent to target<br />
* @param myself snapshot of self<br />
* <br />
* @return aim information for the given opponent<br />
*/<br />
public Aim getAim(Snapshot target, Snapshot myself);<br />
<br />
/**<br />
* Returns whether or not this can is currently capable of aiming and <br />
* firing on the given robot. This method should be lightweight (most<br />
* guns should just return true).<br />
* <br />
* @param target snapshot of robot to fire at<br />
* <br />
* @return whether or not gun can fire on opponent<br />
*/<br />
public boolean canFireAt(Snapshot target);<br />
}<br />
</pre><br />
<br />
=== Gun Array ===<br />
<br />
In cases were the robot should choose between a variety of guns based on some criteria, a ''gun array'' can be set up using the '''GunArray''' class. A gun array must have a ''gun selector'', defined by the '''GunSelector''' interface. A gun array can be set up to fire virtual bullets. <br />
<br />
Historical Note: The GunArray operates much like the CompoundGun of the Xander 1.0 framework. However, it is no longer intended for the construction of ''trees'' (though technically it is still possible to create one). For the Xander 2.0 framework, most component selections are expected to be handled by the ''component chain''.<br />
<br />
== Events ==<br />
Robocode issues a number of different events to the robot. A Xander framework robot repackages these events and also provides other custom events, and makes those available to other components. Xander robots can make use of the following events:<br />
{| border="1" cellpadding="4"<br />
! Listener Class<br />
! Events Issued By (Register With)<br />
! Purpose<br />
|-<br />
| BulletHitListener<br />
| RobotEvents<br />
| Repackages Robocode events onHitByBullet, onBulletHit, onBulletMissed, and onBulletHitBullet<br />
|-<br />
| CollisionListener <br />
| RobotEvents<br />
| Repackages Robocode events onHitRobot and onHitWall<br />
|-<br />
| MyWaveListener<br />
| WaveHistory<br />
| Handles events related to the robot's own bullet waves. Actual bullets only.<br />
|-<br />
| MyVirtualWaveListener<br />
| WaveHistory<br />
| Handles events related to the robot's own virtual bullet waves. Virtual gun bullets only.<br />
|-<br />
| OpponentWaveListener<br />
| WaveHistory<br />
| Handles events related to the opponents bullet waves.<br />
|-<br />
| Painter <br />
| RobotEvents<br />
| Repackages Robocode event onPaint, allowing other components to paint on the battlefield<br />
|-<br />
| RoundBeginListener<br />
| RobotEvents<br />
| Handler for a single event that fires at the beginning of every round. Can be used to initialize variables when a round begins.<br />
|-<br />
| RoundListener<br />
| RobotEvents<br />
| Repackages Robocode events onRoundEnd and onBattleEnd<br />
|-<br />
| ScannedRobotListener <br />
| RobotEvents<br />
| Repackages Robocode event onScannedRobot<br />
|-<br />
| SurvivalListener<br />
| RobotEvents<br />
| Repackages Robocode events onWin, onDeath, and onRobotDeath<br />
|-<br />
| TurnListener <br />
| RobotEvents<br />
| Handler for events that fire on every iteration of the AbstractXanderRobot main processing loop. One event that fires at the beginning of a turn, and one event that fires at the end of a turn immediately before execute() is called.<br />
|}<br />
<br />
= Xander Utilities =<br />
<br />
== Logging ==<br />
<br />
The Xander framework provides basic logging services loosely based on the Log4J logging model. Though not nearly as configurable as Log4J logging, it is much more advanced than just using System.out.print statements.<br />
<br />
Xander logs have the following levels, in order of significance:<br />
* DEBUG - Debugging messages.<br />
* INFO - Informational messages. This is the default logging level.<br />
* WARNING - Warning messages. <br />
* STAT - Statistics messages. These are meant to be messages that are useful during development, but also of interest for a finished robot.<br />
* ERROR - Error messages.<br />
<br />
Log levels are defined by the nested Enum named Level in the Log class (e.g. the level INFO would be accessed via Log.Level.INFO)<br />
<br />
Logging consists of two classes: Logger and Log. Each class can have it's own Log. A Log is created by the Logger. <br />
<br />
A Log can currently be created in a manner similar to as follows:<br />
<pre><br />
public class ExampleClass {<br />
<br />
private static final Log log = Logger.getLog(ExampleClass.class);<br />
<br />
}<br />
</pre><br />
Once created, it can be used by calling the appropriate methods of the Log class as in the following example:<br />
<pre><br />
log.info("This is an informational message.");<br />
</pre><br />
Similar to Log4J, log messages will only be printed if the level of the message is at or above the level set in the Log. By default, all Logs are at level INFO. This can be changed globally on startup through the Logger class, or on a Log by Log basis.<br />
<br />
== Mathematics ==<br />
<br />
=== RCMath ===<br />
This class provides generic math helper functions. Most are targeted at solving Robocode problems, but are still usable in a more generic sense. <br />
<br />
=== RCPhysics ===<br />
This class provides constants and methods that are only useful within the context of Robocode physics. Some of what it provides is obsolete due to various additions to the Robocode API over the last few years -- specifically the Robocode Rules and Utils classes -- but I leave it there for posterity.<br />
<br />
== CPU Utilization ==<br />
The Xander framework also provides a few ways to track processing time.<br />
=== RunTimeLogger ===<br />
Provides an easy-to-use means for testing average and peak run times for any particular block of code. Results are logged to the console at the end of each round.<br />
=== CPU Utilization Painting ===<br />
CPU utilization can be graphed on screen by setting the ''drawCPUUtilization'' flag to true in the '''Configuration'''.<br />
<br />
= Guess Factors and Wave Surfing =<br />
At the fringe of the framework are a variety of classes for handling guess factors and wave surfing. These classes are in package xander.gfws. This package might be best described as an add-on to the framework, and is somewhat less mature than the core framework.<br />
<br />
== Factor Array Processors ==<br />
<br />
A ''factor array processor'', defined by the '''FactorArrayProcessor''' interface, is responsible providing factor arrays for waves. Originally, they were also meant to handle logging wave data, but some of the latest implementations let other classes handle logging data.<br />
<br />
The '''AbstractFactorArrayProcessor''' provides a basic implementation of this interface designed to work in both guess factor guns and and wave surfing drives. This is an older implementation that is intended to handle logging data in addition to building factor arrays.<br />
<br />
== Distributers ==<br />
<br />
A ''distributer'', defined by the '''WeightDistributer''' interface, is responsible for distributing a set amount of weight into a factor array.<br />
<br />
Current available distributers include:<br />
* '''PointDistributer''' - dumps all weight onto a single index.<br />
* '''TriangleDistributer''' - weight is logged into a triangular region whose base width, by default, is equivalent to the width of the robot.<br />
* '''WaveDistributer''' - weight is logged across the entire factor range, with weight decreasing exponentially the further it gets from the hit index.<br />
<br />
== Segmentation ==<br />
<br />
Wave surfing drives and guess factor guns can use segmenters. Basic segmenters must implement the '''Segmenter''' interface. There is also an '''AbstractSegmenter''' class for simple segmenters that operate on values within a fixed range.<br />
<br />
Current available segmenters include:<br />
* '''AttackerBearingSegmenter''' - segments on the attacker's bearing from the back-as-front heading of the defender<br />
* '''BulletTravelTimeSegmenter''' - segments on bullet travel time<br />
* '''DefenderAccelerationSegmenter''' - segments on defender acceleration<br />
* '''DefenderSpeedSegmenter''' - segments on defender speed<br />
* '''LateralVelocitySegmenter''' - segments on defender lateral velocity<br />
* '''NullSegmenter''' - provides no segmentation (a segmenter with only a single segment).<br />
* '''WallSmoothingSegmenter''' - segments on whether it appears defender will have to wall smooth clockwise, counter-clockwise, both directions (in corner), or not at all.<br />
* '''WallStickSegmenter''' - segments on opponent distance to wall in the forward or reverse direction of the defenders current direction.<br />
<br />
== Utilities ==<br />
<br />
A '''FactorArrays''' utility class provides static methods for common factor array functions such as converting between factor angles and factor indexes.<br />
<br />
== Drives ==<br />
<br />
The '''DirectWaveSurfingDrive''' (named '''DWaveSurfingDrive''' in v9.3 of XanderCat) class provides the basic implementation for a ''direct'' wave surfing drive, relying on a ''direct surf selector'' to choose the factor angle and direct heading to use for each wave. Surf selectors are defined by the '''DirectSurfSelector''' interface.<br />
<br />
This drive is capable of surfing 2 waves at once, though only surfs a single wave by default. It is a Go-To style wave surfing drive, but will reprocess where to go on the same wave under the following situations:<br />
* when surf wave is updated (such as when a newly fired bullet creates new bullet shadows)<br />
* when opponent position deviates significantly from prediction. This is done primarily for the sake of distancing.<br />
<br />
The xander.gfws package does not provide any surf selector implementations. However, XanderCat 9.3+ uses a surf selector named '''GreenBeeSurfSelector''' which other surf selectors might be modeled from. It uses a ''factor array processor'' for managing the drive data, along with a '''DirectDrivePredictor''' and '''DistancingEquation''' from the Xander core classes to aid in choosing what direction to move in.<br />
<br />
== Guns ==<br />
<br />
The '''GuessFactorTargeter''' class provides the basic implementation of a guess factor targeter, and utilizes a ''factor array processor'' and ''weight distributer'' for it's operation.<br />
<br />
= Components Built on Xander =<br />
The components listed in this section are not considered part of the Xander framework core; they are example components built for the Xander framework that I use in my various robots. Exceptions to this are the '''HeadOnTargeter''', as it is used by a Xander framework core class and must therefore be considered part of the framework.<br />
<br />
== Xander Radars ==<br />
<br />
=== BasicRadar ===<br />
Basic radar scan the field, and locks onto the first target it finds. Target can switch if another robot happens to be closer and drives through the scan beam.<br />
<br />
== Xander Guns and Targeters ==<br />
<br />
=== AntiMirrorGun ===<br />
Specifically for targeting opponents who use a mirroring drive strategy. Must be used in combination with the '''AntiMirrorDrive'''.<br />
=== BSProtectedGun ===<br />
A wrapper for other guns that provides support for counteracting bullet shielding.<br />
=== CircularTargeter ===<br />
This targeter is for targeting opponents that drive in circles. If the opponent does not appear to be going in circles, this gun will not fire on the target. One advantage this gun has over some other circular targeting implementations is that it works for circular paths that are centered anywhere, and is not limited to circular paths centered at the location bullet wave was fired from. This gun pulverizes SpinBot.<br />
<br />
=== HeadOnTargeter ===<br />
Head-on shots.<br />
=== LinearTargeter ===<br />
This targeter is for targeting opponents that drive in a straight line. It fires on the opponent based on the opponents current speed and heading. It does not attempt to determine whether the target is actually moving in a straight line or not, but does compensate for battlefield bounds (don't shoot off the grid). The linear intercept calculation is precise (not iterative nor an approximation).<br />
<br />
== Xander Drives ==<br />
<br />
=== AntiMirrorDrive ===<br />
Drive specifically for use with opponents who use a mirroring drive strategy. This drive must be used in combination with the '''AntiMirrorGun'''.<br />
<br />
=== BasicSurferDrive ===<br />
This drive is an adaptation of the Wave Surfing drive used in the BasicGFSurfer robot.<br />
<br />
=== GreenBeeSurfSelector ===<br />
This class is a ''direct surf selector'' which can be used in a '''DirectWaveSurfingDrive'''. It utilizes a ''factor array processor'' for managing data and building a factor array to surf. It also utilizes the '''DirectDrivePredictor''' and '''DistancingEquation''' classes from the Xander core in it's operation. <br />
<br />
The basic steps in it's operation are:<br />
# Create two sets of test drive angles, one for clockwise, one for counter-clockwise.<br />
# Determine greatest reachable factors and end positions when driving at each test angle.<br />
# Reduce the set of test angles to consider based on the distancing provided by the '''DistancingEquation'''.<br />
# Determine greatest reachable factor range after distancing is applied.<br />
# If reachable factor range after distancing is applied is too constricted, expand the test range back out until it is not.<br />
# Use the '''FactorArrayProcessor''' to get the factor array to surf.<br />
# Choose which factor angle to move to in the surf array.<br />
# Choose test angle that optimizes distancing while still reaching the chosen factor angle for the wave.<br />
<br />
=== IdealPositionDrive ===<br />
Attempts to ideally position the robot on the battlefield. This should only be used when no enemy bullets are in play.<br />
<br />
=== RamEscapeDrive ===<br />
For getting away from needy robots who always want a hug.<br />
<br />
= Xander Code Examples =<br />
<br />
== Example Robot Class ==<br />
<br />
Stripped version of XanderCat main robot class (some content removed to provide simplified example):<br />
<pre><br />
public class XanderCat extends AbstractXanderRobot {<br />
<br />
@Override<br />
protected void style(RobotStyle robotStyle) {<br />
robotStyle.setColors(Color.WHITE, Color.BLACK, Color.GREEN);<br />
}<br />
<br />
@Override<br />
protected void configure(Configuration configuration) {<br />
configuration.setLogComponentRunTimes(true);<br />
configuration.setLogDriveTimes(true);<br />
}<br />
<br />
@Override<br />
protected boolean recordBattleStats(Map<String, String> oppStats) {<br />
GunStats gunStats = Resources.getGunStats();<br />
double oHR = gunStats.getOverallOpponentHitRatio();<br />
double mHR = gunStats.getOverallHitRatio();<br />
oppStats.put("OppHitRatio", Logger.format(oHR,3));<br />
oppStats.put("MyHitRatio", Logger.format(mHR,3));<br />
return true;<br />
}<br />
<br />
@Override<br />
protected void addComponents(ComponentChain chain) {<br />
<br />
// RADAR<br />
<br />
chain.addDefaultComponents(new BasicRadar(45, 5));<br />
<br />
// DRIVES<br />
<br />
Path2D.Double driveBounds = DriveBoundsFactory.getSmoothedRectangleBounds(getBattleFieldSize());<br />
<br />
RamFactory.addAntiRamComponents(chain);<br />
<br />
MirrorFactory.addAntiMirrorComponents(chain, 12);<br />
<br />
Scenario ipScenario = new NoOpponentWavesScenario();<br />
Drive ipDrive = new IdealPositionDrive();<br />
chain.addComponents(ipScenario, ipDrive);<br />
<br />
...<br />
Drive mainDrive = ...<br />
...<br />
Drive tdDrive = ... <br />
DriveSelector driveSelector = new HighPerformanceDriveSelector(mainDrive, 50, 0.08);<br />
DriveArray driveArray = new DriveArray(driveSelector, mainDrive, tdDrive); <br />
<br />
chain.addDefaultComponents(driveArray);<br />
<br />
// GUNS <br />
<br />
// a special scenario just for our circular drivers out there!<br />
XanderGun circularGun = new XanderGun(new CircularTargeter(), mainPowerSelector);<br />
circularDriverScenario = new CircularDriveScenario(circularGun);<br />
chain.addComponents(circularDriverScenario, circularGun);<br />
<br />
// main guess factor guns<br />
...<br />
Gun[] guns = new Gun[2];<br />
...<br />
VirtualHitRatioGunSelector gunSelector = new VirtualHitRatioGunSelector();<br />
gunSelector.setRollingRatioWeight(0.25);<br />
GunArray gunArray = new GunArray(gunSelector, guns);<br />
<br />
chain.addDefaultComponents(gunArray);<br />
} <br />
}<br />
</pre><br />
<br />
= Handling Static Data =<br />
In order to remember information from one battle to the next, it is necessary to save that information in some static variable or object. However, this would seem to cause problems if you want to pit a robot against itself, or if you want to run two different robots off of the same base framework classes. This would seem to be a problem because suddenly you have two or more distinct robots sharing certain static resources, when each robot should have it's own unique set. However, Robocode uses a separate class loader for every robot, putting each robot in it's own isolated sandbox. This means static variables are not shared among robots.<br />
<br />
The Xander framework attempts to adhere to good object oriented practices; declaring variables as static to preserve them between rounds is considered contrary to this. Therefore, the Xander framework hides this necessity by storing most objects as static behind the scenes, rather than relying on overuse of static variables.</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36373XanderCat2017-04-08T23:32:06Z<p>Skotty: Replaced 12.10 plans for 13.0</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 13.0 (planned) ===<br />
<br />
* Switch to updated Xander Framework v3.<br />
* Fix an exploitable vulnerability in the tracking systems.<br />
* New statistics-based distancing technique for surf drives. This is actually somewhat revolutionary for XanderCat -- not just a tweak -- and it will give the drive far more authority to adjust distance than it has ever had before, from maintaining max distance possible all the way up to essentially ramming (a point of interest that I just removed the Ram drive components in the prior version, but this change would bring similar behavior back as a possibility). Will require some thorough testing prior to release due to the significance of the change.<br />
* Fix bug in wave surfing framework that could result in NullPointerException.<br />
* Tweaks to fix whatever corner cases I might have broke in 12.9.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/Robo001/reply_(3)&diff=36371Thread:User talk:Voidious/Robo001/reply (3)2017-04-04T15:37:58Z<p>Skotty: Reply to Robot001</p>
<hr />
<div>I'm sure we will talk more about this robot later. Probably should be renamed at the very least if it's not the work of Voidious. This is an interesting bot regardless, as it exposes certain vulnerabilities in some robots, including XanderCat; vulnerabilities which I've fixed in XanderCat version 12.10.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/Robo001/reply_(2)&diff=36369Thread:User talk:Voidious/Robo001/reply (2)2017-04-04T04:34:59Z<p>Skotty: Reply to Robot001</p>
<hr />
<div>On closer inspection, looks like Robot001 probably isn't your robot. Author name is Yifan Zhu. Probably just a modified version of Diamond?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36368XanderCat2017-04-04T02:46:20Z<p>Skotty: /* Version 12.10 (planned) */ updated version 12.10 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 12.10 (planned) ===<br />
<br />
* Fix an exploitable vulnerability in the tracking systems.<br />
* New statistics-based distancing technique for surf drives. This is actually somewhat revolutionary for XanderCat -- not just a tweak -- and it will give the drive far more authority to adjust distance than it has ever had before, from maintaining max distance possible all the way up to essentially ramming (a point of interest that I just removed the Ram drive components in the prior version, but this change would bring similar behavior back as a possibility). Will require some thorough testing prior to release due to the significance of the change.<br />
* Fix bug in wave surfing framework that could result in NullPointerException.<br />
* Tweaks to fix whatever corner cases I might have broke in 12.9.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36367XanderCat2017-04-03T22:08:38Z<p>Skotty: /* Version 12.10 (planned) */ updated version 12.10 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 12.10 (planned) ===<br />
<br />
* Fix an exploitable vulnerability in the tracking systems.<br />
* New statistics-based distancing technique for surf drives. This is actually somewhat revolutionary for XanderCat -- not just a tweak -- and it will give the drive far more authority to adjust distance than it has ever had before, from maintaining max distance possible all the way up to essentially ramming (a point of interest that I just removed the Ram drive components in the prior version, but this change would bring similar behavior back as a possibility). Will require some thorough testing prior to release due to the significance of the change.<br />
* Tweaks to fix whatever corner cases I might have broke in 12.9.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36366XanderCat2017-04-03T22:05:31Z<p>Skotty: /* Version 12.10 (planned) */ updated version 12.10 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 12.10 (planned) ===<br />
<br />
* Fix an exploitable vulnerability in the tracking systems.<br />
* New statistics-based distancing technique for surf drives. This is actually somewhat revolutionary for XanderCat -- not just a tweak -- and it will give the drive far more authority to adjust distance than it has ever had before, from maintaining max distance possible all the way up to essentially ramming (a point of interest that I just removed the Ram drive components, but this change would bring similar behavior back). Will require some thorough testing prior to release due to the significance of the change.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36365XanderCat2017-04-03T18:32:08Z<p>Skotty: /* Version 12.10 (planned) */ updated version 12.10 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 12.10 (planned) ===<br />
<br />
* Fix vulnerability in tracking systems.<br />
* New statistics-based distancing technique for surf drives.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36364XanderCat2017-04-03T18:16:46Z<p>Skotty: start section on next planned version 12.10</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Version 12.10 (planned) ===<br />
<br />
* Fix vulnerability in tracking systems.<br />
* TBD<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/Robo001/reply&diff=36363Thread:User talk:Voidious/Robo001/reply2017-04-03T17:46:24Z<p>Skotty: Reply to Robot001</p>
<hr />
<div>I see now. I won't share your dirty little trick, but I will be fixing the vulnerability in the next version of XanderCat. :-)</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/Robo001&diff=36362Thread:User talk:Voidious/Robo0012017-04-03T17:00:40Z<p>Skotty: </p>
<hr />
<div>What is this abomination you have created? I haven't looked at it at all yet, but I'm going to guess it's an advanced/evolved MoxieBot. Second guess is just a regular bullet shielder that emphasizes shielding against more advanced targeting techniques. It's lost big to some robots, but it beat other top robots including Diamond, which is a next to impossible feat. I guess I'm partially to blame by helping bring bullet shielding into the end game. :-P</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/Robo001&diff=36361Thread:User talk:Voidious/Robo0012017-04-03T16:56:51Z<p>Skotty: New thread: Robo001</p>
<hr />
<div>What is this abomination you have created? I haven't looked at it at all yet, but I'm going to guess it's an advanced/evolved MoxieBot. I guess I'm partially to blame by helping bring bullet shielding into the end game. :-P</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36360XanderCat2017-04-03T13:40:50Z<p>Skotty: /* Version 12.9 */</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
UH OH! At least one bot I broke XanderCat against. 12.2 APS on one battle against simonton.mini.WeeksOnEnd 1.10.4. Well, that's what happens when you have a multi-mode bot you don't test well enough before releasing to the rumble. Doh! Hopefully the improvements against other bots make up for it.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=RoboRumble/Participants&diff=36359RoboRumble/Participants2017-04-03T09:07:31Z<p>Skotty: replaced XanderCat 12.8 with XanderCat 12.9 (bullet shielding tweaks, hopefully didn't break anything)</p>
<hr />
<div>{{:RoboRumble/Navigation}}<br />
<br />
----<br />
Just add your bot name ('''as appears in the Robocode selector after packaging''', so including versionnumber) and the RobocodeRepository id number separated by "," (there must be no space after the comma).<br />
<br><br />
The list is in '''alphabetical''' order. Add your bot in the right slot.<br />
<br />
For your bot to be accepted by the RR@Home server, the following rules are mandatory:<br />
<br />
* The bot must have a package-name.<br />
* The bot must be packaged in a jar-file.<br />
* A <botname>.properties file must be present in the jar-file.<br />
* The naming of the bot must reflect the internal structure,see [http://home.versatel.nl/gheijenk/plaatjes/bot_naming.png]for sample.RamFire.<br />
<br />
The easiest way to do this is to package your bot with Robocode (Robot -> Package robot for upload).<br />
<br />
'''PLEASE MAKE SURE YOUR BOT IS NOT ALREADY ON THE LIST BEFORE YOU ADD IT.<br>IF YOU ARE ADDING A NEW VERSION OF YOUR BOT, PLEASE DELETE THE OLD ONE.'''<br />
<br />
----<br />
<pre><br />
a.FreyaOS 1.0,http://robocode-archive.strangeautomata.com/robots/a.FreyaOS_1.0.jar<br />
ab.DengerousRoBatra 1.3,http://robocode-archive.strangeautomata.com/robots/ab.DengerousRoBatra_1.3.jar<br />
abc.Shadow 3.83c,http://robocode.aclsi.pt/abc.Shadow_3.83c.jar<br />
abc.Tron 2.02,http://robocode-archive.strangeautomata.com/robots/abc.Tron_2.02.jar<br />
abc.tron3.Tron 3.11,http://robocode-archive.strangeautomata.com/robots/abc.tron3.Tron_3.11.jar<br />
abud.ThirdRobo 1.0,http://robocode-archive.strangeautomata.com/robots/abud.ThirdRobo_1.0.jar<br />
acid.Bl4ck 1.0,https://dl.dropboxusercontent.com/s/vaq7j18cnweocba/acid.Bl4ck_1.0.jar<br />
acid.Null 1.0,https://dl.dropboxusercontent.com/s/b2ncehfu900jmwh/acid.Null_1.0.jar<br />
acid.Syzygy 1.0.4,https://dl.dropbox.com/s/r53cd4xezv0ils5/acid.Syzygy_1.0.4.jar<br />
acogdev.alpha 0.2,https://sites.google.com/site/cqjake/robocode/acogdev.alpha_0.2.jar<br />
ad.last.Bottom 1.0,http://robocode-archive.strangeautomata.com/robots/ad.last.Bottom_1.0.jar<br />
ad.Quest 0.10,http://robocode-archive.strangeautomata.com/robots/ad.Quest_0.10.jar<br />
adt.Ar1 2.1,http://robocode-archive.strangeautomata.com/robots/adt.Ar1_2.1.jar<br />
adt.Ar2 1.0,http://robocode-archive.strangeautomata.com/robots/adt.Ar2_1.0.jar<br />
aetos.AetosFirstBot 1.0,http://robocode-archive.strangeautomata.com/robots/aetos.AetosFirstBot_1.0.jar<br />
ag.Gir 0.99,http://robocode-archive.strangeautomata.com/robots/ag.Gir_0.99.jar<br />
agd.Mooserwirt2 2.7,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/agd.Mooserwirt2_2.7.jar<br />
agrach.Dalek 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.Dalek_1.0.jar<br />
agrach.MicroDalek 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.MicroDalek_1.0.jar<br />
agrach.RobotSlayer 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.RobotSlayer_1.0.jar<br />
ags.Glacier 0.2.7,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.Glacier_0.2.7.jar<br />
ags.micro.Carpet 1.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.micro.Carpet_1.1.jar<br />
ags.Midboss 1q.fast,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.Midboss_1q.fast.jar<br />
ags.polished.PolishedRuby 1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.polished.PolishedRuby_1.jar<br />
ags.rougedc.RougeDC willow,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.rougedc.RougeDC_willow.jar<br />
ahf.Acero 1.0,http://robocode-archive.strangeautomata.com/robots/ahf.Acero_1.0.jar<br />
ahf.NanoAndrew .4,http://robocode-archive.strangeautomata.com/robots/ahf.NanoAndrew_.4.jar<br />
ahf.r2d2.R2d2 0.86,http://robocode-archive.strangeautomata.com/robots/ahf.r2d2.R2d2_0.86.jar<br />
ahr.ice.Ice 1.0,http://robocode-archive.strangeautomata.com/robots/ahr.ice.Ice_1.0.jar<br />
AIR.iRobot 1.0,http://robocode-archive.strangeautomata.com/robots/AIR.iRobot_1.0.jar<br />
ak.Fermat 2.0,http://robocode-archive.strangeautomata.com/robots/ak.Fermat_2.0.jar<br />
alex.Diabolo5 1.1,http://robocode-archive.strangeautomata.com/robots/alex.Diabolo5_1.1.jar<br />
alk.lap.LoudAndProud 2.23,http://robocode-archive.strangeautomata.com/robots/alk.lap.LoudAndProud_2.23.jar<br />
alpha.BlackIce 1.0,https://docs.google.com/uc?export=download&confirm=no_antivirus&id=0B4I_xy0UZndLSkc3MVI3Y0sycW8<br />
alpha.RainingFire 1.0,https://docs.google.com/uc?export=download&id=0B4I_xy0UZndLQnVwbHBKVWd5ak0<br />
am.Miedzix 3.0,http://robocode-archive.strangeautomata.com/robots/am.Miedzix_3.0.jar<br />
amarok.Rookie 1.1,http://robocode-archive.strangeautomata.com/robots/amarok.Rookie_1.1.jar<br />
amc.ROBv202 1.01,http://matron.ic.cz/robocode/amc.ROBv202_1.01.jar<br />
amc.ROBv203 1.0,http://matron.ic.cz/robocode/amc.ROBv203_1.0.jar<br />
amc.ROBv300 1.1,http://matron.ic.cz/robocode/amc.ROBv300_1.1.jar<br />
amc.ROBv301 1.1,http://matron.ic.cz/robocode/amc.ROBv301_1.1.jar<br />
amc.ROBv400 1.0,http://matron.ic.cz/robocode/amc.ROBv400_1.0.jar<br />
amk.ChumbaMini 0.2,http://robocode-archive.strangeautomata.com/robots/amk.ChumbaMini_0.2.jar<br />
amk.ChumbaWumba 0.3,http://robocode-archive.strangeautomata.com/robots/amk.ChumbaWumba_0.3.jar<br />
amk.jointstrike.JointStrike 0.2,http://robocode-archive.strangeautomata.com/robots/amk.jointstrike.JointStrike_0.2.jar<br />
amk.Punbot.Punbot 0.01,http://robocode-archive.strangeautomata.com/robots/amk.Punbot.Punbot_0.01.jar<br />
amk.ShizzleStiX.ShizzleStiX 0.6,http://robocode-archive.strangeautomata.com/robots/amk.ShizzleStiX.ShizzleStiX_0.6.jar<br />
amk.superstrike.SuperStrike 0.3,http://robocode-archive.strangeautomata.com/robots/amk.superstrike.SuperStrike_0.3.jar<br />
And.BasicSurfer FF1.6,https://sites.google.com/site/devonrobots/home/basicsurfer/And.BasicSurfer_FF1.6.jar?attredirects=0&d=1<br />
ao.T100 0.9,http://robocode-archive.strangeautomata.com/robots/ao.T100_0.9.jar<br />
ap.Frederick 1.1,http://robocode-archive.strangeautomata.com/robots/ap.Frederick_1.1.jar<br />
apc.botM 3.0, http://www.jambe.co.nz/~james/apc.botM_3.0.jar<br />
apc.Caan 1.0, http://www.jambe.co.nz/~james/apc.Caan_1.0.jar<br />
apc.Colossus2 0.12, http://robocode-archive.strangeautomata.com/robots/apc.Colossus2_0.12.jar<br />
apc.LeeroyJenkins2 1.0,http://robocode-archive.strangeautomata.com/robots/apc.LeeroyJenkins2_1.0.jar<br />
apollokidd.ApolloKidd 0.9,http://robocode-archive.strangeautomata.com/robots/apollokidd.ApolloKidd_0.9.jar<br />
apv.Aspid 1.7,http://robocode-archive.strangeautomata.com/robots/apv.Aspid_1.7.jar<br />
apv.AspidReloaded 0.6,http://robocode-archive.strangeautomata.com/robots/apv.AspidReloaded_0.6.jar<br />
apv.LauLectrik 1.2,http://robocode-archive.strangeautomata.com/robots/apv.LauLectrik_1.2.jar<br />
apv.MicroAspid 1.8,http://robocode-archive.strangeautomata.com/robots/apv.MicroAspid_1.8.jar<br />
apv.NanoLauLectrik 1.0,http://robocode-archive.strangeautomata.com/robots/apv.NanoLauLectrik_1.0.jar<br />
apv.NanoLauLectrikTheCannibal 1.1,http://robocode-archive.strangeautomata.com/robots/apv.NanoLauLectrikTheCannibal_1.1.jar<br />
apv.ScruchiPu 1.0,http://robocode-archive.strangeautomata.com/robots/apv.ScruchiPu_1.0.jar<br />
apv.test.Virus 0.6.1,http://robocode-archive.strangeautomata.com/robots/apv.test.Virus_0.6.1.jar<br />
apv.TheBrainPi 0.5fix,http://robocode-archive.strangeautomata.com/robots/apv.TheBrainPi_0.5fix.jar<br />
ar.horizon.Horizon 1.2.2,http://robocode-archive.strangeautomata.com/robots/ar.horizon.Horizon_1.2.2.jar<br />
ar.QuantumChromodynamics 1.2.1,http://robocode-archive.strangeautomata.com/robots/ar.QuantumChromodynamics_1.2.1.jar<br />
ar.TheoryOfEverything 1.2.1,http://robocode-archive.strangeautomata.com/robots/ar.TheoryOfEverything_1.2.1.jar<br />
ara.Shera 0.88,http://robocode-archive.strangeautomata.com/robots/ara.Shera_0.88.jar<br />
ArchAlpha.ArchimedesAlpha 1.0,https://www.dropbox.com/s/ytkmgs2mk16qehf/ArchAlpha.ArchimedesAlpha_1.0.jar?dl=1<br />
areb.Union 1.06,http://robocode-archive.strangeautomata.com/robots/areb.Union_1.06.jar<br />
arthord.KostyaTszyu Beta2,http://robocode-archive.strangeautomata.com/robots/arthord.KostyaTszyu_Beta2.jar<br />
arthord.MannyPacquiao Delta2,http://scoutery.awardspace.com/arthord.MannyPacquiao_Delta2.jar<br />
arthord.micro.Apoptygma 0.4,http://robocode-archive.strangeautomata.com/robots/arthord.micro.Apoptygma_0.4.jar<br />
arthord.micro.Muffin 0.6.1,http://robocode-archive.strangeautomata.com/robots/arthord.micro.Muffin_0.6.1.jar<br />
arthord.NanoSatan Mu,http://robocode-archive.strangeautomata.com/robots/arthord.NanoSatan_Mu.jar<br />
arthord.NanoSatanMelee Beta,http://robocode-archive.strangeautomata.com/robots/arthord.NanoSatanMelee_Beta.jar<br />
ary.Crisis 1.0,http://robocode-archive.strangeautomata.com/robots/ary.Crisis_1.0.jar<br />
ary.FourWD 1.3d,http://robocode-archive.strangeautomata.com/robots/ary.FourWD_1.3d.jar<br />
ary.Help 1.0,http://robocode-archive.strangeautomata.com/robots/ary.Help_1.0.jar<br />
ary.micro.Weak 1.2,http://robocode-archive.strangeautomata.com/robots/ary.micro.Weak_1.2.jar<br />
ary.mini.Nimi 1.0,http://robocode-archive.strangeautomata.com/robots/ary.mini.Nimi_1.0.jar<br />
ary.nano.AceSurf 1.2,http://robocode-archive.strangeautomata.com/robots/ary.nano.AceSurf_1.2.jar<br />
ary.nano.ColorNanoP 1.1,http://robocode-archive.strangeautomata.com/robots/ary.nano.ColorNanoP_1.1.jar<br />
ary.SMG 1.01,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ary.SMG_1.01.jar<br />
as.xbots 1.0,http://robocode-archive.strangeautomata.com/robots/as.xbots_1.0.jar<br />
asd.Cthulhu 1.2,http://robocode-archive.strangeautomata.com/robots/asd.Cthulhu_1.2.jar<br />
asm.Statistas 0.1,http://robocode-archive.strangeautomata.com/robots/asm.Statistas_0.1.jar<br />
av.RobAtHome 1.2,http://www.user.tu-berlin.de/vickqsjf/av.RobAtHome_1.2.jar<br />
aw.Gilgalad 1.99.5c,https://sites.google.com/site/awusa94/robocode/aw.Gilgalad_1.99.5c.jar?attredirects=0<br />
awesomeness.Elite 1.0,http://robocode-archive.strangeautomata.com/robots/awesomeness.Elite.jar<br />
awl.Locutus 1.5,https://dl.dropboxusercontent.com/u/1589443/awl.Locutus_1.5.jar<br />
axeBots.HataMoto 3.09,http://robocode-archive.strangeautomata.com/robots/axeBots.HataMoto_3.09.jar<br />
axeBots.Musashi 2.18,http://robocode-archive.strangeautomata.com/robots/axeBots.Musashi_2.18.jar<br />
axeBots.Okami 1.04,http://robocode-archive.strangeautomata.com/robots/axeBots.Okami_1.04.jar<br />
axeBots.SilverSurfer 2.53.33fix,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/axeBots.SilverSurfer_2.53.33fix.jar<br />
ayk.WallHugger 1.0,http://robocode-archive.strangeautomata.com/robots/ayk.WallHugger_1.0.jar<br />
az.Ololobot 0.2.4,https://github.com/alexei-zayakin/robocode/raw/master/az.Ololobot_0.2.4.jar<br />
baal.nano.N 1.42,http://webpages.charter.net/eleeleth/Robots/baal.nano.N_1.42.jar<br />
banshee.micro.Nexus6 0.3.0,http://robocode-archive.strangeautomata.com/robots/banshee.micro.Nexus6_0.3.0.jar<br />
banshee.mini.Nexus6 0.2.0,http://robocode-archive.strangeautomata.com/robots/banshee.mini.Nexus6_0.2.0.jar<br />
barontrozo.BaronTrozo 1.7.6,https://www.dropbox.com/s/6kzl3akeofm3ynq/barontrozo.BaronTrozo_1.7.6.jar?dl=1<br />
bayen.nano.Squirrel 0.2,http://www.freewebs.com/bayen/files/bayen.nano.Squirrel_0.2.jar<br />
bayen.nut.Squirrel 1.621,http://robocode-archive.strangeautomata.com/robots/bayen.nut.Squirrel_1.621.jar<br />
bayen.UbaMicro 1.4,http://robocode-archive.strangeautomata.com/robots/bayen.UbaMicro_1.4.jar<br />
bayen.UbaRamLT 1.0,http://robocode-archive.strangeautomata.com/robots/bayen.UbaRamLT_1.0.jar<br />
bbo.RamboT 0.3,http://robocode-archive.strangeautomata.com/robots/bbo.RamboT_0.3.jar<br />
bbo.TheRoof 1.4.3,http://robocode-archive.strangeautomata.com/robots/bbo.TheRoof_1.4.3.jar<br />
benhorner.PureAggression 0.2.6,http://robocode-archive.strangeautomata.com/robots/benhorner.PureAggression_0.2.6.jar<br />
bh.PencilRain 0.01,http://robocode-archive.strangeautomata.com/robots/bh.PencilRain-0.01.jar<br />
bigpete.Stewie 1.0,http://robocode-archive.strangeautomata.com/robots/bigpete.Stewie_1.0.jar<br />
bing2.Melody 1.3.1,http://www.ccs.neu.edu/home/bing/robocode/bing2.Melody_1.3.1.jar<br />
bjl.LoneDragon 0.5,http://robocode-archive.strangeautomata.com/robots/bjl.LoneDragon_0.5.jar<br />
bk.Shooter 1.0,https://dl.dropboxusercontent.com/u/81048920/bk.Shooter_1.0.jar<br />
blir.micro.blixi.Blixi 1.2,https://dl.dropboxusercontent.com/u/103112496/Robocode/blixi/blir.micro.blixi.Blixi_1.2.jar<br />
blir.mini.oops.Splooshlu 2.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/splooshlu/blir.mini.oops.Splooshlu_2.0.jar<br />
blir.nano.Bruce R1.0.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/bruce/blir.nano.Bruce_R1.0.0.jar<br />
blir.nano.Cabbage R1.0.1,https://dl.dropboxusercontent.com/u/103112496/Robocode/cabbage/blir.nano.Cabbage_R1.1.0.jar<br />
blir.nano.inch.Inchworm 1.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/inchworm/blir.nano.inch.Inchworm_1.0.jar<br />
blr.Chicken001 0.1,https://dl.dropbox.com/s/b1isx9axzuyl2yb/blr.Chicken001_0.1.jar?dl=1<br />
bndl.LostLion 1.2,http://robocode-archive.strangeautomata.com/robots/bndl.LostLion_1.2.jar<br />
boe.Minerva 0.80,https://dl.dropboxusercontent.com/u/27918021/boe.Minerva_0.80.jar<br />
bons.NanoStalker 1.2,http://robocode-archive.strangeautomata.com/robots/bons.NanoStalker_1.2.jar<br />
bots.UberBot 1.2c,https://dl.dropboxusercontent.com/u/97134235/bots.UberBot_1.2c.jar<br />
bots.UnterBot 1.0,https://dl.dropboxusercontent.com/u/97134235/bots.UnterBot_1.0.jar<br />
bots.UnterExBot 1.0,https://dl.dropboxusercontent.com/u/97134235/bots.UnterExBot_1.0.jar<br />
bp.Kuma 1.0,http://robocode-archive.strangeautomata.com/robots/bp.Kuma_1.0.jar<br />
braaropolis.Abot 1.0,http://robocode-archive.strangeautomata.com/robots/braaropolis.Abot_1.0.jar<br />
brainfade.Fallen 0.63,http://robocode-archive.strangeautomata.com/robots/brainfade.Fallen_0.63.jar<br />
brainfade.melee.Dusk 0.44,http://robocode-archive.strangeautomata.com/robots/brainfade.melee.Dusk_0.44.jar<br />
bts.mega.Gnarly 1.4,http://www.bluetorchsource.com/bots/bts.mega.Gnarly_1.4.jar<br />
bts.wiki.RipCurl 0.9b,http://www.bluetorchsource.com/bots/bts.wiki.RipCurl_0.9b.jar<br />
buba.Archivist 0.1,http://robocode-archive.strangeautomata.com/robots/buba.Archivist_0.1.jar<br />
buba.Buba 0.3,http://robocode-archive.strangeautomata.com/robots/buba.Buba_0.3.jar<br />
bumblebee.Bumblebee 1.0, https://dl.dropbox.com/s/ac31anjpew7ownh/bumblebee.Bumblebee_1.0.jar?dl=1<br />
bvh.fnr.Fenrir 0.36l,http://robocode-archive.strangeautomata.com/robots/bvh.fnr.Fenrir_0.36l.jar<br />
bvh.frg.Friga 0.112dev,http://robocode-archive.strangeautomata.com/robots/bvh.frg.Friga_0.112dev.jar<br />
bvh.fry.Freya 0.82,http://robocode-archive.strangeautomata.com/robots/bvh.fry.Freya_0.82.jar<br />
bvh.hdr.Hodur 0.4,http://robocode-archive.strangeautomata.com/robots/bvh.hdr.Hodur_0.4.jar<br />
bvh.loki.Loki 0.5,http://robocode-archive.strangeautomata.com/robots/bvh.loki.Loki_0.5.jar<br />
bvh.micro.Freya 0.3,http://robocode-archive.strangeautomata.com/robots/bvh.micro.Freya_0.3.jar<br />
bvh.micro.Svadilfari 0.2,http://robocode-archive.strangeautomata.com/robots/bvh.micro.Svadilfari_0.2.jar<br />
bvh.mini.Fenrir 0.39,http://robocode-archive.strangeautomata.com/robots/bvh.mini.Fenrir_0.39.jar<br />
bvh.mini.Freya 0.55,http://robocode-archive.strangeautomata.com/robots/bvh.mini.Freya_0.55.jar<br />
bvh.mini.Mjolnir 0.3,http://robocode-archive.strangeautomata.com/robots/bvh.mini.Mjolnir_0.3.jar<br />
bvh.mini.Wodan 0.50,http://robocode-archive.strangeautomata.com/robots/bvh.mini.Wodan_0.50.jar<br />
bvh.tyr.Tyr 1.74,http://robocode-archive.strangeautomata.com/robots/bvh.tyr.Tyr_1.74.jar<br />
bwbaugh.nano.Tirunculus 0.0.0a,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/bwbaugh.nano.Tirunculus_0.0.0a.jar<br />
bzdp.BoxCar 2.0,http://robocode-archive.strangeautomata.com/robots/bzdp.BoxCar_2.0.jar<br />
bzdp.Pansy 2.1,http://robocode-archive.strangeautomata.com/robots/bzdp.Pansy_2.1.jar<br />
caimano.Furia_Ceca 0.22,http://robocode-archive.strangeautomata.com/robots/caimano.Furia_Ceca_0.22.jar<br />
can.Pookie 1.1,http://robocode-archive.strangeautomata.com/robots/can.Pookie-1.1.jar<br />
casey.Flee 1.0,http://robocode-archive.strangeautomata.com/robots/casey.Flee_1.0.jar<br />
casey.Flump 1.0,https://www.sites.google.com/site/fatsandbox/robots/casey.Flump_1.0.jar<br />
cb.mega.Remedy 0.9,http://bomberportal.com/other/robocode/cb.mega.Remedy_0.9.jar<br />
cbot.agile.Nibbler 0.2,http://robocode-archive.strangeautomata.com/robots/cbot.agile.Nibbler_0.2.jar<br />
cbot.cbot.CBot 0.8,http://robocode-archive.strangeautomata.com/robots/cbot.cbot.CBot_0.8.jar<br />
cf.mini.Chiva 1.0,http://robocode-archive.strangeautomata.com/robots/cf.mini.Chiva_1.0.jar<br />
cf.OldMan.OldManXP 0.1,http://robocode-archive.strangeautomata.com/robots/cf.OldMan.OldManXP_0.1.jar<br />
cf.proto.Shiva 2.2,http://robocode-archive.strangeautomata.com/robots/cf.proto.Shiva_2.2.jar<br />
cf.star.Star2 1.23,http://robocode-archive.strangeautomata.com/robots/cf.star.Star2_1.23.jar<br />
ch.rhj.rbc.RHJ1 1.0,http://robocode-archive.strangeautomata.com/robots/ch.rhj.rbc.RHJ1_1.0.jar<br />
CharlieN.Omega.Omega 1.03,http://robocode-archive.strangeautomata.com/robots/CharlieN.Omega.Omega_1.03.jar<br />
chase.pm.Pytko 1.0,http://robocode-archive.strangeautomata.com/robots/chase.pm.Pytko_1.0.jar<br />
chickenfuego.UrChicken2 1.0,http://robocode-archive.strangeautomata.com/robots/chickenfuego.UrChicken2_1.0.jar<br />
cjk.Merkava 0.1.1,http://robocode-archive.strangeautomata.com/robots/cjk.Merkava_0.1.1.jar<br />
cjm.chalk.Chalk 2.6.Be,http://scatterbright.com/robots/cjm.chalk.Chalk_2.6.Be.jar<br />
cjm.Charo 1.1,http://scatterbright.com/robots/cjm.Charo_1.1.jar<br />
cjm.Che 1.2,http://robocode-archive.strangeautomata.com/robots/cjm.Che_1.2.jar<br />
cjm.Chomsky 1.5,http://scatterbright.com/robots/cjm.Chomsky_1.5.jar<br />
cli.Dancer 1.1,http://robocode-archive.strangeautomata.com/robots/cli.Dancer_1.1.jar<br />
cli.WasteOfAmmo 1.0,http://robocode-archive.strangeautomata.com/robots/cli.WasteOfAmmo_1.0.jar<br />
codemojo.nano.Woot 1.0,http://robocode-archive.strangeautomata.com/robots/codemojo.nano.Woot_1.0.jar<br />
com.arsenic.NewTest 1.0,http://arsenic.iobb.net/robocode/com.arsenic.NewTest_1.0.jar<br />
com.blogspot.malinkody.DestrobotMalin 1.0,http://robocode-archive.strangeautomata.com/robots/com.blogspot.malinkody.DestrobotMalin_1.0.jar<br />
com.cohesiva.robocode.ManOwaR 1.0,http://robocode-archive.strangeautomata.com/robots/com.cohesiva.robocode.ManOwaR_1.0.jar<br />
com.sociesc.T1000 1.0.0,https://www.dropbox.com/s/221ua09baltwioe/SociescRobot.jar?dl=1<br />
com.syncleus.robocode.Dreadnaught 0.1,http://robocode-archive.strangeautomata.com/robots/com.syncleus.robocode.Dreadnaught_0.1.jar<br />
com.timothyveletta.FuzzyBot 1.1,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/com.timothyveletta.FuzzyBot_1.1.jar<br />
conscience.Bulldozer 1.0a,http://pmdom.altervista.org/conscience.Bulldozer_1.0a.jar<br />
conscience.Electron 1.3g,http://pmdom.altervista.org/conscience.Electron_1.3g.jar<br />
conscience.Idem 1.0a,http://pmdom.altervista.org/conscience.Idem_1.0a.jar<br />
conscience.Suicidal 1.1,http://pmdom.altervista.org/conscience.Suicidal_1.1.jar<br />
cre.Karolos 0.32,http://robocode-archive.strangeautomata.com/robots/cre.Karolos_0.32.jar<br />
cs.Mint 0.14b,https://github.com/Chase-san/AI-MintClover/releases/download/v0.14b/cs.Mint_0.14b.jar<br />
cs.Nene 1.0.5,http://file.csdgn.org/robocode/cs.Nene_1.0.5.jar<br />
cs.PumpkinPie 1.0,http://file.csdgn.org/robocode/cs.PumpkinPie_1.0.jar<br />
cs.s2.Seraphim 2.3.1,http://robocode-archive.strangeautomata.com/robots/cs.s2.Seraphim_2.3.1.jar<br />
cs.Wren 1.0,http://robocode-archive.strangeautomata.com/robots/cs.Wren_1.0.jar<br />
csm.NthGeneration 0.04,http://robocode-archive.strangeautomata.com/robots/csm.NthGeneration_0.04.jar<br />
csp.Eagle 3.30,http://robocode-archive.strangeautomata.com/robots/csp.Eagle_3.30.jar<br />
css.Delitioner 0.11,http://robocode-archive.strangeautomata.com/robots/css.Delitioner_0.11.jar<br />
cuoq.Kakera 1.0,http://robocode-archive.strangeautomata.com/robots/cuoq.Kakera_1.0.jar<br />
cw.megas.Blade 0.8,http://robocode-archive.strangeautomata.com/robots/cw.megas.Blade_0.8.jar<br />
cw.megas.GhostShell GT,http://robocode-archive.strangeautomata.com/robots/cw.megas.GhostShell_GT.jar<br />
cw.megas.Gridd 0.4,http://robocode-archive.strangeautomata.com/robots/cw.megas.Gridd_0.4.jar<br />
cw.megas.Polar 3.2,http://robocode-archive.strangeautomata.com/robots/cw.megas.Polar_3.2.jar<br />
cw.megas.Silhouette 1.1,http://robocode-archive.strangeautomata.com/robots/cw.megas.Silhouette_1.1.jar?attredirects=0&d=1<br />
cx.BlestPain 1.41,http://robocode-archive.strangeautomata.com/robots/cx.BlestPain_1.41.jar<br />
cx.CigaretBH 1.03,http://robocode-archive.strangeautomata.com/robots/cx.CigaretBH_1.03.jar<br />
cx.Lacrimas 1.36,http://robocode-archive.strangeautomata.com/robots/cx.Lacrimas_1.36.jar<br />
cx.micro.Blur 0.2,http://robocode-archive.strangeautomata.com/robots/cx.micro.Blur_0.2.jar<br />
cx.micro.Smoke 0.96,http://robocode-archive.strangeautomata.com/robots/cx.micro.Smoke_0.96.jar<br />
cx.micro.Spark 0.6,http://robocode-archive.strangeautomata.com/robots/cx.micro.Spark_0.6.jar<br />
cx.mini.BlackSwans 0.60,http://robocode-archive.strangeautomata.com/robots/cx.mini.BlackSwans_0.60.jar<br />
cx.mini.Cigaret 1.31,http://robocode-archive.strangeautomata.com/robots/cx.mini.Cigaret_1.31.jar<br />
cx.mini.Nimrod 0.55,http://robocode-archive.strangeautomata.com/robots/cx.mini.Nimrod_0.55.jar<br />
cx.nano.Smog 2.6,http://robocode-archive.strangeautomata.com/robots/cx.nano.Smog_2.6.jar<br />
cx.Princess 1.0,http://robocode-archive.strangeautomata.com/robots/cx.Princess_1.0.jar<br />
cyragia.Bot 1.1,http://robocode-archive.strangeautomata.com/robots/cyragia.Bot_1.1.jar<br />
da.NewBGank 1.4,http://robocode-archive.strangeautomata.com/robots/da.NewBGank_1.4.jar<br />
daemons.DizzyA 1.0,https://github.com/bushranger/DizzyA/blob/master/daemons.DizzyA_1.0.jar?raw=true<br />
dam.MogBot 2.9,http://robocode-archive.strangeautomata.com/robots/dam.MogBot_2.9.jar<br />
dans.Cinnamon 1.2,http://robocode-archive.strangeautomata.com/robots/dans.Cinnamon_1.2.jar<br />
darkcanuck.Gaff 1.50,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Gaff_1.50.jar<br />
darkcanuck.Holden 1.13a,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Holden_1.13a.jar<br />
darkcanuck.Pris 0.92,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Pris_0.92.jar<br />
davidalves.Firebird 0.25,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/davidalves.Firebird_0.25.jar<br />
davidalves.net.Duelist 0.1.6src,http://robocode-archive.strangeautomata.com/robots/davidalves.net.Duelist_0.1.6src.jar<br />
davidalves.net.DuelistMicro 1.22,http://robocode-archive.strangeautomata.com/robots/davidalves.net.DuelistMicro_1.22.jar<br />
davidalves.net.DuelistMicroMkII 1.1,http://robocode-archive.strangeautomata.com/robots/davidalves.net.DuelistMicroMkII_1.1.jar<br />
davidalves.net.DuelistMini 1.1,http://robocode-archive.strangeautomata.com/robots/davidalves.net.DuelistMini_1.1.jar<br />
davidalves.net.DuelistNano 1.0,http://robocode-archive.strangeautomata.com/robots/davidalves.net.DuelistNano_1.0.jar<br />
davidalves.Phoenix 1.02,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/davidalves.Phoenix_1.02.jar<br />
davidalves.PhoenixOS 1.1,http://robocode-archive.strangeautomata.com/robots/davidalves.PhoenixOS_1.1.jar<br />
davv.DOne b002,http://urbanowicz.ckziu-wolow.pl/RobotCode-robots/davv.DOne_b002.jar<br />
dcs.Eater_of_Worlds 1.1.3-A,http://robocode-archive.strangeautomata.com/robots/dcs.Eater_of_Worlds_1.1.3-A.jar<br />
dcs.Eater_of_Worlds_Mini 1.0,http://robocode-archive.strangeautomata.com/robots/dcs.Eater_of_Worlds_Mini_1.0.jar<br />
dcs.PM.Eater_of_Worlds_PM 1.2,http://robocode-archive.strangeautomata.com/robots/dcs.PM.Eater_of_Worlds_PM_1.2.jar<br />
de.erdega.robocode.Polyphemos 0.4,http://robocode-archive.strangeautomata.com/robots/de.erdega.robocode.Polyphemos_0.4.jar<br />
de.simpleworks.robocode.bots.swiBot 1.0,http://fmg.96.lt/robocode/de.simpleworks.robocode.bots.swiBot_1.0.jar<br />
de.simpleworks.robocode.bots.swiBot 1.1,http://fmg.96.lt/robocode/de.simpleworks.robocode.bots.swiBot_1.1.jar<br />
deewiant.Anomaly 0.2,http://www.iki.fi/~deewiant/files/deewiant.Anomaly_0.2.jar<br />
deith.Czolgzilla 0.11,http://robocode-archive.strangeautomata.com/robots/deith.Czolgzilla_0.11.jar<br />
demetrix.ForceMajeure 0.75,http://ever-rage.narod.ru/robowiki/demetrix.ForceMajeure_0.75.jar<br />
demetrix.nano.Neutrino 0.27,http://ever-rage.narod.ru/robowiki/demetrix.nano.Neutrino_0.27.jar<br />
demetrix.nano.SledgeHammer 0.22,http://ever-rage.narod.ru/robowiki/demetrix.nano.SledgeHammer_0.22.jar<br />
deo.CloudBot 1.3,http://robocode-archive.strangeautomata.com/robots/deo.CloudBot_1.3.jar<br />
deo.FlowerBot 1.0,http://robocode-archive.strangeautomata.com/robots/deo.FlowerBot_1.0.jar<br />
deo.virtual.RainbowBot 1.0,http://robocode-archive.strangeautomata.com/robots/deo.virtual.RainbowBot_1.0.jar<br />
dft.Calliope 5.6,http://robocode-archive.strangeautomata.com/robots/dft.Calliope_5.6.jar<br />
dft.Cyanide 1.90,http://robocode-archive.strangeautomata.com/robots/dft.Cyanide_1.90.jar<br />
dft.Cyprus 3.0,http://robocode-archive.strangeautomata.com/robots/dft.Cyprus_3.0.jar<br />
dft.Freddie 1.32,http://robocode-archive.strangeautomata.com/robots/dft.Freddie_1.32.jar<br />
dft.Guppy 1.0,http://robocode-archive.strangeautomata.com/robots/dft.Guppy_1.0.jar<br />
dft.Immortal 1.40,http://robocode-archive.strangeautomata.com/robots/dft.Immortal_1.40.jar<br />
dft.Krazy 1.5,http://robocode-archive.strangeautomata.com/robots/dft.Krazy_1.5.jar<br />
dft.Virgin 1.25,http://robocode-archive.strangeautomata.com/robots/dft.Virgin_1.25.jar<br />
dggp.haiku.gpBot_0 1.1,http://robocode-archive.strangeautomata.com/robots/dggp.haiku.gpBot_0_1.1.jar<br />
dhn.Immortal 1.0,http://www.griessersoftware.com/robocode/dhn.Immortal.1.0.jar<br />
disan.Chair 2.2.0,https://dl.dropboxusercontent.com/u/138299243/Robocode/disan.Chair_2.2.0.jar<br />
disan.Ghost .01,https://dl.dropboxusercontent.com/u/138299243/Robocode/disan.Ghost_.01.jar<br />
discan.mini.Exode 0.25,https://sites.google.com/site/discanroborumblebots/discan.mini.Exode_0.25.jar<br />
dittman.BlindSquirl Retired,http://home.comcast.net/~kokyunage/robocode/ugluk/dittman.BlindSquirl_Retired.jar<br />
divineomega.DivineBot 1.9.5,https://dl.dropboxusercontent.com/s/9wr4n4ta4adyclk/divineomega.DivineBot_1.9.5.jar?dl=1&token_hash=AAFORZvnVipGgc_vZvrhTyPqJtbTNE9fzxdGT38DoUbq8g<br />
divineomega.PatrollerBot 1.0,https://www.dropbox.com/s/hukckrda0z5xdnk/divineomega.PatrollerBot_1.0.jar?dl=1<br />
divineomega.TrialBot 0.003,https://dl.dropboxusercontent.com/s/an44muntp8f0p6h/divineomega.TrialBot_0.003.jar?token_hash=AAG5XTuv2fkEkTYhNIEJ0zre-SpWgK-jvKNqQ120pFeYSA&dl=1<br />
djc.Aardvark 0.3.6,http://robocode-archive.strangeautomata.com/robots/djc.Aardvark_0.3.6.jar<br />
djdjdj.NanoSkunk10 1.0,http://davidjoerg.com/robocode/djdjdj.NanoSkunk10_1.0.jar<br />
dk.stable.Gorgatron 1.1,http://robocode-archive.strangeautomata.com/robots/dk.stable.Gorgatron_1.1.jar<br />
dks.MicroDanMK2 1.0,http://robocode-archive.strangeautomata.com/robots/dks.MicroDanMK2_1.0.jar<br />
DM.Capriite 3.7.2,http://robocode-archive.strangeautomata.com/robots/DM.Capriite_3.7.2.jar<br />
DM.Chicken 4.0,http://robocode-archive.strangeautomata.com/robots/DM.Chicken_4.0.jar<br />
DM.Mijit .3,http://robocode-archive.strangeautomata.com/robots/DM.Mijit_.3.jar<br />
dmh.robocode.robot.BlackDeath 9.2,https://www.dropbox.com/s/tads4vk7jrgmv6u/dmh.robocode.robot.BlackDeath_9.2.jar?dl=1<br />
dmh.robocode.robot.BlueBerry 0.5,https://www.dropbox.com/s/rjlhcmkj3gsb6mj/dmh.robocode.robot.BlueBerry_0.5.jar?dl=1<br />
dmh.robocode.robot.GreenDragon 1.0,https://www.dropbox.com/s/6hcm5lpj0rfcywa/dmh.robocode.robot.GreenDragon_1.0.jar?dl=1<br />
dmh.robocode.robot.PinkPanther 1.1,https://www.dropbox.com/s/hrs8c2nd04cxmxx/dmh.robocode.robot.PinkPanther_1.1.jar?dl=1<br />
dmh.robocode.robot.YellowBird 0.12,https://www.dropbox.com/s/g413cgtvnz53xqr/dmh.robocode.robot.YellowBird_0.12.jar?dl=1<br />
dmp.micro.Aurora 1.41,http://robocode-archive.strangeautomata.com/robots/dmp.micro.Aurora_1.41.jar<br />
dmp.nano.Eve 3.41,http://robocode-archive.strangeautomata.com/robots/dmp.nano.Eve_3.41.jar<br />
doka.KillerRabbit 1.0,https://dl.dropboxusercontent.com/u/79981221/doka.KillerRabbit_1.0.jar<br />
doka.Shinigami 2.2,https://dl.dropboxusercontent.com/u/79981221/doka.Shinigami_2.2.jar<br />
doka.ShinigamiKNN 1.0,https://dl.dropboxusercontent.com/u/79981221/doka.ShinigamiKNN_1.0.jar<br />
doka.Test 1.0,https://dl.dropboxusercontent.com/u/79981221/doka.Test_1.0.jar<br />
donjezza.Jezza 1.0,http://robocode-archive.strangeautomata.com/robots/donjezza.Jezza_1.0.jar<br />
donjezza.Muncho 1.0,http://robocode-archive.strangeautomata.com/robots/donjezza.Muncho_1.0.jar<br />
dragonbyte.Neutrino 4,http://www.manxrobocode.com/bots/dragonbyte.Neutrino_4.jar<br />
drd.Dreadknoght 0.9,http://robocode-archive.strangeautomata.com/robots/drd.Dreadknoght_0.9.jar<br />
drm.CobraBora 1.12,http://robocode-archive.strangeautomata.com/robots/drm.CobraBora_1.12.jar<br />
drm.Magazine 0.39,http://robocode-archive.strangeautomata.com/robots/drm.Magazine_0.39.jar<br />
ds.OoV4 0.3b,http://robocode-archive.strangeautomata.com/robots/ds.OoV4_0.3b.jar<br />
ds.Versatile RB1.0.1,http://bluebox.selfip.com/robots/ds.Versatile_RB1.0.1.jar<br />
dsekercioglu.Hammer 6.2,https://www.dropbox.com/s/c3hzit7nnqgzdyp/dsekercioglu.Hammer_6.2.jar?dl=1<br />
dsekercioglu.Havoc 1.2,https://www.dropbox.com/s/r6akllgnhrugw2g/dsekercioglu.Havoc_1.2.jar?dl=1<br />
dsekercioglu.Husky 1.9,https://www.dropbox.com/s/ls5yedwo3jb1gru/dsekercioglu.Husky_1.9.jar?dl=1<br />
dsekercioglu.Nightmare 1.4,https://www.dropbox.com/s/coix0lmdyatnqr9/dsekercioglu.Nightmare_1.4.jar?dl=1<br />
dsekercioglu.Tomahawk 5.04x,https://www.dropbox.com/s/qx5wi8io048pnf3/dsekercioglu.Tomahawk_5.04x.jar?dl=1<br />
dsekercioglu.WhiteFang 1.4.8,https://www.dropbox.com/s/7ecrwjxdxcz7uuv/dsekercioglu.WhiteFang_1.4.8.jar?dl=1<br />
dsekercioglu.WormHole 1.2,https://www.dropbox.com/s/gupdskse08umgtv/dsekercioglu.WormHole_1.2.jar?dl=1<br />
dsw.StaticD 1.0,http://robocode-archive.strangeautomata.com/robots/dsw.StaticD_1.0.jar<br />
dsx724.VSAB_EP3_ATR 1.1,http://robocode-archive.strangeautomata.com/robots/dsx724.VSAB_EP3_ATR_1.1.jar<br />
dsx724.VSAB_EP3a 1.0,http://robocode-archive.strangeautomata.com/robots/dsx724.VSAB_EP3a_1.0.jar<br />
DTF.Kludgy 1.2b,http://robocode-archive.strangeautomata.com/robots/DTF.Kludgy_1.2b.jar<br />
dukie.Ambassador 1.0,http://robocode-archive.strangeautomata.com/robots/dukie.Ambassador_1.0.jar<br />
dummy.micro.HummingBird 2.14,http://robocode-archive.strangeautomata.com/robots/dummy.micro.HummingBird_2.14.jar<br />
dummy.micro.Sparrow 2.5,http://robocode-archive.strangeautomata.com/robots/dummy.micro.Sparrow_2.5.jar<br />
dummy.mini.Parakeet 2.40,http://robocode-archive.strangeautomata.com/robots/dummy.mini.Parakeet_2.40.jar<br />
dvogon.GangBang 1.0,http://robocode-archive.strangeautomata.com/robots/dvogon.GangBang_1.0.jar<br />
dy.LevelOne 2.0,http://robocode-archive.strangeautomata.com/robots/dy.LevelOne_2.0.jar<br />
dz.Caedo 1.4,http://robocode-archive.strangeautomata.com/robots/dz.Caedo_1.4.jar<br />
dz.GalbaMicro 0.11,http://robocode-archive.strangeautomata.com/robots/dz.GalbaMicro_0.11.jar<br />
dz.GalbaMini 0.121,http://robocode-archive.strangeautomata.com/robots/dz.GalbaMini_0.121.jar<br />
dz.MostlyHarmlessNano 2.1,http://robocode-archive.strangeautomata.com/robots/dz.MostlyHarmlessNano_2.1.jar<br />
dz.OthoMicro 0.12,http://robocode-archive.strangeautomata.com/robots/dz.OthoMicro_0.12.jar<br />
dz.OthoMini 0.15,http://robocode-archive.strangeautomata.com/robots/dz.OthoMini_0.15.jar<br />
eat.HumblePieLite 1.0,http://robocode-archive.strangeautomata.com/robots/eat.HumblePieLite_1.0.jar<br />
EBBU.Sim2 1.02,https://dl.dropbox.com/u/85847696/EBBU.Sim2_1.02.jar<br />
ebo.Sparse 0.02,http://www.4geeks.de/files/ebo.Sparse_0.02.jar<br />
ebo.Tahoe 1.1.79,http://www.4geeks.de/files/ebo.Tahoe_1.1.79.jar<br />
EE.LittleBig 1.0,http://robocode-archive.strangeautomata.com/robots/EE.LittleBig_1.0.jar<br />
eem.EvBot v4.6.4,http://evmik.org:1680/~evmik/robocode/eem.EvBot_v4.6.4.jar<br />
eem.EvBotNG v6.1,http://evmik.org:1680/~evmik/robocode/eem.EvBotNG_v6.1.jar<br />
eem.IWillFireNoBullet v2.4,http://evmik.org:1680/~evmik/robocode/eem.IWillFireNoBullet_v2.4.jar<br />
EFD.AdvancedEFD 0.4.5a,http://robocode-archive.strangeautomata.com/robots/EFD.AdvancedEFD_0.4.5a.jar<br />
EH.Fusion 0.32,http://robocode-archive.strangeautomata.com/robots/EH.Fusion_0.32.jar<br />
EH.kms.LightningStorm 0.11B,http://robocode-archive.strangeautomata.com/robots/EH.kms.LightningStorm_0.11B.jar<br />
EH.mini.Panther 0.2,http://robocode-archive.strangeautomata.com/robots/EH.mini.Panther_0.2.jar<br />
EH.nano.NightBird M,http://robocode-archive.strangeautomata.com/robots/EH.nano.NightBird_M.jar<br />
EH.Pegasus 0.113,http://robocode-archive.strangeautomata.com/robots/EH.Pegasus_0.113.jar<br />
el.Attackr 0.1,http://robocode-archive.strangeautomata.com/robots/el.Attackr_0.1.jar<br />
el.JumpShoot 0.2,http://robocode-archive.strangeautomata.com/robots/el.JumpShoot_0.2.jar<br />
el33t.EL33tGangstarr2 2.0,http://robocode-archive.strangeautomata.com/robots/el33t.EL33tGangstarr2_2.0.jar<br />
eld.Hmm 1.0,http://robocode-archive.strangeautomata.com/robots/eld.Hmm_1.0.jar<br />
element.Earth 1.1,http://robocode-archive.strangeautomata.com/robots/element.Earth_1.1.jar<br />
elloco.Flower 0.1r1,http://robocode-archive.strangeautomata.com/robots/elloco.Flower_0.1r1.jar<br />
elloco.Kabuto 0.2r,http://robocode-archive.strangeautomata.com/robots/elloco.Kabuto_0.2r.jar<br />
elvbot.ElverionBot 0.3,http://robocode-archive.strangeautomata.com/robots/elvbot.ElverionBot_0.3.jar<br />
emp.Yngwie 1.11,http://robocode-archive.strangeautomata.com/robots/emp.Yngwie_1.11.jar<br />
ender.EnderRobot 1.1,https://dl.dropbox.com/s/iwl74grt9ogcst0/ender.EnderRobot_1.1.jar?dl=0<br />
ep.MyFirstRobot 1.0,https://www.dropbox.com/s/iy5h7yhvguiq9ac/ep.MyFirstRobot_1.0.jar?dl=1<br />
erdnis.Rover 0.3,http://www.free-games-fun.com/erdnis.Rover_0.3.jar<br />
eskimo.micro.Echo 0.1,http://robocode-archive.strangeautomata.com/robots/eskimo.micro.Echo_0.1.jar<br />
et.Predator 1.8,http://robocode-archive.strangeautomata.com/robots/et.Predator_1.8.jar<br />
ethdsy.Malacka 2.4,http://robocode-archive.strangeautomata.com/robots/ethdsy.Malacka_2.4.jar<br />
etienne72230.Wall_street 1.0,https://dl.dropboxusercontent.com/u/62402056/robocode/etienne72230.Wall_street_1.0.jar<br />
evd.X1 0.01,http://robocode-archive.strangeautomata.com/robots/evd.X1_0.01.jar<br />
Ex.Survival 3.7,http://robocode-archive.strangeautomata.com/robots/Ex.Survival_3.7.jar?attredirects=0&d=1<br />
exauge.GateKeeper 1.1.121g,http://robocode-archive.strangeautomata.com/robots/exauge.GateKeeper_1.1.121g.jar<br />
exauge.LemonDrop 1.6.130,http://robocode-archive.strangeautomata.com/robots/exauge.LemonDrop_1.6.130.jar<br />
exauge.Leopard 1.1.019,http://robocode-archive.strangeautomata.com/robots/exauge.Leopard_1.1.019.jar<br />
extra.LightSauce 0.01,http://robocode-archive.strangeautomata.com/robots/extra.LightSauce_0.01.jar<br />
extra.Sauce .01,http://robocode-archive.strangeautomata.com/robots/extra.Sauce_.01.jar<br />
fala.robocode.FalaRobot 1.0,http://robocode-archive.strangeautomata.com/robots/fala.robocode.FalaRobot_1.0.jar<br />
FatalFlaw.FatalFlaw 1.0.5,http://robocode-archive.strangeautomata.com/robots/FatalFlaw.FatalFlaw_1.0.5.jar<br />
fcr.First 1.0,http://robocode-archive.strangeautomata.com/robots/fcr.First_1.0.jar<br />
Fenix.FenixTrack 1.0,http://robocode-archive.strangeautomata.com/robots/Fenix.FenixTrack_1.0.jar<br />
fire219.CatBot 1.0, https://dl.dropbox.com/s/bhboah2ps3r9xuj/fire219.CatBot_1.0.jar?dl=0<br />
fire219.cymba.Cymba 1.8, https://dl.dropbox.com/s/clg505z652t5l1h/fire219.cymba.Cymba_1.8.jar?dl=0<br />
florent.FloatingTadpole 1.2.6,http://robocode-archive.strangeautomata.com/robots/florent.FloatingTadpole_1.2.6.jar<br />
florent.small.LittleAngel 1.8,http://robocode-archive.strangeautomata.com/robots/florent.small.LittleAngel_1.8.jar<br />
florent.test.Toad 0.14t,http://robocode-archive.strangeautomata.com/robots/florent.test.Toad_0.14t.jar<br />
florent.XSeries.X2 0.17,http://wesley3.free.fr/florent.XSeries.X2_0.17.jar<br />
fm.claire 1.7,http://robocode-archive.strangeautomata.com/robots/fm.claire_1.7.jar<br />
fm.mammillarias 1.3,http://robocode-archive.strangeautomata.com/robots/fm.mammillarias_1.3.jar<br />
fnc.bandit.Bandit 5.2.0,http://robocode-archive.strangeautomata.com/robots/fnc.bandit.Bandit_5.2.0.jar<br />
fnc.bandit2002.Bandit2002 4.0.2,http://robocode-archive.strangeautomata.com/robots/fnc.bandit2002.Bandit2002_4.0.2.jar<br />
fowl3628800.LightningBolt 2.6.0,http://fowl3628800.atwebpages.com/robocode/fowl3628800.LightningBolt_2.6.0.jar<br />
fowl3628800.SitAndGo 1.0.0,http://fowl3628800.atwebpages.com/robocode/fowl3628800.SitAndGo_1.0.0.jar<br />
fowl3628800.StopAndGo 1.0.0,http://fowl3628800.atwebpages.com/robocode/fowl3628800.StopAndGo_1.0.0.jar<br />
fowl3628800.ThunderStruck 3.0.0,http://fowl3628800.atwebpages.com/robocode/fowl3628800.ThunderStruck_3.0.0.jar<br />
frag.FragBot 1.0,http://robocode-archive.strangeautomata.com/robots/frag.FragBot_1.0.jar<br />
franzor.Lizt 1.3.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/franzor.Lizt_1.3.1.jar<br />
froh.micro.Aversari 0.31,https://dl.dropbox.com/u/60122033/Bots/froh.micro.Aversari_0.31.jar<br />
fromHell.BlackBox 0.2,https://www.dropbox.com/s/fj6ozfq1uf23nsy/fromHell.BlackBox_0.0.2.jar?dl=1<br />
fromHell.C22H30N2O2S 2.2,https://www.dropbox.com/s/xmdpc1i8b1xtsso/fromHell.C22H30N2O2S_2.2.jar?dl=1<br />
fromHell.C4H10O 1.5.1,https://www.dropbox.com/s/hne7pq1fo0dwmjg/fromHell.C4H10O_1.5.1.jar?dl=1<br />
fromHell.CHCl3 1.4.2,https://www.dropbox.com/s/9ipmp881g7e9fdz/fromHell.CHCl3_1.4.2.jar?dl=1<br />
fruits.NanoStrawbery 1.3,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/fruits.NanoStrawbery_1.3.jar<br />
fullsail.LaxativeTeaTwo 1.0,http://robocode-archive.strangeautomata.com/robots/fullsail.LaxativeTeaTwo_1.0.jar<br />
fullsail.SweetTea 1.1,http://robocode-archive.strangeautomata.com/robots/fullsail.SweetTea_1.1.jar<br />
fullsail.TimbotNoPrediction 1.0,http://robocode-archive.strangeautomata.com/robots/fullsail.TimbotNoPrediction_1.0.jar<br />
fushi.PvP1.PvP1 2004-02-16,http://robocode-archive.strangeautomata.com/robots/fushi.PvP1.PvP1_2004-02-16.jar<br />
fw.Number1 1.0b,http://robocode-archive.strangeautomata.com/robots/fw.Number1_1.0b.jar<br />
gadsky.Gadsky 1.01,http://robocode-archive.strangeautomata.com/robots/gadsky.Gadsky_1.01.jar<br />
Gecko.ultimateGeckoBot 1.0,http://robocode-archive.strangeautomata.com/robots/Gecko.ultimateGeckoBot_1.0.jar<br />
geep.mini.GPBotA 1.0,http://robocode-archive.strangeautomata.com/robots/geep.mini.GPBotA_1.0.jar<br />
geep.mini.GPBotB 1.1,http://robocode-archive.strangeautomata.com/robots/geep.mini.GPBotB_1.1.jar<br />
genprog.Gajeel 1.0,http://robocode-archive.strangeautomata.com/robots/genprog.Gajeel_1.0.jar<br />
genprog.Rinmorikazu 1.0,http://robocode-archive.strangeautomata.com/robots/genprog.Rinmorikazu_1.0.jar<br />
genprog.Zafaran 1.0,http://robocode-archive.strangeautomata.com/robots/genprog.Zafaran_1.0.jar<br />
germ.TheMind .2,http://robocode-archive.strangeautomata.com/robots/germ.TheMind_.2.jar<br />
gf.Centaur.Centaur 0.6.7,http://robocode-archive.strangeautomata.com/robots/gf.Centaur.Centaur_0.6.7.jar<br />
gg.Squaraus 0.6,http://robocode-archive.strangeautomata.com/robots/gg.Squaraus_0.6.jar<br />
gg.Wolverine 2.0,http://robocode-archive.strangeautomata.com/robots/gg.Wolverine_2.0.jar<br />
gh.GresSuffurd 0.3.14,http://home.versatel.nl/gheijenk/robocode/jarfiles/gh.GresSuffurd_0.3.14.jar<br />
gh.GrubbmGrb 1.2.4,http://home.versatel.nl/gheijenk/robocode/jarfiles/gh.GrubbmGrb_1.2.4.jar<br />
gh.GrypRepetyf 0.13,http://robocode-archive.strangeautomata.com/robots/gh.GrypRepetyf_0.13.jar<br />
gh.micro.Grinnik 0.7,http://robocode-archive.strangeautomata.com/robots/gh.micro.Grinnik_0.7.jar<br />
gh.micro.GrubbmThree 0.9,http://robocode-archive.strangeautomata.com/robots/gh.micro.GrubbmThree_0.9.jar<br />
gh.mini.Gruwel 0.9,http://robocode-archive.strangeautomata.com/robots/gh.mini.Gruwel_0.9.jar<br />
gh.nano.Grofvuil 0.2,http://robocode-archive.strangeautomata.com/robots/gh.nano.Grofvuil_0.2.jar<br />
ghent.ArthurPanzergon 1.0.0,http://franck.jousseaume.free.fr/robocode/ArthurPanzergon_1.0.0.jar<br />
gimp.GimpBot 0.1,http://robocode-archive.strangeautomata.com/robots/gimp.GimpBot_0.1.jar<br />
gio.RealGioBot 1.0,http://robocode-archive.strangeautomata.com/robots/gio.RealGioBot_1.0.jar<br />
gjr.Cephalosporin 0.2,http://robocode-archive.strangeautomata.com/robots/gjr.Cephalosporin_0.2.jar<br />
gm.GaetanoA 2.15,http://robocode-archive.strangeautomata.com/robots/gm.GaetanoA_2.15.jar<br />
goblin.Bender 2.4,http://robocode-archive.strangeautomata.com/robots/goblin.Bender_2.4.jar<br />
gre.svman4.Leonidas 1.1,http://sv9rha.onmypc.org/robocode/gre.svman4.Leonidas_1.1.jar<br />
gre.svman4.Morfeas 1.4,http://robocode-archive.strangeautomata.com/robots/gre.svman4.Morfeas_1.4.jar<br />
grybgoofy.GoofyBot 0.10,http://robocode-archive.strangeautomata.com/robots/grybgoofy.GoofyBot_0.10.jar<br />
Grystrion.RandomTrackerNOREV 1.0,https://www.dropbox.com/s/9ym5golnwurhfxw/Grystrion.RandomTrackerNOREV_1.0.jar?dl=1<br />
Grystrion.TrackerWO 1.0,https://www.dropbox.com/s/f1j88yf69zn37jp/Grystrion.TrackerWO_1.0.jar?dl=1<br />
gtf.robocode.Strafer 2.1.1,http://www.cirp.org/tmp/robocode/gtf.robocode.Strafer-2.1.1.jar<br />
gu.MicroScoob 1.3,http://robocode-archive.strangeautomata.com/robots/gu.MicroScoob_1.3.jar<br />
gwah.GBotMarkIV 1.0,http://robocode-archive.strangeautomata.com/robots/gwah.GBotMarkIV_1.0.jar<br />
gwah.GerryBotMkII 1.5.1,http://robocode-archive.strangeautomata.com/robots/gwah.GerryBotMkII_1.5.1.jar<br />
ha2.T2 0.2,http://robocode-archive.strangeautomata.com/robots/ha2.T2_0.2.jar<br />
ha2.T2b 0.2b,http://robocode-archive.strangeautomata.com/robots/ha2.T2b_0.2b.jar<br />
ha2.T3 0.1,http://robocode-archive.strangeautomata.com/robots/ha2.T3_0.1.jar<br />
ha2.T3 0.2,http://robocode-archive.strangeautomata.com/robots/ha2.T3_0.2.jar<br />
hamilton.Hamilton 1.0,http://robocode-archive.strangeautomata.com/robots/hamilton.Hamilton_1.0.jar<br />
hapiel.Spiral 0.1,http://robocode-archive.strangeautomata.com/robots/hapiel.Spiral_0.1.jar<br />
Heal.TekitokaBot 1.0,http://robocode-archive.strangeautomata.com/robots/Heal.TekitokaBot_1.0.jar<br />
hirataatsushi.Neo 1.6,http://robocode-archive.strangeautomata.com/robots/hirataatsushi.Neo_1.6.jar<br />
hirataatsushi.Trinity 0.003,http://robocode-archive.strangeautomata.com/robots/hirataatsushi.Trinity_0.003.jar<br />
hlavko.micro.Flex 1.5, http://robocode.hmark.eu/hlavko.micro.Flex_1.5.jar<br />
hlavko.nano.Phoenix 1.0, http://robocode.hmark.eu/hlavko.nano.Phoenix_1.0.jar<br />
hlavko.nano.Ringo 1.0d, http://robocode.hmark.eu/hlavko.nano.Ringo_1.0d.jar<br />
hlavko.nano.Ringo 2.0, http://robocode.hmark.eu/hlavko.nano.Ringo_2.0.jar<br />
homerbots.h1 1.0,http://robocode-archive.strangeautomata.com/robots/homerbots.h1_1.0.jar<br />
hp.Athena 0.1,http://robocode-archive.strangeautomata.com/robots/hp.Athena_0.1.jar<br />
hs.SimpleHBot 1.3,http://robocode-archive.strangeautomata.com/robots/hs.SimpleHBot_1.3.jar<br />
hvilela.HVilela 0.9,http://robocode-archive.strangeautomata.com/robots/hvilela.HVilela_0.9.jar<br />
ICS4U1.Patrick_White_Schrodinger 1.1,http://robocode-archive.strangeautomata.com/robots/ICS4U1.Patrick_White_Schrodinger_1.1.jar<br />
infovk.s_schwarzm16.silverbird 1.0,https://dl.dropboxusercontent.com/u/67422107/infovk.s_schwarzm16.silverbird_1.0.jar<br />
ins.MobyNano 0.8,http://robocode-archive.strangeautomata.com/robots/ins.MobyNano_0.8.jar<br />
intruder.PrairieWolf 2.61,http://robocode-archive.strangeautomata.com/robots/intruder.PrairieWolf_2.61.jar<br />
is.fon.rs.FonDestroyer3084 1.0,http://robocode-archive.strangeautomata.com/robots/is.fon.rs.FonDestroyer3084_1.0.jar<br />
is.fon.rs.Kamikaza 1.0,https://dl.dropboxusercontent.com/u/81048920/is.fon.rs.Kamikaza_1.0.jar<br />
jaara.LambdaBot 1.1,http://robocode-archive.strangeautomata.com/robots/jaara.LambdaBot_1.1.jar<br />
jab.avk.ManuelGallegus 0.6,http://robocode-archive.strangeautomata.com/robots/jab.avk.ManuelGallegus_0.6.jar<br />
jab.DiamondStealer 5,http://robocode-archive.strangeautomata.com/robots/jab.DiamondStealers_5.jar<br />
jab.micro.Sanguijuela 0.8,http://robocode-archive.strangeautomata.com/robots/jab.micro.Sanguijuela_0.8.jar<br />
jam.micro.RaikoMicro 1.44,http://robocode-archive.strangeautomata.com/robots/jam.micro.RaikoMicro_1.44.jar<br />
jam.mini.Raiko 0.43,http://robocode-archive.strangeautomata.com/robots/jam.mini.Raiko_0.43.jar<br />
jam.RaikoMX 0.32,http://robocode-archive.strangeautomata.com/robots/jam.RaikoMX_0.32.jar<br />
janm.Jammy 1.0,http://robocode-archive.strangeautomata.com/robots/janm.Jammy_1.0.jar<br />
japs.Serenity 1.0,http://robocode-archive.strangeautomata.com/robots/japs.Serenity_1.0.jar<br />
japs.Sjonniebot 0.9.1,http://robocode-archive.strangeautomata.com/robots/japs.Sjonniebot_0.9.1.jar<br />
jasolo.Sonda 0.55,http://robocode-archive.strangeautomata.com/robots/jasolo.Sonda_0.55.jar<br />
jaw.KarenCain 0.11,http://robocode-archive.strangeautomata.com/robots/jaw.KarenCain_0.11.jar<br />
jaw.Mouse 0.11,http://robocode-archive.strangeautomata.com/robots/jaw.Mouse_0.11.jar<br />
jaybot.adv.bots.JayBot 2.0,http://robocode-archive.strangeautomata.com/robots/jaybot.adv.bots.JayBot_2.0.jar<br />
jaybot.bots.Oddball 4.0,http://robocode-archive.strangeautomata.com/robots/jaybot.bots.Oddball_4.0.jar<br />
jbot.Rabbit2 1.1,http://robocode-archive.strangeautomata.com/robots/jbot.Rabbit2_1.1.jar<br />
jcs.AutoBot 4.2.1,http://robocode-archive.strangeautomata.com/robots/jcs.AutoBot_4.2.1.jar<br />
jcs.Decepticon 2.5.3,http://robocode-archive.strangeautomata.com/robots/jcs.Decepticon_2.5.3.jar<br />
jcs.Megatron 1.2,http://robocode-archive.strangeautomata.com/robots/jcs.Megatron_1.2.jar<br />
jcs.Seth 1.8,http://robocode-archive.strangeautomata.com/robots/jcs.Seth_1.8.jar<br />
jcw.ArcherOne 1.0,http://robocode-archive.strangeautomata.com/robots/jcw.ArcherOne_1.0.jar<br />
jcz.linio.Linio 2.0.H,https://github.com/L1ni0/rcb-bin/raw/master/jcz.linio.Linio_2.0.H.jar<br />
jdw.Hornet 1.0,http://robocode-archive.strangeautomata.com/robots/jdw.Hornet_1.0.jar<br />
jekl.DarkHallow .90.9,http://robocode-archive.strangeautomata.com/robots/jekl.DarkHallow_.90.9.jar<br />
jekl.Jekyl .70,http://robocode-archive.strangeautomata.com/robots/jekl.Jekyl_.70.jar<br />
jekl.mini.BlackPearl .91,http://robocode-archive.strangeautomata.com/robots/jekl.mini.BlackPearl_.91.jar<br />
jep.nano.Hawkwing 0.4.1,http://robocode-archive.strangeautomata.com/robots/jep.nano.Hawkwing_0.4.1.jar<br />
jep.nano.Hotspur 0.1,http://robocode-archive.strangeautomata.com/robots/jep.nano.Hotspur_0.1.jar<br />
jep.Terrible 0.4.1,http://robocode-archive.strangeautomata.com/robots/jep.Terrible_0.4.1.jar<br />
jeremyreeder.Bully 1,http://thesafehouse.info/robocode/jeremyreeder.Bully_1.jar<br />
jeremyreeder.collective.Prophet 5,http://thesafehouse.info/robocode/jeremyreeder.collective.Prophet_5.jar<br />
jeremyreeder.Vincent 2011.12.09,http://robocode-archive.strangeautomata.com/robots/jeremyreeder.Vincent_2011.12.09.jar<br />
jf.Dodger 1.3,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/jf.Dodger_1.3.jar<br />
jgap.JGAP12584 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP12584_1.0.jar<br />
jgap.JGAP130166 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP130166_1.0.jar<br />
jgap.JGAP23423 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP23423_1.0.jar<br />
jgap.JGAP6139 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP6139_1.0.jar<br />
jgap.JGAP7247_2 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP7247_2_1.0.jar<br />
jgap.JGAP7958 1.0,http://robocode-archive.strangeautomata.com/robots/jgap.JGAP7958_1.0.jar<br />
jje.BagPuss 1.2,http://robocode-archive.strangeautomata.com/robots/jje.BagPuss_1.2.jar<br />
jk.mega.DrussGT 3.1.3,https://dl.dropboxusercontent.com/u/4066735/jk.mega.DrussGT_3.1.3.jar<br />
jk.melee.Neuromancer 5.1,https://dl.dropboxusercontent.com/u/4066735/jk.melee.Neuromancer_5.1.jar<br />
jk.micro.Cotillion 0.8,https://dl.dropboxusercontent.com/u/4066735/jk.micro.Cotillion_0.8.jar<br />
jk.mini.CunobelinDC 1.2,https://dl.dropboxusercontent.com/u/4066735/jk.mini.CunobelinDC_1.2.jar<br />
jk.nano.Machete 2.0, https://dl.dropboxusercontent.com/u/4066735/jk.nano.Machete_2.0.jar<br />
jk.precise.EnergyDome 1.6,https://dl.dropboxusercontent.com/u/4066735/jk.precise.EnergyDome_1.6.jar<br />
jk.precise.Wintermute 0.8,https://dl.dropboxusercontent.com/u/4066735/jk.precise.Wintermute_0.8.jar<br />
jk.sheldor.nano.Yatagan 1.2.3,https://dl.dropboxusercontent.com/u/4066735/jk.sheldor.nano.Yatagan_1.2.3.jar<br />
jmcd.BeoWulf 2.8,http://robocode-archive.strangeautomata.com/robots/jmcd.BeoWulf_2.8.jar<br />
joe.ADinosaur 1.0,http://robocode-archive.strangeautomata.com/robots/joe.ADinosaur_1.0.jar<br />
josago.Jorgito 0.16,http://robocode-archive.strangeautomata.com/robots/josago.Jorgito_0.16.jar<br />
jp.Perpy 16.0,http://robocode-archive.strangeautomata.com/robots/jp.Perpy_16.0.jar<br />
jp.SineWall 1.0,http://robocode-archive.strangeautomata.com/robots/jp.SineWall_1.0.jar<br />
jrm.Test0 1.0,http://robocode-archive.strangeautomata.com/robots/jrm.Test0_1.0.jar<br />
js.PinBall 1.6,http://robocode-archive.strangeautomata.com/robots/js.PinBall_1.6.jar<br />
jsal.Jsalbot 1.0,http://robocode-archive.strangeautomata.com/robots/jsal.Jsalbot_1.0.jar<br />
jt.SpearmintCT Alpha,http://robocode-archive.strangeautomata.com/robots/jt.SpearmintCT_Alpha.jar<br />
justin.DemonicRage 3.20,http://robocode-archive.strangeautomata.com/robots/justin.DemonicRage_3.20.jar<br />
jw.Booring 1.11,http://robocode-archive.strangeautomata.com/robots/jw.Booring_1.11.jar<br />
jwirde.Gort 2.0,https://docs.google.com/uc?export=download&id=0B5g5k-WHNBJicHpNNXotVE9aNHc<br />
jwst.DAD.DarkAndDarker 1.1,http://robocode-archive.strangeautomata.com/robots/jwst.DAD.DarkAndDarker_1.1.jar<br />
kanishk.Fr0z3n 1.1,http://robocode-archive.strangeautomata.com/robots/kanishk.Fr0z3n_1.1.jar<br />
kano.gamma.KanoGamma 1.8,http://robocode-archive.strangeautomata.com/robots/kano.gamma.KanoGamma_1.8.jar<br />
kawam.kmBot9 1.0,http://robocode-archive.strangeautomata.com/robots/kawam.kmBot9_1.0.jar<br />
kawigi.f.FhqwhgadsMicro 1.0,http://robocode-archive.strangeautomata.com/robots/kawigi.f.FhqwhgadsMicro_1.0.jar<br />
kawigi.micro.Shiz 1.1,http://robocode-archive.strangeautomata.com/robots/kawigi.micro.Shiz_1.1.jar<br />
kawigi.mini.Coriantumr 1.1,http://robocode-archive.strangeautomata.com/robots/kawigi.mini.Coriantumr_1.1.jar<br />
kawigi.mini.Fhqwhgads 1.1,http://robocode-archive.strangeautomata.com/robots/kawigi.mini.Fhqwhgads_1.1.jar<br />
kawigi.nano.FunkyChicken 1.1,http://robocode-archive.strangeautomata.com/robots/kawigi.nano.FunkyChicken_1.1.jar<br />
kawigi.nano.ThnikkaBot 0.9,http://robocode-archive.strangeautomata.com/robots/kawigi.nano.ThnikkaBot_0.9.jar<br />
kawigi.robot.Girl 1.2,http://robocode-archive.strangeautomata.com/robots/kawigi.robot.Girl_1.2.jar<br />
kawigi.sbf.Barracuda 1.0,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.Barracuda_1.0.jar<br />
kawigi.sbf.FloodHT 0.9.2,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.FloodHT_0.9.2.jar<br />
kawigi.sbf.FloodMicro 1.5,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.FloodMicro_1.5.jar<br />
kawigi.sbf.FloodMini 1.4,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.FloodMini_1.4.jar<br />
kawigi.sbf.FloodNano 1.2,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.FloodNano_1.2.jar<br />
kawigi.sbf.FloodSonnet 0.9,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.FloodSonnet_0.9.jar<br />
kawigi.sbf.Teancum 1.3,http://robocode-archive.strangeautomata.com/robots/kawigi.sbf.Teancum_1.3.jar<br />
kawigi.spare.SpareParts 0.7.6nosnd,http://robocode-archive.strangeautomata.com/robots/kawigi.spare.SpareParts_0.7.6nosnd.jar<br />
kb.PingPong 1.0,http://www.griessersoftware.com/robocode/kb.PingPong.1.0.jar<br />
kc.micro.Needle 0.101,http://robocode-archive.strangeautomata.com/robots/kc.micro.Needle_0.101.jar<br />
kc.micro.Thorn 1.252,http://robocode-archive.strangeautomata.com/robots/kc.micro.Thorn_1.252.jar<br />
kc.micro.WaveShark 0.31,http://robocode-archive.strangeautomata.com/robots/kc.micro.WaveShark_0.31.jar<br />
kc.mini.Vyper 0.311,http://robocode-archive.strangeautomata.com/robots/kc.mini.Vyper_0.311.jar<br />
kc.nano.Splinter 1.2,http://robocode-archive.strangeautomata.com/robots/kc.nano.Splinter_1.2.jar<br />
kc.serpent.Hydra 0.21,http://robocode-archive.strangeautomata.com/robots/kc.serpent.Hydra_0.21.jar<br />
kc.serpent.WaveSerpent 2.11,http://robocode-archive.strangeautomata.com/robots/kc.serpent.WaveSerpent_2.11.jar<br />
kcn.percept.PerceptBot 2.3,http://robocode-archive.strangeautomata.com/robots/kcn.percept.PerceptBot_2.3.jar<br />
kcn.unnamed.Unnamed 1.21,http://robocode-archive.strangeautomata.com/robots/kcn.unnamed.Unnamed_1.21.jar<br />
kebabs.kebabs.Frankenstein 1.0,http://robocodebots.net23.net/kebabs.Frankenstein_1.0.jar<br />
kenran.InfiniteObscurity 0.8,https://dl.dropboxusercontent.com/u/66821565/robots/kenran.InfiniteObscurity_0.8.jar<br />
kenran.mega.Pantheist 1.1,http://robocode-archive.strangeautomata.com/robots/kenran.mega.Pantheist_1.1.jar<br />
kid.Gladiator .7.2,http://robocode-archive.strangeautomata.com/robots/kid.Gladiator_.7.2.jar<br />
kid.Toa .0.5,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/kid.Toa_.0.5.jar<br />
kinsen.melee.Angsaichmophobia 1.8c,http://robocode-archive.strangeautomata.com/robots/kinsen.melee.Angsaichmophobia_1.8c.jar<br />
kinsen.nano.Charp 1.0,https://dl.dropbox.com/s/xivyqm5qi4z2bvp/kinsen.nano.Charp_1.0.jar?dl=1<br />
kinsen.nano.Hoplomachy 1.6,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Hoplomachy_1.6.jar<br />
kinsen.nano.Quarrelet 1.0,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Quarrelet_1.0.jar<br />
kinsen.nano.Senticous 1.0,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Senticous_1.0.jar<br />
KiraNL.Cataris 1.0,http://robocode-archive.strangeautomata.com/robots/KiraNL.Cataris_1.0.jar<br />
KiraNL.Chupacabra 0.5,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.Chupacabra_0.5.jar<br />
KiraNL.ChupaLite 0.4,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.ChupaLite_0.4.jar<br />
KiraNL.SpaceKees 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.SpaceKees_0.1.jar<br />
kjc.etc.Dharok 1.0,http://robocode-archive.strangeautomata.com/robots/kjc.etc.Dharok_1.0.jar<br />
kjc.Karaykan 1.0,http://robocode-archive.strangeautomata.com/robots/kjc.Karaykan_1.0.jar<br />
kjc.MailManX 2.0,http://robocode-archive.strangeautomata.com/robots/kjc.MailManX_2.0.jar<br />
klein.GottesKrieger 1.1,http://robocode-archive.strangeautomata.com/robots/klein.GottesKrieger_1.1.jar<br />
kms.Golden 0.10,http://robocode-archive.strangeautomata.com/robots/kms.Golden_0.10.jar<br />
kms.Royal 0.15M,http://robocode-archive.strangeautomata.com/robots/kms.Royal_0.15M.jar<br />
kneels.nano.Derp 0.2,http://www.schickt.de/robocode/kneels.nano.Derp_0.2.jar<br />
kneels.ToNoone 0.2,http://www.schickt.de/robocode/kneels.ToNoone_0.2.jar<br />
Krabb.fe4r.Fe4r 0.4,http://robocode-archive.strangeautomata.com/robots/Krabb.fe4r.Fe4r_0.4.jar<br />
Krabb.krabby.Krabby 1.18b,http://robocode-archive.strangeautomata.com/robots/Krabb.krabby.Krabby_1.18b.jar<br />
Krabb.krabby2.Krabby2 1.9o,http://robocode-archive.strangeautomata.com/robots/Krabb.krabby2.Krabby2_1.9o.jar<br />
Krabb.sliNk.Garm 0.9u,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/Krabb.sliNk.Garm_0.9u.jar<br />
krillr.mega.Psyche 0.0.3,http://robocode-archive.strangeautomata.com/robots/krillr.mega.Psyche_0.0.3.jar<br />
krillr.mini.JointStrike 2.0.0,http://robocode-archive.strangeautomata.com/robots/krillr.mini.JointStrike_2.0.0.jar<br />
kronenthaler.Basilisk 1.0,http://robocode-archive.strangeautomata.com/robots/kronenthaler.Basilisk_1.0.jar<br />
krzysiek.robbo2.Robbo 1.0.0,http://robocode-archive.strangeautomata.com/robots/krzysiek.robbo2.Robbo_1.0.0.jar<br />
kurios.DOSexe .9a,http://www.kuriosly.com/roborumble/kurios.DOSexe_.9a.jar<br />
kvk.HebusLeTroll 0.41,http://robocode-archive.strangeautomata.com/robots/kvk.HebusLeTroll_0.41.jar<br />
labg.Cataclysm 2.05,http://robocode-archive.strangeautomata.com/robots/labg.Cataclysm_2.05.jar<br />
lancel.Lynx 1.09,http://robocode-archive.strangeautomata.com/robots/lancel.Lynx_1.09.jar<br />
lazarecki.mega.PinkerStinker 0.7,http://robocode-archive.strangeautomata.com/robots/lazarecki.mega.PinkerStinker_0.7.jar<br />
learn.ISmart 2.0s,https://sites.google.com/site/robotrepository/learn.ISmart_2.0s.jar?attredirects=0&d=1<br />
leb.ShootAnArrow 0.1,http://robocode-archive.strangeautomata.com/robots/leb.ShootAnArrow_0.1.jar<br />
lechu.Ala 0.0.4,http://robocode-archive.strangeautomata.com/robots/lechu.Ala_0.0.4.jar<br />
lechu.Lechu 1.1,http://robocode-archive.strangeautomata.com/robots/lechu.Lechu_1.1.jar<br />
Legend.Biogon 1.5,http://robocode-archive.strangeautomata.com/robots/Legend.Biogon_1.5.jar?attredirects=0&d=1<br />
Legend.BoulderZY 1.4.9,http://robocode-archive.strangeautomata.com/robots/Legend.BoulderZY_1.4.9.jar?attredirects=0&d=1<br />
Legend.Qetro 1.6,http://robocode-archive.strangeautomata.com/robots/Legend.Qetro_1.6.jar?attredirects=0&d=1<br />
Legend.X_FireFly 1.3,http://robocode-archive.strangeautomata.com/robots/Legend.X_FireFly_1.3.jar?attredirects=0&d=1<br />
lessonz.robocode.Oz 0.5.0,https://dl.dropbox.com/u/9231432/robocode/lessonz.robocode.Oz-0.5.0.jar<br />
lion.Kresnanano 1.0,http://robocode-archive.strangeautomata.com/robots/lion.Kresnanano_1.0.jar<br />
lk.nano.Avesnar 1.1,http://robocode-archive.strangeautomata.com/robots/lk.nano.Avesnar_1.1.jar<br />
lmk.ACPFinal 0.2,http://pillow.rscheme.org/lmk.ACPFinal_0.2.jar<br />
Lo_Ian.Gandalf_V4 4.0,http://robocode-archive.strangeautomata.com/robots/Lo_Ian.Gandalf_V4_4.0.jar<br />
logiblocs.Fire 1.0,https://dl.dropboxusercontent.com/u/66369360/logiblocs.Fire_1.0.jar<br />
logiblocs.SittingDroid 1.0,https://dl.dropboxusercontent.com/u/66369360/logiblocs.SittingDroid_1.0.jar<br />
lorneswork.Predator 1.0,http://robocode-archive.strangeautomata.com/robots/lorneswork.Predator_1.0.jar<br />
lrem.magic.TormentedAngel Antiquitie,http://robocode-archive.strangeautomata.com/robots/lrem.magic.TormentedAngel_Antiquitie.jar<br />
lrem.micro.FalseProphet Alpha,http://robocode-archive.strangeautomata.com/robots/lrem.micro.FalseProphet_Alpha.jar<br />
lrem.micro.MoggFanatic 0.2,http://robocode-archive.strangeautomata.com/robots/lrem.micro.MoggFanatic_0.2.jar<br />
lrem.quickhack.QuickHack 1.0,http://robocode-archive.strangeautomata.com/robots/lrem.quickhack.QuickHack_1.0.jar<br />
lrem.Spectre 0.4.4,http://robocode-archive.strangeautomata.com/robots/lrem.Spectre_0.4.4.jar<br />
lucasslf.Dodger 1.0,http://robocode-archive.strangeautomata.com/robots/lucasslf.Dodger_1.0.jar<br />
lucasslf.HariSeldon 0.2.1,http://robocode-archive.strangeautomata.com/robots/lucasslf.HariSeldon_0.2.1.jar<br />
lucasslf.Wiggins 0.6,http://robocode-archive.strangeautomata.com/robots/lucasslf.Wiggins_0.6.jar<br />
lunchie.Lunchbox 0.93,http://robocode-archive.strangeautomata.com/robots/lunchie.Lunchbox_0.93.jar<br />
lundal.Mark8 2012.09.15,https://dl.dropbox.com/s/gcs13tapwtwpdwc/lundal.Mark8_2012.09.15.jar<br />
lw.LuthersTest 0.1,http://robocode-archive.strangeautomata.com/robots/lw.LuthersTest_0.1.jar<br />
lxx.ConceptA 0.8,https://github.com/aleksey-zhidkov/ConceptA/raw/master/builds/lxx.ConceptA_0.8.jar<br />
lxx.Emerald 0.6.5,https://github.com/aleksey-zhidkov/Emerald/releases/download/v0.6.5/lxx.Emerald_0.6.5.jar<br />
lxx.Tomcat 3.68,https://github.com/aleksey-zhidkov/Tomcat/raw/develop/builds/lxx.Tomcat_3.68.jar<br />
m3thos.Eva00 1.1,http://robocode-archive.strangeautomata.com/robots/m3thos.Eva00_1.1.jar<br />
m3thos.Eva02 0.7.1,http://robocode-archive.strangeautomata.com/robots/m3thos.Eva02_0.7.1.jar<br />
m3thos.mini.Eva01 0.5.5,http://robocode-archive.strangeautomata.com/robots/m3thos.mini.Eva01_0.5.5.jar<br />
ma.is.fon.rs.RobotA 0.01,http://robocode-archive.strangeautomata.com/robots/ma.is.fon.rs.RobotA_0.01.jar<br />
madmath.Cow 0.1.1,http://robocode-archive.strangeautomata.com/robots/madmath.Cow_0.1.1.jar<br />
mae.Mae1 1.1,http://robocode-archive.strangeautomata.com/robots/mae.Mae1_1.1.jar<br />
mahrgell.mahrram 1.3,http://robocode-archive.strangeautomata.com/robots/mahrgell.mahrram_1.3.jar<br />
marcinek.TopGun 1.3,http://robocode-archive.strangeautomata.com/robots/marcinek.TopGun_1.3.jar<br />
maribo.FollowFire 1.11,http://robocode-archive.strangeautomata.com/robots/maribo.FollowFire_1.11.jar<br />
maribo.IotaCT 1.0,http://robocode-archive.strangeautomata.com/robots/maribo.IotaCT_1.0.jar<br />
maribo.melee.BMV 0.1,http://robocode-archive.strangeautomata.com/robots/maribo.melee.BMV_0.1.jar<br />
maribo.Omicron 1.0,http://robocode-archive.strangeautomata.com/robots/maribo.Omicron_1.0.jar<br />
marksteam.Phoenix 1.0,http://robocode-archive.strangeautomata.com/robots/marksteam.Phoenix_1.0.jar<br />
matt.advanced.Katana 1.0,http://robocode-archive.strangeautomata.com/robots/matt.advanced.Katana_1.0.jar<br />
matt.BlueMind 0.8.00,http://robocode-archive.strangeautomata.com/robots/matt.BlueMind_0.8.00.jar<br />
matt.UnderDark3 2.4.34,http://robocode-archive.strangeautomata.com/robots/matt.UnderDark3_2.4.34.jar<br />
matt.UnderDark4 0.4.00,http://robocode-archive.strangeautomata.com/robots/matt.UnderDark4_0.4.00.jar<br />
maye.SlashBot 1.0,https://onedrive.live.com/download?resid=DE77B02CC5BE354F!183&authkey=!ADPCkUOMRP2quWg&ithint=file%2cjar<br />
mb.Beast 0.4.1,http://cdn.bitbucket.org/mbrahm/robodownloads/downloads/mb.Beast_0.4.1.jar<br />
mb.Monte 0.1.0,http://cdn.bitbucket.org/mbrahm/robodownloads/downloads/mb.Monte_0.1.0.jar<br />
mbh.Mbh 0.1,http://robocode-archive.strangeautomata.com/robots/mbh.Mbh_0.1.jar<br />
mbro.BelajarBot 0.0.3,http://robocode-archive.strangeautomata.com/robots/mbro.BelajarBot_0.0.3.jar<br />
mbro.Detektor3 0.1.1,http://robocode-archive.strangeautomata.com/robots/mbro.Detektor3_0.1.1.jar<br />
mc.Messapia 0.1.8,http://robocode-archive.strangeautomata.com/robots/mc.Messapia_0.1.8.jar<br />
mc2.enemy.Original 0.9,https://dl.dropboxusercontent.com/u/69395514/mc2.enemy.Original_0.9.jar<br />
mcb.Audace 1.3,http://robocode-archive.strangeautomata.com/robots/mcb.Audace_1.3.jar<br />
McS.Spanky_test 0.1a,http://robocode-archive.strangeautomata.com/robots/McS.Spanky_test_0.1a.jar<br />
md.November 1.0,http://robocode-archive.strangeautomata.com/robots/md.November_1.0.jar<br />
md.Pasta 1.1,http://robocode-archive.strangeautomata.com/robots/md.Pasta_1.1.jar<br />
md.VelociRaptor 1.3,http://robocode-archive.strangeautomata.com/robots/md.VelociRaptor_1.3.jar<br />
mdouet.BotKicker 2.0,http://robocode-archive.strangeautomata.com/robots/mdouet.BotKicker_2.0.jar<br />
metal.small.dna2.MCoolDNA 1.5,http://robocode-archive.strangeautomata.com/robots/metal.small.dna2.MCoolDNA_1.5.jar<br />
metal.small.MCool 1.21,http://robocode-archive.strangeautomata.com/robots/metal.small.MCool_1.21.jar<br />
microtestbotpack.MicroTestBot 1.0,https://dl.dropboxusercontent.com/u/4547352/robocode/microtestbotpack.MicroTestBot_1.0.jar<br />
mjhjd.MattHussey1 1.1,https://dl.dropbox.com/u/90567837/mjhjd.MattHussey1_1.1.jar<br />
mk.Alpha 0.2.1,http://robocode-archive.strangeautomata.com/robots/mk.Alpha_0.2.1.jar<br />
mladjo.AIR 0.7,http://robocode-archive.strangeautomata.com/robots/mladjo.AIR_0.7.jar<br />
mladjo.GnuKlub 0.1,http://robocode-archive.strangeautomata.com/robots/mladjo.GnuKlub_0.1.jar<br />
mladjo.Grrrrr 0.9,http://robocode-archive.strangeautomata.com/robots/mladjo.Grrrrr_0.9.jar<br />
mladjo.iRobot 0.3,http://robocode-archive.strangeautomata.com/robots/mladjo.iRobot_0.3.jar<br />
mladjo.Startko 1.0,http://robocode-archive.strangeautomata.com/robots/mladjo.Startko_1.0.jar<br />
mld.DustBunny 3.8,http://robocode-archive.strangeautomata.com/robots/mld.DustBunny_3.8.jar<br />
mld.Infinity 2.2,http://robocode-archive.strangeautomata.com/robots/mld.Infinity_2.2.jar<br />
mld.jdc.nano.LittleBlackBook 1.0,http://robocode-archive.strangeautomata.com/robots/mld.jdc.nano.LittleBlackBook_1.0.jar<br />
mld.LittleBlackBook 1.69e,http://robocode-archive.strangeautomata.com/robots/mld.LittleBlackBook_1.69e.jar<br />
mld.Moebius 2.9.3,http://robocode-archive.strangeautomata.com/robots/mld.Moebius_2.9.3.jar<br />
mld.Wisdom 1.0,http://robocode-archive.strangeautomata.com/robots/mld.Wisdom_1.0.jar<br />
mmb.Roskilde 0.5,http://robocode-archive.strangeautomata.com/robots/mmb.Roskilde_0.5.jar<br />
mme.NikeEnhanced 2.0,http://robocode-archive.strangeautomata.com/robots/mme.NikeEnhanced_2.0.jar<br />
mn.Combat 3.25.0,https://www.dropbox.com/s/5iufszjp28qfptw/mn.Combat_3.25.0.jar?dl=1<br />
mn.micro.perceptual.Mimic 1.0.0,http://dl.dropbox.com/s/3m8lbyarqc06tps/mn.micro.perceptual.Mimic_1.0.0.jar?dl=1<br />
mn.nano.perceptual.Impact 1.3.0,http://dl.dropbox.com/s/njuuaycr3qswlgu/mn.nano.perceptual.Impact_1.3.0.jar?dl=1<br />
mn.SuperSittingDuck 1.0.2,http://robocode-archive.strangeautomata.com/robots/mn.SuperSittingDuck_1.0.2.jar<br />
mnt.AHEB 0.6a,http://robocode-archive.strangeautomata.com/robots/mnt.AHEB_0.6a.jar<br />
mnt.SurferBot 0.2.5,http://robocode-archive.strangeautomata.com/robots/mnt.SurferBot_0.2.5.jar<br />
morbid.MorbidPriest 1.0,http://robocode-archive.strangeautomata.com/robots/morbid.MorbidPriest_1.0.jar<br />
mrm.MightyMoose .2,http://robocode-archive.strangeautomata.com/robots/mrm.MightyMoose_.2.jar<br />
ms.Ares 0.19,http://robocode-archive.strangeautomata.com/robots/ms.Ares_0.19.jar<br />
mue.Ascendant 1.2.27,http://mue.sonar-echo.de/robocode/mue.Ascendant_1.2.27.jar<br />
mue.Hyperion 0.8,http://robocode-archive.strangeautomata.com/robots/mue.Hyperion_0.8.jar<br />
muf.CrazyKitten 0.9,http://robocode-archive.strangeautomata.com/robots/muf.CrazyKitten_0.9.jar<br />
mwj.A1176183 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/mwj.A1176183_1.0.jar<br />
myl.micro.Avipes 1.00,http://robocode-archive.strangeautomata.com/robots/myl.micro.Avipes_1.00.jar<br />
myl.micro.NekoNinja 1.30,http://robocode-archive.strangeautomata.com/robots/myl.micro.NekoNinja_1.30.jar<br />
myl.micro.Predator 1.50,http://robocode-archive.strangeautomata.com/robots/myl.micro.Predator_1.50.jar<br />
myl.micro.Troodon 1.10,http://robocode-archive.strangeautomata.com/robots/myl.micro.Troodon_1.10.jar<br />
myl.nano.Graviton 1.10,http://robocode-archive.strangeautomata.com/robots/myl.nano.Graviton_1.10.jar<br />
myl.nano.Kakuru 1.20,http://robocode-archive.strangeautomata.com/robots/myl.nano.Kakuru_1.20.jar<br />
myl.nano.KomoriNinja 1.1,http://robocode-archive.strangeautomata.com/robots/myl.nano.KomoriNinja_1.1.jar<br />
mym.EdgeStalker 1.0,http://robocode-archive.strangeautomata.com/robots/mym.EdgeStalker_1.0.jar<br />
mz.Adept 2.65,http://robocode-archive.strangeautomata.com/robots/mz.Adept_2.65.jar<br />
mz.AdeptBSB 1.03,http://robocode-archive.strangeautomata.com/robots/mz.AdeptBSB_1.03.jar<br />
mz.Movement 1.8,http://robocode-archive.strangeautomata.com/robots/mz.Movement_1.8.jar<br />
mz.NanoDeath 2.56,http://robocode-archive.strangeautomata.com/robots/mz.NanoDeath_2.56.jar<br />
mz.NanoGod 2.02,http://robocode-archive.strangeautomata.com/robots/mz.NanoGod_2.02.jar<br />
nammyung.ModelT 0.23,http://robocode-archive.strangeautomata.com/robots/nammyung.ModelT_0.23.jar<br />
nan.Ihivatar_Mk_1 1.0,http://dl.dropbox.com/s/4oxw831xuu9yui0/nan.Ihivatar_Mk_1_1.0.jar?dl=1<br />
nanoskank.NanoSkank 1.0,http://robocode-archive.strangeautomata.com/robots/nanoskank.NanoSkank_1.0.jar<br />
nat.BlackHole 2.0gamma,http://nat.robothai.net/robots/nat.BlackHole_2.0gamma.jar<br />
nat.Hikari dev0001,http://nat.robothai.net/robots/nat.Hikari_dev0001.jar<br />
nat.micro.Reepicheep 0.1a,http://nat.robothai.net/robots/nat.micro.Reepicheep_0.1a.jar<br />
nat.nano.Ocnirp 1.73,http://nat.robothai.net/robots/nat.nano.Ocnirp_1.73.jar<br />
nat.nano.OcnirpPM 1.0,http://nat.robothai.net/robots/nat.nano.OcnirpPM_1.0.jar<br />
nat.nano.OcnirpSNG 1.0b,http://nat.robothai.net/robots/nat.nano.OcnirpSNG_1.0b.jar<br />
nat.Samekh 0.4,http://nat.robothai.net/robots/nat.Samekh_0.4.jar<br />
ncj.MoxieBot 1.0,http://robocode-archive.strangeautomata.com/robots/ncj.MoxieBot_1.0.jar<br />
NDH.GuessFactor 1.0, http://robocode-archive.strangeautomata.com/robots/NDH.GuessFactor_1.0.jar<br />
ndn.DyslexicMonkey 1.1,http://robocode-archive.strangeautomata.com/robots/ndn.DyslexicMonkey_1.1.jar<br />
ne.Chimera 1.2,http://robocode-archive.strangeautomata.com/robots/ne.Chimera_1.2.jar<br />
nexus.Experimental 0.2,https://dl.dropbox.com/s/kxeorcrx6jwlm2e/nexus.Experimental_0.2.jar<br />
nexus.One 1.0,http://robocode-archive.strangeautomata.com/robots/nexus.One_1.0.jar<br />
nexus.Prototype 1.0,http://robocode-archive.strangeautomata.com/robots/nexus.Prototype_1.0.jar<br />
nexus.Two 0.2,https://dl.dropbox.com/s/glol05xymwbb0a7/nexus.Two_0.2.jar<br />
NG.LegatusLegionis 1.2,http://robocode-archive.strangeautomata.com/robots/NG.LegatusLegionis_1.2.jar<br />
ngf.nano.Sparky 0.1.5,http://robocode-archive.strangeautomata.com/robots/ngf.nano.Sparky_0.1.5.jar<br />
nic.Nicator 2.4,http://robocode-archive.strangeautomata.com/robots/nic.Nicator_2.4.jar<br />
nic.SnippetBot 1.0,http://robocode-archive.strangeautomata.com/robots/nic.SnippetBot_1.0.jar<br />
nkn.mini.Jskr0 0.1,http://robocode-archive.strangeautomata.com/robots/nkn.mini.Jskr0_0.1.jar<br />
non.mega.NaN 0.1,http://robocode-archive.strangeautomata.com/robots/non.mega.NaN_0.1.jar<br />
non.mega.NoName 0.0,http://robocode-archive.strangeautomata.com/robots/non.mega.NoName_0.0.jar<br />
Noran.BitchingElk 0.054,http://robocode-archive.strangeautomata.com/robots/Noran.BitchingElk_0.054.jar<br />
Noran.RandomTargeting 0.02,http://robocode-archive.strangeautomata.com/robots/Noran.RandomTargeting_0.02.jar<br />
nosteel.Welby 0.0.3,https://dl.dropboxusercontent.com/u/45266100/nosteel.Welby_0.0.3.jar<br />
nova.Snow 1.0,http://robocode-archive.strangeautomata.com/robots/nova.Snow_1.0.jar<br />
ntc.Cannon 1.12test,http://robocode-archive.strangeautomata.com/robots/ntc.Cannon_1.12test.jar<br />
ntc.Evader 1.2,http://robocode-archive.strangeautomata.com/robots/ntc.Evader_1.2.jar<br />
ntc.Knowledge 1.1,http://robocode-archive.strangeautomata.com/robots/ntc.Knowledge_1.1.jar<br />
ntc.Lasers.Lasers 0.9,http://robocode-archive.strangeautomata.com/robots/ntc.Lasers.Lasers_0.9.jar<br />
ntc.Plains 0.9,http://robocode-archive.strangeautomata.com/robots/ntc.Plains_0.9.jar<br />
ntc.Swim 0.9,http://robocode-archive.strangeautomata.com/robots/ntc.Swim_0.9.jar<br />
ntw.Sighup 1.5,http://robocode-archive.strangeautomata.com/robots/ntw.Sighup_1.5.jar<br />
ntw.Sigsys 1.6,http://robocode-archive.strangeautomata.com/robots/ntw.Sigsys_1.6.jar<br />
nz.A7Ibwenape A7Ibwen1.0,http://robocode-archive.strangeautomata.com/robots/nz.A7Ibwenape_A7Ibwen1.0.jar<br />
nz.jdc.micro.HedgehogGF 1.5,http://robocode-archive.strangeautomata.com/robots/nz.jdc.micro.HedgehogGF_1.5.jar<br />
nz.jdc.micro.HedgehogP 1.2,http://robocode-archive.strangeautomata.com/robots/nz.jdc.micro.HedgehogP_1.2.jar<br />
nz.jdc.nano.AralR 1.1,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.AralR_1.1.jar<br />
nz.jdc.nano.AralT 1.1,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.AralT_1.1.jar<br />
nz.jdc.nano.NeophytePattern 1.1,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.NeophytePattern_1.1.jar<br />
nz.jdc.nano.NeophytePRAL 1.4,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.NeophytePRAL_1.4.jar<br />
nz.jdc.nano.NeophyteSRAL 1.3,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.NeophyteSRAL_1.3.jar<br />
nz.jdc.nano.PatternAdept 1.0,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.PatternAdept_1.0.jar<br />
nz.jdc.nano.PralDeGuerre 1.2,http://robocode-archive.strangeautomata.com/robots/nz.jdc.nano.PralDeGuerre_1.2.jar<br />
nzeemin.Izh 0.5,http://nzeemin-opensrc.googlecode.com/files/nzeemin.Izh_0.5.jar<br />
oa.weak.BotherBot 0.1,http://robocode-archive.strangeautomata.com/robots/oa.weak.BotherBot_0.1.jar<br />
oa.weak.FlyMk1 0.1,http://robocode-archive.strangeautomata.com/robots/oa.weak.FlyMk1_0.1.jar<br />
ola.Puffin 1.0,http://robocode-archive.strangeautomata.com/robots/ola.Puffin_1.0.jar<br />
omens.CannonfodderMicro 1.4,https://dl.dropbox.com/s/ye675r93lpgpuei/omens.CannonfodderMicro_1.4.jar<br />
omens.CannonfodderNano 1.4,https://dl.dropbox.com/s/u94wp86uo34feue/omens.CannonfodderNano_1.4.jar<br />
oog.melee.Capulet 1.2,https://sites.google.com/site/crazybassoon/oog.melee.Capulet_1.2.jar<br />
oog.melee.Mercutio 1.0,http://robocode-archive.strangeautomata.com/robots/oog.melee.Mercutio_1.0.jar<br />
oog.micro.MagicD3 0.41,http://robocode-archive.strangeautomata.com/robots/oog.micro.MagicD3_0.41.jar<br />
oog.micro.Maui 1.2,http://robocode-archive.strangeautomata.com/robots/oog.micro.Maui_1.2.jar<br />
oog.micro.SavantMicro 1.1,http://robocode-archive.strangeautomata.com/robots/oog.micro.SavantMicro_1.1.jar<br />
oog.mini.AlphaDragon 0.1,http://robocode-archive.strangeautomata.com/robots/oog.mini.AlphaDragon_0.1.jar<br />
oog.nano.Caligula 1.15,http://robocode-archive.strangeautomata.com/robots/oog.nano.Caligula_1.15.jar<br />
oog.nano.Fuatisha 1.1,http://robocode-archive.strangeautomata.com/robots/oog.nano.Fuatisha_1.1.jar<br />
oog.nano.MagicD2 2.4,http://robocode-archive.strangeautomata.com/robots/oog.nano.MagicD2_2.4.jar<br />
oog.nano.SavantVS 1.1,http://robocode-archive.strangeautomata.com/robots/oog.nano.SavantVS_1.1.jar<br />
oog.nano.SavantWS 0.1,http://robocode-archive.strangeautomata.com/robots/oog.nano.SavantWS_0.1.jar<br />
oog.PricklyPear 1.0.6,http://robocode-archive.strangeautomata.com/robots/oog.PricklyPear_1.0.6.jar<br />
ouroboros.Dragon 0.0.3,https://dl.dropboxusercontent.com/u/98946154/robocode/ouroboros.Dragon_0.0.3.jar<br />
pa.Improved 1.1,http://robocode-archive.strangeautomata.com/robots/pa.Improved_1.1.jar<br />
pa3k.Manta 1.20,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Manta_1.20.jar<br />
pa3k.Quark 1.02,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Quark_1.02.jar<br />
pa3k.Viper 5.03,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Viper_5.03.jar<br />
pac.ABC 2.1,https://dl.dropbox.com/u/5439044/Robocode/pac.ABC_2.1.jar<br />
pak.Dargon 1.0b,http://robocode-archive.strangeautomata.com/robots/pak.Dargon_1.0b.jar<br />
pak.JakeTheTestingRobot .1b,http://robocode-archive.strangeautomata.com/robots/pak.JakeTheTestingRobot_.1b.jar<br />
paket.MojRobot 1.0,https://dl.dropbox.com/s/faovho732zgpvq8/paket.MojRobot_1.0.jar?dl=1<br />
panzer.Panzer 0.2,http://robocode-archive.strangeautomata.com/robots/panzer.Panzer_0.2.jar<br />
paolord.TheHulk 1.0,http://robocode-archive.strangeautomata.com/robots/paolord.TheHulk_1.0.jar<br />
patson.PatsonTestBot 1.0,http://robocode-archive.strangeautomata.com/robots/patson.PatsonTestBot_1.0.jar<br />
paulk.PaulV3 1.7,http://robocode-archive.strangeautomata.com/robots/paulk.PaulV3_1.7.jar<br />
pb.Oscillator 1.0,http://robocode-archive.strangeautomata.com/robots/pb.Oscillator_1.0.jar<br />
pbg.NinjaX 1.2,https://github.com/realr2d2/Bots/blob/gh-pages/pbg.NinjaX_1.2.jar?raw=true<br />
pe.mini.SandboxMini 1.2,http://robocode-archive.strangeautomata.com/robots/pe.mini.SandboxMini_1.2.jar<br />
pe.minimelee.SandboxMiniMelee 1.1,http://robocode-archive.strangeautomata.com/robots/pe.minimelee.SandboxMiniMelee_1.1.jar<br />
pe.SandboxDT 3.02,http://robocode-archive.strangeautomata.com/robots/pe.SandboxDT_3.02.jar<br />
pe.SandboxLump 1.52,http://robocode-archive.strangeautomata.com/robots/pe.SandboxLump_1.52.jar<br />
pedersen.Hubris 2.4,http://home.comcast.net/~kokyunage/robocode/hubris/pedersen.Hubris_2.4.jar<br />
pedersen.Ugluk 1.0,http://home.comcast.net/~kokyunage/robocode/ugluk/pedersen.Ugluk_1.0.jar<br />
penguin.Ivy 1.1r,https://sites.google.com/site/robotrepository/penguin.Ivy_1.1r.jar?attredirects=0&d=1<br />
penguin.Joker .611wr,https://sites.google.com/site/robotrepository/penguin.Joker_.611wr.jar?attredirects=0&d=1<br />
penguin.MrFreeze 1.0a,https://sites.google.com/site/robotrepository/penguin.MrFreeze_1.0a.jar?attredirects=0&d=1<br />
pez.clean.Swiffer 0.2.9,http://robocode-archive.strangeautomata.com/robots/pez.clean.Swiffer_0.2.9.jar<br />
pez.frankie.Frankie 0.9.6.1,http://robocode-archive.strangeautomata.com/robots/pez.frankie.Frankie_0.9.6.1.jar<br />
pez.gloom.GloomyDark 0.9.2,http://robocode-archive.strangeautomata.com/robots/pez.gloom.GloomyDark_0.9.2.jar<br />
pez.mako.Mako 1.5,http://robocode-archive.strangeautomata.com/robots/pez.mako.Mako_1.5.jar<br />
pez.micro.Aristocles 0.3.7,http://robocode-archive.strangeautomata.com/robots/pez.micro.Aristocles_0.3.7.jar<br />
pez.mini.ChironexFleckeri 0.5,http://robocode-archive.strangeautomata.com/robots/pez.mini.ChironexFleckeri_0.5.jar<br />
pez.mini.Gouldingi 1.5,http://robocode-archive.strangeautomata.com/robots/pez.mini.Gouldingi_1.5.jar<br />
pez.mini.Pugilist 2.5.1f,https://dl.dropboxusercontent.com/u/3259215/robocode/bots/pez.mini.Pugilist_2.5.1f.jar<br />
pez.mini.Tityus 0.9.1,http://robocode-archive.strangeautomata.com/robots/pez.mini.Tityus_0.9.1.jar<br />
pez.mini.VertiLeach 0.4.0,http://robocode-archive.strangeautomata.com/robots/pez.mini.VertiLeach_0.4.0.jar<br />
pez.nano.Icarus 0.3,http://robocode-archive.strangeautomata.com/robots/pez.nano.Icarus_0.3.jar<br />
pez.nano.LittleEvilBrother 0.1,http://robocode-archive.strangeautomata.com/robots/pez.nano.LittleEvilBrother_0.1.jar<br />
pez.rumble.Ali 0.4.9,http://robocode-archive.strangeautomata.com/robots/pez.rumble.Ali_0.4.9.jar<br />
pez.rumble.CassiusClay 2rho.02no,https://dl.dropboxusercontent.com/u/3259215/robocode/bots/pez.rumble.CassiusClay_2rho.02no.jar<br />
pfvicm.Sobieski 7.2.3b,http://robocode-archive.strangeautomata.com/robots/pfvicm.Sobieski_7.2.3b.jar<br />
ph.micro.Pikeman 0.4.5,http://robocode-archive.strangeautomata.com/robots/ph.micro.Pikeman_0.4.5.jar<br />
ph.mini.Archer 0.6.6,http://robocode-archive.strangeautomata.com/robots/ph.mini.Archer_0.6.6.jar<br />
ph.musketeer.Musketeer 0.6,http://robocode-archive.strangeautomata.com/robots/ph.musketeer.Musketeer_0.6.jar<br />
ph.Thinker 0.2.5,http://robocode-archive.strangeautomata.com/robots/ph.Thinker_0.2.5.jar<br />
pi.Dark 10,http://robocode-archive.strangeautomata.com/robots/pi.Dark_10.jar<br />
PK.Twardy 0.4.2,http://robocode-archive.strangeautomata.com/robots/PK.Twardy_0.4.2.jar<br />
pkbots.BoyTDSurfer 1.0,http://robocode-archive.strangeautomata.com/robots/pkbots.BoyTDSurfer_1.0.jar<br />
pkdeken.Paladin 1.0,http://robocode-archive.strangeautomata.com/robots/pkdeken.Paladin_1.0.jar<br />
PkKillers.PkAssassin 1.0,http://robocode-archive.strangeautomata.com/robots/PkKillers.PkAssassin_1.0.jar<br />
pl.Drum 0.1,http://robocode-archive.strangeautomata.com/robots/pl.Drum_0.1.jar<br />
pl.mskiba.Hilton 0.4,https://dl.dropbox.com/u/1209595/robots/pl.mskiba.Hilton_0.4.jar<br />
pl.Patton.GeneralPatton 1.54,http://robocode-archive.strangeautomata.com/robots/pl.Patton.GeneralPatton_1.54.jar<br />
pl.robocode.Pacyfista 1.0,https://docs.google.com/uc?authuser=0&id=0B3qcr0MebRbCU3hLdHJFTG92cHc&export=download<br />
pla.Memnoch 0.5,http://robocode-archive.strangeautomata.com/robots/pla.Memnoch_0.5.jar<br />
pmc.SniperBot 1.0,http://robocode-archive.strangeautomata.com/robots/pmc.SniperBot_1.0.jar<br />
Polkwane.Intensive 1.0,http://robowiki.net/w/images/1/1d/Polkwane.Intensive_1.0.jar<br />
Polkwane.Piyane 0.7b,https://dl.dropbox.com/s/mztcvf13ab41or5/Polkwane.Piyane_0.7b.jar?token_hash=AAH-IVvOaiKm2CWOaEKosx9APzGrfMWF-jpbOJaY_bFnow&dl=1<br />
populations.TrainStoopidbot 0.01,http://robocode-archive.strangeautomata.com/robots/populations.TrainStoopidbot_0.01.jar<br />
positive.Portia 1.26e,http://robocode-archive.strangeautomata.com/robots/positive.Portia_1.26e.jar<br />
povik.nano.Smilee 0.2.1,http://robocode-archive.strangeautomata.com/robots/povik.nano.Smilee_0.2.1.jar<br />
projectx.ProjectNano 2.0,http://robocode-archive.strangeautomata.com/robots/projectx.ProjectNano_2.0.jar<br />
projectx.TestNano 1.0,http://robocode-archive.strangeautomata.com/robots/projectx.TestNano_1.0.jar<br />
PSW.Relentless 0.1,http://robocode-archive.strangeautomata.com/robots/PSW.Relentless_0.1.jar<br />
pulsar.Nanis 0.3,http://robocode-archive.strangeautomata.com/robots/pulsar.Nanis_0.3.jar<br />
pulsar.PulsarMax 0.8.9,http://robocode-archive.strangeautomata.com/robots/pulsar.PulsarMax_0.8.9.jar<br />
pulsar.PulsarNano 0.2.4,http://robocode-archive.strangeautomata.com/robots/pulsar.PulsarNano_0.2.4.jar<br />
qohnil.blot.BlotBot 3.61,http://robocode-archive.strangeautomata.com/robots/qohnil.blot.BlotBot_3.61.jar<br />
qualidafial.MajorDick 1.0.1,http://dl.dropboxusercontent.com/sh/n570kf8rsq6fuw2/vVQSIJJnAS/qualidafial.MajorDick_1.0.1.jar<br />
Queens_teamrobot.UltraRazor 1.0,http://robocode-archive.strangeautomata.com/robots/Queens_teamrobot.UltraRazor_1.0.jar<br />
quietus.Invader 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/quietus.Invader_0.1.jar<br />
quietus.NarrowRadar 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/quietus.NarrowRadar_0.1.jar<br />
qwaker00.Ahchoo 1.6,https://dl.dropboxusercontent.com/u/29826809/bots/qwaker00.Ahchoo_1.6.j6.jar<br />
qwaker00.Gandhi 1.2,https://dl.dropboxusercontent.com/u/29826809/bots/qwaker00.Gandhi_1.2.j6.jar<br />
racso.Crono 1.0,http://oscargomez.net/files/racso.Crono_1.0.jar<br />
racso.Frog 0.9,http://oscargomez.net/files/racso.Frog_0.9.jar<br />
radnor.DoctorBob 1.42,http://robocode-archive.strangeautomata.com/robots/radnor.DoctorBob_1.42.jar<br />
radnor.RamRod 1.0,http://robocode-archive.strangeautomata.com/robots/radnor.RamRod_1.0.jar<br />
rampancy.Durandal 2.2d,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/rampancy.Durandal_2.2d.jar<br />
rampancy.micro.Epiphron 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/rampancy.micro.Epiphron_1.0.jar<br />
rapture.Rapture 2.13,http://robocode-archive.strangeautomata.com/robots/rapture.Rapture_2.13.jar<br />
ratosh.nano.Debo 1.36,http://robocode-archive.strangeautomata.com/robots/ratosh.nano.Debo_1.36.jar<br />
ratosh.Nobo 0.21,http://robocode-archive.strangeautomata.com/robots/ratosh.Nobo_0.21.jar<br />
ratosh.Wesco 1.4,http://robocode-archive.strangeautomata.com/robots/ratosh.Wesco_1.4.jar<br />
rc.RCBot 2.0,http://robocode-archive.strangeautomata.com/robots/rc.RCBot_2.0.jar<br />
rc.yoda.Yoda 1.0.6c.fix,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/rc.yoda.Yoda_1.0.6c.fix.jar<br />
rcb.Vanessa03 0,http://robocode-archive.strangeautomata.com/robots/rcb.Vanessa03_0.jar<br />
rcp.Kuramatron 1.0,http://robocode-archive.strangeautomata.com/robots/rcp.Kuramatron_1.0.jar<br />
rdt.AgentSmith.AgentSmith 0.5,https://www.dropbox.com/s/qy231hux1ydg9w9/rdt.AgentSmith.AgentSmith_0.5.jar?raw=1<br />
rdt199.Warlord 0.73,http://robocode-archive.strangeautomata.com/robots/rdt199.Warlord_0.73.jar<br />
reaper.Reaper 1.1,http://robocode-archive.strangeautomata.com/robots/reaper.Reaper_1.1.jar<br />
reeder.caden.Elmo 1,http://reederhome.net/colin/Elmo_1.jar<br />
reeder.caden.Grover 1.0,http://reederhome.net/colin/Grover_1.0.jar<br />
reeder.colin.WallGuy3 1.0,http://reederhome.net/colin/WallGuy3_1.0.jar<br />
repositorio.NanoStep 1.0,http://robocode-archive.strangeautomata.com/robots/repositorio.NanoStep_1.0.jar<br />
rfj.Sunburn 1.1,http://robocode-archive.strangeautomata.com/robots/rfj.Sunburn_1.1.jar<br />
rijteam.SmartDodge 1.1,http://robocode-archive.strangeautomata.com/robots/rijteam.SmartDodge_1.1.jar<br />
rjw.RabidWombat 0.71,http://rjw.walkertribe.com/robocode/rjw.RabidWombat_0.71.jar<br />
rnatest.MendelBot 1.0,http://dl.dropboxusercontent.com/s/ci2x5gxbtceo4r2/rnatest.MendelBot_1.0.jar<br />
ROB.TraumaLlama 1.0,http://robocoderepository.com/Controller.jsp?submitAction=downloadClass&id=4344<br />
robar.haiku.Spike 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.haiku.Spike_1.0.jar<br />
robar.micro.Gladius 1.15,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.micro.Gladius_1.15.jar<br />
robar.micro.Kirbyi 1.0,http://hunrobar.freeblog.hu/files/myrobots/robar.micro.Kirbyi_1.0.jar<br />
robar.micro.Topaz 0.25,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.micro.Topaz_0.25.jar<br />
robar.nano.Assertive 0.3,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.nano.Assertive_0.3.jar<br />
robar.nano.BlackWidow 1.3,http://robocode-archive.strangeautomata.com/robots/robar.nano.BlackWidow_1.3.jar<br />
robar.nano.Breeze 0.3,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Breeze_0.3.jar<br />
robar.nano.Mosquito 1.1,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Mosquito_1.1.jar<br />
robar.nano.MosquitoPM 1.0,http://robocode-archive.strangeautomata.com/robots/robar.nano.MosquitoPM_1.0.jar<br />
robar.nano.Prestige 1.0,http://robocode-archive.strangeautomata.com/robots/robar.nano.Prestige_1.0.jar<br />
robar.nano.Pugio 1.49,http://robocode-archive.strangeautomata.com/robots/robar.nano.Pugio_1.49.jar<br />
robar.nano.Scytodes 0.3,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Scytodes_0.3.jar<br />
robar.nano.Vespa 0.95,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Vespa_0.95.jar<br />
robin.SCALPBot 1.0,http://www.fairyapp.com.au/robin.SCALPBot_1.0.jar<br />
robin.ScalpBotC 1.0,http://fairyapp.com.au/robin.ScalpBotC_1.0.jar<br />
robo.PartsBot 1.1,http://robocode-archive.strangeautomata.com/robots/robo.PartsBot_1.1.jar<br />
RobotMarco.MarcoV 0.1,http://robocode-archive.strangeautomata.com/robots/RobotMarco.MarcoV_0.1.jar<br />
romz.robot.circular.WildRabbit 0.9.6, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.circular.WildRabbit_0.9.6.jar<br />
romz.robot.guessfactor.TeasingFox 0.2, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.guessfactor.TeasingFox_0.2.jar<br />
romz.robot.Test 0.1.0, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.Test_0.1.0.jar<br />
rsim.micro.uCatcher 0.1,http://robocode-archive.strangeautomata.com/robots/rsim.micro.uCatcher_0.1.jar<br />
rsim.mini.BulletCatcher 0.4,http://robocode-archive.strangeautomata.com/robots/rsim.mini.BulletCatcher_0.4.jar<br />
rsk1.RSK1 4.0,http://robocode-archive.strangeautomata.com/robots/rsk1.RSK1_4.0.jar<br />
rtk.Tachikoma 1.0,http://robocode-archive.strangeautomata.com/robots/rtk.Tachikoma1.0.jar<br />
ruc.nano.Zealot 0.2,http://robocode-archive.strangeautomata.com/robots/ruc.nano.Zealot_0.2.jar<br />
rus.vv.Dzhigit 1.1,http://robocode-archive.strangeautomata.com/robots/rus.vv.Dzhigit1.1.jar<br />
rus.vv.Snezhok 1.1,http://robocode-archive.strangeautomata.com/robots/rus.vv.Snezhok1.1.jar<br />
ry.LightningBug 1.0,http://robocode-archive.strangeautomata.com/robots/ry.LightningBug_1.0.jar<br />
ry.VirtualGunExperiment 1.2.0,http://robocode-archive.strangeautomata.com/robots/ry.VirtualGunExperiment_1.2.0.jar<br />
ry.Worst 1.0,http://robocode-archive.strangeautomata.com/robots/ry.Worst_1.0.jar<br />
rz.Aleph 0.34,http://robocode-archive.strangeautomata.com/robots/rz.Aleph_0.34.jar<br />
rz.Apollon 0.23,http://robocode-archive.strangeautomata.com/robots/rz.Apollon_0.23.jar<br />
rz.Artist 0.2,http://robocode-archive.strangeautomata.com/robots/rz.Artist_0.2.jar<br />
rz.GlowBlow 2.31,http://robocode-archive.strangeautomata.com/robots/rz.GlowBlow_2.31.jar<br />
rz.GlowBlowAPM 1.0,http://robocode-archive.strangeautomata.com/robots/rz.GlowBlowAPM_1.0.jar<br />
rz.GlowBlowMelee 1.4,http://robocode-archive.strangeautomata.com/robots/rz.GlowBlowMelee_1.4.jar<br />
rz.HawkOnFire 0.1,http://robocode-archive.strangeautomata.com/robots/rz.HawkOnFire_0.1.jar<br />
rz.SmallDevil 1.502,http://robocode-archive.strangeautomata.com/robots/rz.SmallDevil_1.502.jar<br />
sadoner.killer 0.2,http://robocode-archive.strangeautomata.com/robots/sadoner.killer_0.2.jar<br />
sam.ChipmunkDuelist 1.0,http://robocode-archive.strangeautomata.com/robots/sam.ChipmunkDuelist_1.0.jar<br />
sam.Samspin 1.0,http://robocode-archive.strangeautomata.com/robots/sam.Samspin_1.0.jar<br />
sample.Corners 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Corners_1.0.jar<br />
sample.Crazy 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Crazy_1.0.jar<br />
sample.Fire 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Fire_1.0.jar<br />
sample.MyFirstJuniorRobot 1.0,http://robocode-archive.strangeautomata.com//robots/sample.MyFirstJuniorRobot_1.0.jar<br />
sample.MyFirstRobot 1.0,http://robocode-archive.strangeautomata.com/robots/sample.MyFirstRobot_1.0.jar<br />
sample.RamFire 1.0,http://robocode-archive.strangeautomata.com/robots/sample.RamFire_1.0.jar<br />
sample.SittingDuck 1.0,http://robocode-archive.strangeautomata.com/robots/sample.SittingDuck_1.0.jar<br />
sample.SpinBot 1.0,http://robocode-archive.strangeautomata.com/robots/sample.SpinBot_1.0.jar<br />
sample.Target 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Target_1.0.jar<br />
sample.Tracker 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Tracker_1.0.jar<br />
sample.TrackFire 1.0,http://robocode-archive.strangeautomata.com/robots/sample.TrackFire_1.0.jar<br />
sample.VelociRobot 1.0,http://robocode-archive.strangeautomata.com//robots/sample.VelociRobot_1.0.jar<br />
sample.Walls 1.0,http://robocode-archive.strangeautomata.com/robots/sample.Walls_1.0.jar<br />
sanja.First 0.1,https://docs.google.com/uc?export=download&id=0BwXl8v4PYCLialZDZktJR09Ydmc<br />
sanyi.mikrobi.Roberto 1.0,http://robocode-archive.strangeautomata.com/robots/sanyi.mikrobi.Roberto_1.0.jar<br />
satan.R0 0.2,http://satan.so/robocode/satan.R0_0.2.jar<br />
satan.White 0.26,http://satan.so/robocode/satan.White_0.26.jar<br />
sch.Simone 0.3d,http://robocode-archive.strangeautomata.com/robots/sch.Simone_0.3d.jar<br />
scheronimus.AntiRebel 1.1,http://dl.dropboxusercontent.com/s/a80c392snb4iukk/scheronimus.AntiRebel_1.1.jar<br />
scheronimus.NanoScheroBot 1.0,http://dl.dropboxusercontent.com/s/ps150wpts8dsa07/scheronimus.NanoScheroBot_1.0.jar<br />
scheronimus.ScheroBot 2.3,http://dl.dropboxusercontent.com/s/f0eyryuahcjiwhb/scheronimus.ScheroBot_2.3.jar<br />
serenity.moonlightBat 1.17,http://robocode-archive.strangeautomata.com/robots/serenity.moonlightBat_1.17.jar<br />
serenity.nonSense 1.39,http://robocode-archive.strangeautomata.com/robots/serenity.nonSense_1.39.jar<br />
serenity.serenityFire 1.29,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/serenity.serenityFire_1.29.jar<br />
SFS.SamsSecondRobot 1.0,http://robocode-archive.strangeautomata.com/robots/SFS.SamsSecondRobot_1.0.jar<br />
sgp.JollyNinja 3.53,http://robocode-archive.strangeautomata.com/robots/sgp.JollyNinja_3.53.jar<br />
sgp.MadHatter 4.13,http://robocode-archive.strangeautomata.com/robots/sgp.MadHatter_4.13.jar<br />
sgp.nano.FurryLeech 1.0,http://robocode-archive.strangeautomata.com/robots/sgp.nano.FurryLeech_1.0.jar<br />
sgp.ShiningBeetle 1.1,http://robocode-archive.strangeautomata.com/robots/sgp.ShiningBeetle_1.1.jar<br />
sgp.SleepingGoat 1.1,http://robocode-archive.strangeautomata.com/robots/sgp.SleepingGoat_1.1.jar<br />
SHAM.WOW 1.4,http://robocode-archive.strangeautomata.com/robots/SHAM.WOW_1.4.jar<br />
sheldor.melee.nano.TestMelee 0.1,http://robocode-archive.strangeautomata.com/robots/sheldor.melee.nano.TestMelee_0.1.jar<br />
sheldor.micro.EpeeistMicro 2.1.0,http://www.robocoderepository.com/BotFiles/4343/sheldor.micro.EpeeistMicro_2.1.0.jar<br />
sheldor.micro.FoilistMicro 1.2.0,http://www.robocoderepository.com/BotFiles/4341/sheldor.micro.FoilistMicro_1.2.0.jar<br />
sheldor.nano.Epeeist 1.1.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.Epeeist_1.1.0.jar<br />
sheldor.nano.Foilist 2.0.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.Foilist_2.0.0.jar<br />
sheldor.nano.PointInLine 1.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.PointInLine_1.0.jar<br />
sheldor.nano.PointInLineRRAL 1.0.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.PointInLineRRAL_1.0.0.jar<br />
sheldor.nano.Retreat 1.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.Retreat_1.0.jar<br />
sheldor.nano.Sabreur 1.1.2,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.Sabreur_1.1.2.jar<br />
sheldor.nano.Sabreuse 1.0.0,http://robocode-archive.strangeautomata.com/robots/sheldor.nano.Sabreuse_1.0.0.jar<br />
shinh.Entangled 0.3,http://robocode-archive.strangeautomata.com/robots/shinh.Entangled_0.3.jar<br />
shrub.Silver v048,http://robocode-archive.strangeautomata.com/robots/shrub.Silver_v048.jar<br />
shrub.Vapour v159,http://robocode-archive.strangeautomata.com/robots/shrub.Vapour_v159.jar<br />
shu.nitro.LENIN .T34,http://robocode-archive.strangeautomata.com/robots/shu.nitro.LENIN_.T34.jar<br />
sigterm.Sigterm 1.0,http://robocode-archive.strangeautomata.com/robots/sigterm.Sigterm_1.0.jar<br />
simonton.beta.LifelongObsession 0.5.1,http://robocode-archive.strangeautomata.com/robots/simonton.beta.LifelongObsession_0.5.1.jar<br />
simonton.GFNano_D 3.1b,http://robocode-archive.strangeautomata.com/robots/simonton.GFNano_D_3.1b.jar<br />
simonton.mega.SniperFrog 1.0.fix2,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/simonton.mega.SniperFrog_1.0.fix2.jar<br />
simonton.micro.GFMicro 1.0,http://robocode-archive.strangeautomata.com/robots/simonton.micro.GFMicro_1.0.jar<br />
simonton.micro.WeeklongObsession 3.4.1,http://robocode-archive.strangeautomata.com/robots/simonton.micro.WeeklongObsession_3.4.1.jar<br />
simonton.mini.WeeksOnEnd 1.10.4,http://robocode-archive.strangeautomata.com/robots/simonton.mini.WeeksOnEnd_1.10.4.jar<br />
simonton.nano.WeekendObsession_S 1.7,http://robocode-archive.strangeautomata.com/robots/simonton.nano.WeekendObsession_S_1.7.jar<br />
SK.SimpleKiller 1.0,http://robocode-archive.strangeautomata.com/robots/SK.SimpleKiller_1.0.jar<br />
skm.butterfly 1.0,http://robocode-archive.strangeautomata.com/robots/sean1.jar<br />
skm.PateranBotlock2 1.0,http://robocode-archive.strangeautomata.com/robots/skm.PateranBotlock2_1.0.jar<br />
skm.Ryubot 1.0,http://robocode-archive.strangeautomata.com/robots/skm.Ryubot_1.0.jar<br />
sL300.Mozart life,http://robocode-archive.strangeautomata.com/robots/sL300.Mozart_life.jar<br />
sm.Devil 7.3,http://robocode-archive.strangeautomata.com/robots/sm.Devil_7.3.jar<br />
sng.arco.Arco 0.0,http://robocode-archive.strangeautomata.com/robots/sng.arco.Arco_0.0.jar<br />
snowman.Snowman 1.0,https://www.dropbox.com/s/07yb1c628if7kix/snowman.Snowman_1.0.jar?dl=1<br />
sos.SOS 1.0,http://robocode-archive.strangeautomata.com/robots/sos.SOS_1.0.jar<br />
sp.AstherNano 1.0,https://www.dropbox.com/s/08yerucbu0an8sm/sp.AstherNano_1.0.jar?dl=1<br />
spartancompany.Spartan2 1.0,http://robocode-archive.strangeautomata.com/robots/spartancompany.Spartan2_1.0.jar<br />
spin.Bugstard 0.012b,https://dl.dropbox.com/s/jvm89xy5z5911ws/spin.Bugstard_0.012b.jar?dl=1<br />
spinnercat.CopyKat 1.2.3,http://robocode-archive.strangeautomata.com/robots/spinnercat.CopyKat_1.2.3.jar<br />
spinnercat.haiku.Refrigerator 1.1,http://robocode-archive.strangeautomata.com/robots/spinnercat.haiku.Refrigerator_1.1.jar<br />
spinnercat.Kitten 1.6,http://robocode-archive.strangeautomata.com/robots/spinnercat.Kitten_1.6.jar<br />
spinnercat.Limit .01,http://robocode-archive.strangeautomata.com/robots/spinnercat.Limit_.01.jar<br />
spinnercat.mega.Tardis 1.2,http://robocode-archive.strangeautomata.com/robots/spinnercat.mega.Tardis_1.2.jar<br />
spinnercat.Robovirus 2.718,http://robocode-archive.strangeautomata.com/robots/spinnercat.Robovirus_2.718.jar<br />
sqTank.waveSurfing.LionWWSVMvoid 0.01,http://robocode-archive.strangeautomata.com/robots/sqTank.waveSurfing.LionWWSVMvoid_0.01.jar<br />
squidM.SquidmanNano 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/squidM.SquidmanNano_1.0.jar<br />
squidM.SurfinUSA 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/squidM.SurfinUSA_1.0.jar<br />
starpkg.StarViewerZ 1.26,http://robocode-archive.strangeautomata.com/robots/starpkg.StarViewerZ_1.26.jar<br />
staticline.whiskey.Whiskey 0.6,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/staticline.whiskey.Whiskey_0.6.jar<br />
steff.Rebel 2.1,http://dl.dropboxusercontent.com/s/1lqsc0cxaip4wdf/steff.Rebel_2.1.jar<br />
stefw.Tigger 0.0.23,http://robocode-archive.strangeautomata.com/robots/stefw.Tigger_0.0.23.jar<br />
stelo.Chord 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.Chord_1.0.jar<br />
stelo.FretNano 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.FretNano_1.1.jar<br />
stelo.Lifestealer 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.Lifestealer_1.0.jar<br />
stelo.MatchupAGF 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupAGF_1.1.jar<br />
stelo.MatchupMicro 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupMicro_1.2.jar<br />
stelo.MatchupMini 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupMini_1.1.jar<br />
stelo.MatchupWS 1.2c,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupWS_1.2c.jar<br />
stelo.Mirror 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.Mirror_1.1.jar<br />
stelo.MirrorMicro 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MirrorMicro_1.1.jar<br />
stelo.MirrorNano 1.4,http://robocode-archive.strangeautomata.com/robots/stelo.MirrorNano_1.4.jar<br />
stelo.MoojukNano 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.MoojukNano_1.2.jar<br />
stelo.PastFuture 2.1.9,http://robocode-archive.strangeautomata.com/robots/stelo.PastFuture_2.1.9.jar<br />
stelo.PatternRobot 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.PatternRobot_1.0.jar<br />
stelo.PianistNano 1.3,http://robocode-archive.strangeautomata.com/robots/stelo.PianistNano_1.3.jar<br />
stelo.RamTrackSurfer 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.RamTrackSurfer_1.2.jar<br />
stelo.Randomness 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.Randomness_1.1.jar<br />
stelo.Spread 0.3,http://www.robowiki.net/w/images/a/a5/Stelo.Spread_0.3.jar<br />
stelo.SteloTestNano 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.SteloTestNano_1.0.jar<br />
stelo.UnfoolableNano 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.UnfoolableNano_1.0.jar<br />
stelo.UntouchableNano 1.4,http://robocode-archive.strangeautomata.com/robots/stelo.UntouchableNano_1.4.jar<br />
step.NanoBidu 1.0,http://robocode-archive.strangeautomata.com/robots/step.NanoBidu_1.0.jar<br />
step.nanoPri 1.0,http://robocode-archive.strangeautomata.com/robots/step.nanoPri_1.0.jar<br />
stf.PanzerGeneral 0.1,http://robocode-archive.strangeautomata.com/robots/stf.PanzerGeneral_0.1.jar<br />
stordy.StordyBot 1.0,http://robocode-archive.strangeautomata.com/robots/stordy.StordyBot_1.0.jar<br />
stranger.nano.TestBot 1.0,https://dl.dropboxusercontent.com/u/18119890/stranger.nano.TestBot_1.0.jar<br />
strider.Festis 1.2.1,http://robocode-archive.strangeautomata.com/robots/strider.Festis_1.2.1.jar<br />
strider.Mer 1.1.0,http://robocode-archive.strangeautomata.com/robots/strider.Mer_1.1.0.jar<br />
stuff.Vlad 0.1,http://robocode-archive.strangeautomata.com/robots/stuff.Vlad_0.1.jar<br />
suh.mega.WaveSurferGF 1.04,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.mega.WaveSurferGF_1.04.jar<br />
suh.mega.WaveSurferPG 1.06,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.mega.WaveSurferPG_1.06.jar<br />
suh.micro.MirrorPM 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.micro.MirrorPM_1.00.jar<br />
suh.micro.WallPM 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.micro.WallPM_1.00.jar<br />
suh.nano.AngularMirrorC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.AngularMirrorC_1.00.jar<br />
suh.nano.AntiGravityL 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.AntiGravityL_1.01.jar<br />
suh.nano.CornerRL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CornerRL_1.00.jar<br />
suh.nano.CrossC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossC_1.00.jar<br />
suh.nano.CrossH 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossH_1.00.jar<br />
suh.nano.CrossL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossL_1.00.jar<br />
suh.nano.MirrorH 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MirrorH_1.01.jar<br />
suh.nano.MirrorL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MirrorL_1.00.jar<br />
suh.nano.MyFirstAdvancedRobot 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MyFirstAdvancedRobot_1.00.jar<br />
suh.nano.OscillatorL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.OscillatorL_1.00.jar<br />
suh.nano.RammingC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.RammingC_1.00.jar<br />
suh.nano.RandomPM 1.02,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.RandomPM_1.02.jar<br />
suh.nano.StopAndGoL 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.StopAndGoL_1.01.jar<br />
suh.nano.TargetC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetC_1.00.jar<br />
suh.nano.TargetH 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetH_1.00.jar<br />
suh.nano.TargetL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetL_1.00.jar<br />
suh.nano.TargetR 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetR_1.00.jar<br />
suh.nano.Worst 1.02,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.Worst_1.02.jar<br />
sul.Bicephal 1.2,http://robocode-archive.strangeautomata.com/robots/sul.Bicephal_1.2.jar<br />
sul.BlueBot 1.0,http://robocode-archive.strangeautomata.com/robots/sul.BlueBot_1.0.jar<br />
sul.NanoR2 1.32,http://robocode-archive.strangeautomata.com/robots/sul.NanoR2_1.32.jar<br />
sul.Pinkbot 1.1,http://robocode-archive.strangeautomata.com/robots/sul.Pinkbot_1.1.jar<br />
supersample.SuperBoxBot 1.0,http://robocode-archive.strangeautomata.com/robots/supersample.SuperBoxBot_1.0.jar<br />
supersample.SuperCorners 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperCorners_1.0.jar<br />
SuperSample.SuperCrazy 1.0,http://robocode-archive.strangeautomata.com/robots/SuperSample.SuperCrazy_1.0.jar<br />
supersample.SuperMercutio 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperMercutio_1.0.jar<br />
supersample.SuperRamFire 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperRamFire_1.0.jar<br />
supersample.SuperSpinBot 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperSpinBot_1.0.jar<br />
supersample.SuperTracker 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperTracker_1.0.jar<br />
supersample.SuperTrackFire 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperTrackFire_1.0.jar<br />
supersample.SuperWalls 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperWalls_1.0.jar<br />
suzushin7.nano.Galaxy01 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suzushin7.nano.Galaxy01_1.01.jar<br />
suzushin7.nano.Galaxy02 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suzushin7.nano.Galaxy02_1.01.jar<br />
suzushin7.nano.Galaxy03 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suzushin7.nano.Galaxy03_1.01.jar<br />
suzushin7.nano.TargetC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suzushin7.nano.TargetC_1.00.jar<br />
syl.Centipede 0.5,http://robocode-archive.strangeautomata.com/robots/syl.Centipede_0.5.jar<br />
synapse.Geomancy 15,http://robocode-archive.strangeautomata.com/robots/synapse.Geomancy_15.jar<br />
synapse.rsim.GeomancyBS 0.11,http://robocode-archive.strangeautomata.com/robots/synapse.rsim.GeomancyBS_0.11.jar<br />
synnalagma.NeuralPremier 0.51,http://robocode-archive.strangeautomata.com/robots/synnalagma.NeuralPremier_0.51.jar<br />
synnalagma.test.MiniNeural 1.1,http://robocode-archive.strangeautomata.com/robots/synnalagma.test.MiniNeural_1.1.jar<br />
t3.Ripper 1.0,https://www.dropbox.com/s/t3rxtjyw490zjbe/t3.Ripper_1.0.jar?dl=1<br />
tad.Dalek98 0.98,http://robocode-archive.strangeautomata.com/robots/tad.Dalek98_0.98.jar<br />
takeBot.SpinSpiral 1.2,http://robocode-archive.strangeautomata.com/robots/takeBot.SpinSpiral_1.2.jar<br />
takeBot.SpiralCrash 1.0,http://robocode-archive.strangeautomata.com/robots/takeBot.SpiralCrash_1.0.jar<br />
takeBot.WeavingWiggle 1.1,http://robocode-archive.strangeautomata.com/robots/takeBot.WeavingWiggle_1.1.jar<br />
tango.Recrimpo 2.51,http://robocode-archive.strangeautomata.com/robots/tango.Recrimpo_2.51.jar<br />
taqho.taqbot 1.0,http://robocode-archive.strangeautomata.com/robots/taqho.taqbot_1.0.jar<br />
tcf.Drifter 29,http://www.7sun.com/robocode/robots/tcf.Drifter_29.jar<br />
tcf.Repat3 2,http://robocode-archive.strangeautomata.com/robots/tcf.Repat3_2.jar<br />
TCMI.Enyo 0.4,http://www.timthegeek.com/other/robocode/TCMI.Enyo_0.4.jar<br />
TCMI.nano.Copper 0.2,http://www.timthegeek.com/other/robocode/TCMI.nano.Copper_0.2.jar<br />
techdude.Class2C.Class2C 0.1,http://robocode-archive.strangeautomata.com/robots/techdude.Class2C.Class2C_0.1.jar<br />
techdude.kombat.FlamingKombat 1.5,http://robocode-archive.strangeautomata.com/robots/techdude.kombat.FlamingKombat_1.5.jar<br />
test.Fuzzer 1.0.1,http://robocode-archive.strangeautomata.com/robots/test.Fuzzer_1.0.1.jar<br />
test.Podgy 4.0,http://robocode-archive.strangeautomata.com/robots/test.Podgy_4.0.jar<br />
testantiswapgun.AntiSwap 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/testantiswapgun.AntiSwap_1.0.jar<br />
tex.Longbot 0.4,https://sites.google.com/a/pelt.cc/pelt/home/my-roborcode-project/tex.Longbot_0.4.jar?attredirects=0&d=1<br />
theo.avenge.Pequod 1.0,https://sites.google.com/site/robotrepository/theo.avenge.Pequod_1.0.jar?attredirects=0&d=1<br />
theo.Hydrogen 2.1r,https://sites.google.com/site/robotrepository/theo.Hydrogen_2.1r.jar?attredirects=0&d=1<br />
theo.QuarkSoup 1.5fga,https://sites.google.com/site/robotrepository/theo.QuarkSoup_1.5fga.jar?attredirects=0&d=1<br />
theo.real.Ahab 1.0,https://sites.google.com/site/robotrepository/theo.real.Ahab_1.0.jar?attredirects=0&d=1<br />
theo.simple.Bones 1.0,https://sites.google.com/site/robotrepository/theo.simple.Bones_1.0.jar?attredirects=0&d=1<br />
theo.simple.Lucid 1.0,https://sites.google.com/site/robotrepository/theo.simple.Lucid_1.0.jar?attredirects=0&d=1<br />
theo.Tungsten 1.0a,https://sites.google.com/site/robotrepository/theo.Tungsten_1.0a.jar?attredirects=0&d=1<br />
throxbot.ThroxBot 0.1,http://robocode-archive.strangeautomata.com/robots/throxbot.ThroxBot_0.1.jar<br />
tide.pear.Pear 0.62.1,http://robocode-archive.strangeautomata.com/robots/tide.pear.Pear_0.62.1.jar<br />
timmit.micro.TimXJ 0.22,http://robocode-archive.strangeautomata.com/robots/timmit.micro.TimXJ_0.22.jar<br />
timmit.mini.TimVA 0.43,http://robocode-archive.strangeautomata.com/robots/timmit.mini.TimVA_0.43.jar<br />
timmit.nano.TimCat 0.13,http://robocode-archive.strangeautomata.com/robots/timmit.nano.TimCat_0.13.jar<br />
timmit.nano.TimDog 0.33,http://robocode-archive.strangeautomata.com/robots/timmit.nano.TimDog_0.33.jar<br />
timmit.TimmiT 0.22,http://robocode-archive.strangeautomata.com/robots/timmit.TimmiT_0.22.jar<br />
TJ.Exupery 1.39,http://robocode-archive.strangeautomata.com/robots/TJ.Exupery1.39.jar<br />
tjk.AFlatNatural 1.0,https://dl.dropboxusercontent.com/u/75978227/tjk.AFlatNatural_1.0.jar<br />
tjk.deBroglie rev0108,https://dl.dropboxusercontent.com/u/75978227/tjk.deBroglie_rev0108.jar<br />
tk.BotOX 0.3,http://www.physikus-klenk.de/robocode/tk.BotOX_0.3.jar<br />
tkt.RedShift 1.1.CS.0,https://github.com/ttaomae/robocode-tkt-redshift/raw/codesize/release/tkt.RedShift_1.1.CS.0.jar<br />
tlp.ThreeLeggedPig 1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/tlp.ThreeLeggedPig_1.jar<br />
tm.Yuugao 1.0,http://robocode-archive.strangeautomata.com/robots/tm.Yuugao_1.0.jar<br />
tobe.calypso.Calypso 4.1,http://robocode-archive.strangeautomata.com/robots/tobe.calypso.Calypso_4.1.jar<br />
tobe.Fusion 1.0,http://robocode-archive.strangeautomata.com/robots/tobe.Fusion_1.0.jar<br />
tobe.mini.Charon 0.9,http://robocode-archive.strangeautomata.com/robots/tobe.mini.Charon_0.9.jar<br />
tobe.Relativity 3.9,http://robocode-archive.strangeautomata.com/robots/tobe.Relativity_3.9.jar<br />
tobe.Saturn lambda,http://robocode-archive.strangeautomata.com/robots/tobe.Saturn_lambda.jar<br />
tornyil.bottomup.BottomUp 1.05,http://www.alpha-consulting.hu/robo/tornyil.bottomup.BottomUp_1.05.jar<br />
tornyil.Lajcsi2.Lajcsi2sm 1.0,http://www.alpha-consulting.hu/robo/tornyil.Lajcsi2.Lajcsi2sm_1.0.jar<br />
toz.Gnome 1.1,http://robocode-archive.strangeautomata.com/robots/toz.Gnome_1.1.jar<br />
trab.Crusader 0.1.7,http://www.stud.ntnu.no/~grashei/bots/trab.Crusader_0.1.7.jar<br />
trab.nano.AinippeNano 1.3,http://www.stud.ntnu.no/~grashei/bots/trab.nano.AinippeNano_1.3.jar<br />
traker.Eraser 1,http://robocode-archive.strangeautomata.com/robots/traker.Eraser_1.jar<br />
trm.Wrekt 1.1.6.f,https://dl.dropboxusercontent.com/s/tpv2gujuboxqot1/trm.Wrekt_1.1.6.f.jar?dl=1<br />
tvv.micro.Antares 1.1.1,https://sites.google.com/site/tvvrobots/tvv.micro.Antares_1.1.1.jar?attredirects=0&d=1<br />
tvv.nano.Polaris 1.2,https://sites.google.com/site/tvvrobots/tvv.nano.Polaris_1.2.jar?attredirects=0&d=1<br />
tw.Exterminator 1.0,http://robocode-archive.strangeautomata.com/robots/tw.Exterminator_1.0.jar<br />
tzu.TheArtOfWar 1.2,http://robocode-archive.strangeautomata.com/robots/tzu.TheArtOfWar_1.2.jar<br />
ua.kiiv.kosyak.robocode.tn1.Tn1 2.0,http://robocode-archive.strangeautomata.com/robots/ua.kiiv.kosyak.robocode.tn1.Tn1_2.0.jar<br />
uccc.Dorito 1.12,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.Dorito_1.12.jar<br />
uccc.MilkyWay 1.01,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.MilkyWay_1.01.jar<br />
uccc.RingDing 1.12,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.RingDing_1.12.jar<br />
uccc.Scrapple 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.Scrapple_1.0.jar<br />
ultra.Defender 1.2,http://teamgallego.com/dl/bots/ultra.Defender_1.2.jar<br />
unarmedlad.nano.VirginSteele 2.2,https://dl.dropbox.com/s/nt32eas7mzp7wbe/unarmedlad.nano.VirginSteele_2.2.jar<br />
urdos.URDOS 1.3,http://robocode-archive.strangeautomata.com/robots/urdos.URDOS_1.3.jar<br />
usa.nano.Nemo 2.0,http://robocode-archive.strangeautomata.com/robots/usa.nano.Nemo_2.0.jar<br />
velas.Alpha 1.0,https://www.dropbox.com/s/30rqwdjtbg9cyq7/velas.Alpha_1.0.jar?dl=1<br />
velas.Beta_2_0,https://www.dropbox.com/s/3kyftgk3r48h3lj/velas.Beta_2_0_2.0.jar?dl=1<br />
vft.Hrist 1.0,http://robocode-archive.strangeautomata.com/robots/vft.Hrist_1.0.jar<br />
vft.Valkyrie 1.0,http://robocode-archive.strangeautomata.com/robots/vft.Valkyrie_1.0.jar<br />
vic.Locke 0.7.5.5,http://robocode-archive.strangeautomata.com/robots/vic.Locke_0.7.5.5.jar<br />
vjik.UnViolation 1.1,http://robocode-archive.strangeautomata.com/robots/vjik.UnViolation_1.1.jar<br />
voidious.Diamond 1.8.22,http://robocode-archive.strangeautomata.com/robots/voidious.Diamond_1.8.22.jar<br />
voidious.Dookious 1.573c,https://dl.dropbox.com/u/72179384/voidious.Dookious_1.573c.jar<br />
voidious.micro.Jen 1.11,https://dl.dropbox.com/u/72179384/voidious.micro.Jen_1.11.jar<br />
voidious.mini.Komarious 1.88,https://dl.dropbox.com/u/72179384/voidious.mini.Komarious_1.88.jar<br />
voidious.perceptual.RetroGirl 1.0.0,https://dl.dropbox.com/u/72179384/voidious.perceptual.RetroGirl_1.0.0.jar<br />
voidious.Robot001 1.0,https://dl.dropboxusercontent.com/s/0czb1a40aa0c21b/voidious.Robot001_1.0.jar<br />
vort.Chaser 0.0.3,https://github.com/Vort/Chaser/blob/master/packed/vort.Chaser_0.0.3.jar?raw=true<br />
vStar.RAFzilla 2.10,https://sites.google.com/site/vstarrobocode/fil/vStar.RAFzilla_2.10.jar?attredirects=0&d=1<br />
vuen.Fractal 0.55,http://robocode-archive.strangeautomata.com/robots/vuen.Fractal_0.55.jar<br />
WarfaJibril.Jibril_Warfa_Andromeda 1.11,http://robocode-archive.strangeautomata.com/robots/WarfaJibril.Jibril_Warfa_Andromeda_1.11.jar<br />
wcsv.Engineer.Engineer 0.5.4,http://robocode-archive.strangeautomata.com/robots/wcsv.Engineer.Engineer_0.5.4.jar<br />
wcsv.mega.PowerHouse2 0.2,http://robocode-archive.strangeautomata.com/robots/wcsv.mega.PowerHouse2_0.2.jar<br />
wcsv.PowerHouse.PowerHouse 1.7e3,http://robocode-archive.strangeautomata.com/robots/wcsv.PowerHouse.PowerHouse_1.7e3.jar<br />
wcsv.Stampede 1.3.3,http://robocode-archive.strangeautomata.com/robots/wcsv.Stampede_1.3.3.jar<br />
wcsv.Stampede2.Stampede2 1.1.0,http://robocode-archive.strangeautomata.com/robots/wcsv.Stampede2.Stampede2_1.1.0.jar<br />
WdV.Lesserbee 0.01,http://robocode-archive.strangeautomata.com/robots/WdV.Lesserbee_0.01.jar<br />
whind.Constitution 0.7.1,http://robocode-archive.strangeautomata.com/robots/whind.Constitution_0.7.1.jar<br />
whind.Strength 0.6.4,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/whind.Strength_0.6.4.jar<br />
whind.StrengthBee 0.6.4,http://whindgames.50webs.com/otherstuff/whind.StrengthBee_0.6.4.jar<br />
whind.Wisdom 0.5.1,http://robocode-archive.strangeautomata.com/robots/whind.Wisdom_0.5.1.jar<br />
whitesquare.robots.SkynetAdvanced 1.1,https://dl.dropbox.com/s/6epm51goxqp7p0h/whitesquare.robots.SkynetAdvanced_1.1.jar?dl=1<br />
WidowMakersAtWar.EpicCow 1.0,https://sites.google.com/site/dereksrobots/home/epiccow/WidowMakersAtWar.EpicCow_1.0.jar?attredirects=0&d=1<br />
wiki.BasicBulletShielder 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.BasicBulletShielder_1.0.jar<br />
wiki.BasicGFSurfer 1.02,http://robocode-archive.strangeautomata.com/robots/wiki.BasicGFSurfer_1.02.jar<br />
wiki.mako.MakoHT 1.2.2.1,http://robocode-archive.strangeautomata.com/robots/wiki.mako.MakoHT_1.2.2.1.jar<br />
wiki.mini.BlackDestroyer 0.9.0,http://robocode-archive.strangeautomata.com/robots/wiki.mini.BlackDestroyer_0.9.0.jar<br />
wiki.mini.GouldingiHT 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.mini.GouldingiHT_1.0.jar<br />
wiki.mini.Griffon 0.1,http://robocode-archive.strangeautomata.com/robots/wiki.mini.Griffon_0.1.jar<br />
wiki.mini.Sedan 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.mini.Sedan_1.0.jar<br />
wiki.nano.DevilFISH 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.nano.DevilFISH_1.0.jar<br />
wiki.nano.RaikoNano 1.1,http://robocode-archive.strangeautomata.com/robots/wiki.nano.RaikoNano_1.1.jar<br />
wiki.SuperSampleBot.SuperSittingDuck 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.SuperSampleBot.SuperSittingDuck_1.0.jar<br />
wiki.WaveRammer 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.WaveRammer_1.0.jar<br />
wiki.Wolverine 2.1,http://robocode-archive.strangeautomata.com/robots/wiki.Wolverine_2.1.jar<br />
wilson.Chameleon 0.91,http://robocode-archive.strangeautomata.com/robots/wilson.Chameleon_0.91.jar<br />
winamp32.micro.MicroMacro 1.0,http://robocode-archive.strangeautomata.com/robots/winamp32.micro.MicroMacro_1.0.jar<br />
wit.Chuliath 1.0,http://robocode-archive.strangeautomata.com/robots/wit.Chuliath_1.0.jar<br />
wit.Deep7 2.0,http://robocode-archive.strangeautomata.com/robots/wit.Deep7_2.0.jar<br />
wompi.Kowari 1.6,http://www.casepool.de/robocode/wompi.Kowari_1.6.jar<br />
wompi.Numbat 1.9,http://www.casepool.de/robocode/wompi.Numbat_1.9.jar<br />
xander.cat.Fiona 1.4,http://www.distantvisions.net/robocode/xander.cat.Fiona_1.4.jar<br />
xander.cat.Mikey 1.2,http://www.distantvisions.net/robocode/xander.cat.Mikey_1.2.jar<br />
xander.cat.SamAxe 1.1,http://www.distantvisions.net/robocode/xander.cat.SamAxe_1.1.jar<br />
xander.cat.Spitfire 1.4,http://www.distantvisions.net/robocode/xander.cat.Spitfire_1.4.jar<br />
xander.cat.XanderCat 12.9,http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
xiongan.Xiongan 1.1,http://robocode-archive.strangeautomata.com/robots/xiongan.Xiongan_1.1.jar<br />
yabot.YaBot 0.1,http://robocode-archive.strangeautomata.com/robots/yabot.YaBot_0.1.jar<br />
yagami.Tidus 0.11,http://robocode-archive.strangeautomata.com/robots/yagami.Tidus_0.11.jar<br />
yarghard.Y101 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/yarghard.Y101_1.0.jar<br />
yarhoslav.YaroBot 1.2,http://yarhoslav.260mb.net/robot/yarhoslav.YaroBot_1.2.jar<br />
yk.JahMicro 1.0,http://robocode-archive.strangeautomata.com/robots/yk.JahMicro_1.0.jar<br />
yk.JahRoslav 1.1,http://robocode-archive.strangeautomata.com/robots/yk.JahRoslav_1.1.jar<br />
zch.David 0.21,http://robocode-archive.strangeautomata.com/robots/zch.David_0.21.jar<br />
zch.Hirkan 0.11,http://robocode-archive.strangeautomata.com/robots/zch.Hirkan_0.11.jar<br />
zen.Lindada 0.2,http://robocode-archive.strangeautomata.com/robots/zen.Lindada_0.2.jar<br />
zeze2.OperatorZeze 1.05,http://robocode-archive.strangeautomata.com/robots/zeze2.OperatorZeze_1.05.jar<br />
zezinho.QuerMePegarKKKK 1.0,http://www.vamoslogo.com.br/zezinho.QuerMePegarKKKK_1.0.jar<br />
zh.UnderDog 0.0.2,http://robocode-archive.strangeautomata.com/robots/zh.UnderDog_0.0.2.jar<br />
zignd.ZigIndexOutOfRange 1.1,https://dl.dropboxusercontent.com/s/fbq6nfybjjemp34/zignd.ZigIndexOutOfRange_1.1.jar<br />
zyx.mega.YersiniaPestis 3.0,http://robocode-archive.strangeautomata.com/robots/zyx.mega.YersiniaPestis_3.0.jar<br />
zyx.micro.Ant 1.1,http://robocode-archive.strangeautomata.com/robots/zyx.micro.Ant_1.1.jar<br />
zyx.nano.Ant 1.1,http://robocode-archive.strangeautomata.com/robots/zyx.nano.Ant_1.1.jar<br />
zyx.nano.EscherichiaColi 1.0,http://robocode-archive.strangeautomata.com/robots/zyx.nano.EscherichiaColi_1.0.jar<br />
zyx.nano.RedBull 1.0,http://robocode-archive.strangeautomata.com/robots/zyx.nano.RedBull_1.0.jar<br />
zzx.Gron 1.14,http://robocode-archive.strangeautomata.com/robots/zzx.Gron_1.14.jar<br />
zzx.Ignohis 8.0,https://sites.google.com/site/devonrobots/home/wave-surfers/zzx.Ignohis_8.0.jar?attredirects=0&d=1<br />
zzx.Serunyr 2.0.2,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/zzx.Serunyr_2.0.2.jar<br />
zzx.StormHead 1.0.1,http://robocode-archive.strangeautomata.com/robots/zzx.StormHead_1.0.1.jar<br />
</pre><br />
----<br />
'''''No chatting on this page. Use the /ParticipantsChat page for that.'''''<br />
<br />
'''''Removed due to Igniring ... ,SERVER output in client'''''<br />
''uji.SiberianKhatru 2.0,https://files.itslearning.com/data/ntnu/117178/uji.SiberianKhatru_2.0.jar<br />
<br />
'''''Removed due to it is an invalid robot or team'''''<br />
''kurt.robot.KurtWaveSurfer 1.6,https://www.dropbox.com/s/9342wwl7jje7j4n/kurt.robot.KurtWaveSurfer_1.6.jar?dl=1<br />
''me.rishshadra.Ouranos 1.0,http://rishshadra.me/robocode/me.rishshadra.Ouranos_1.0.jar<br />
''me.rishshadra.Poseidon 1.0,http://rishshadra.me/robocode/me.rishshadra.Poseidon_1.0.jar<br />
''too.TheOnlyOne 1.0,https://www.dropbox.com/s/f76cakv284vo1o2/too.TheOnlyOne_1.0.jar?dl=1<br />
<br />
'''''Removed because Could not download'''''<br />
''Bemo.Sweet30 1.6.1,http://www.stg-volleyball.de/images/Bemo.Sweet30_1.6.1.jar<br />
''xyzdev.SimpleJack 1.1.1,https://xyzdev.webfactional.com/archive/xyzdev.SimpleJack_1.1.1.jar<br />
''ivor.prophet.Prophet 0.01,http://www.ivan.php5.sk/ivor.prophet.Prophet_0.01.jar<br />
<br />
<br />
'''''Removed due to Out Of Memory Exceptions in long battles'''''<br />
cs.ags.Scarlet 1.1c,http://file.csdgn.org/robocode/cs.ags.Scarlet_1.1c.jar<br />
<br />
'''''Removed because the jarcontent/filename is not correct'''''<br><br />
''cberendt.Bot1 0.160''<br><br />
''dmsr.MiniR101 0.6''<br><br />
''henriquevilela.TieFighter 0.1,3224''<br><br />
''jgap.Aspirant_7980_gen7 1.0,3552''br><br />
''jgap.Aspirant_13029_gen7 1.0,3553''<br><br />
''techdude.Carruthers 1.2.6''<br><br />
''uccc.Orbiter 1.0''<br><br />
''WhoAmI.WhoAmI 1.00''<br><br />
''Nucleii.ED4 1.0''<br><br />
''xatu.MySecondRobot 0.1''<br />
<br><br />
<br />
'''''Removed until file corruption is resolved:'''''<br />
<br />
''cas.CelsoKiller 1.0,3465''<br />
<br />
'''''Removed due to almost always giving '0' scores:'''''<br />
<br />
''lazarecki.PinkerStinker 0.1,http://www.robocoderepository.com/BotFiles/3824/lazarecki.PinkerStinker_0.1.jar''<br />
<br />
'''''Removed because it's incorrectly packaged:'''''<br />
<br />
''Indesh.Indesh 1.1,http://jakobserlier.250free.com/Indesh.jar''<br />
<br />
''loganom.FirstRobot 0.1, http://www.loganom.com/robocode/loganom.FirstRobot_0.1.jar''<br />
<br />
''<br />
fruits.micro.Cherry 1.1,http://robocode-archive.strangeautomata.com/robots/fruits.micro.Cherry_1.1.jar''<br />
<br />
'''''Removed due to invalid line'''''<br />
<br />
''Legend.LNightHawk,http://robocoderepository.com/BotFiles/4167/Legend.LNightHawk.class''<br><br />
''WidowMakersAtWar.Hollow,http://http://www.robocoderepository.com/BotDetail/4169/WidowMakersAtWar.Hollow.jar''<br />
<br />
----<br />
<br />
'''''Removed due to WontFix issues in Robocode 1.7+:'''''<br><br />
''* Hviela: ([[http://sourceforge.net/tracker/?func=detail&aid=2953268&group_id=37202&atid=419486 SF #2953268]])''<br><br />
'': hvilela.HVilela 0.9.3,http://henrique.vilela.googlepages.com/hvilela.HVilela_0.9.3.jar''<br><br />
''* Barney (Tries to write files without using RobocodeOutputStream. Robocode 1.7 punishes for that more harshly which will give 0 scores)<br><br />
'': Homer.Barney 1.0,http://www.robocoderepository.com/BotFiles/1932/Homer.Barney_1.0.jar<br></div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36358XanderCat2017-04-03T09:03:34Z<p>Skotty: </p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5/6 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36357XanderCat2017-04-03T09:03:11Z<p>Skotty: updated for most recent version 12.9</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.9<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.9.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario''' (not currently in use)<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36356XanderCat2017-04-03T09:00:37Z<p>Skotty: /* Version 12.9 (Planned) */ updated version 12.9 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 ===<br />
<br />
Kind of wrecklessly throwing this version out there without solid vetting. :-P<br />
<br />
* Fix some bullet shielding failures.<br />
* Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36355XanderCat2017-04-03T07:48:29Z<p>Skotty: /* Version 12.9 (Planned) */ updated version 12.9 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Fix bullet shielding failures.<br />
** Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution.<br />
** Adjust bullet shielding scenario conditions for opponent not firing, opponent too close, and low opponent firepower.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36354XanderCat2017-04-03T05:15:01Z<p>Skotty: /* Version 12.9 (Planned) */</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Fix bullet shielding failures.<br />
** Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution. One example bot where this was a problem was jcs.Megatron.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36353XanderCat2017-04-03T05:14:48Z<p>Skotty: /* Version 12.9 (Planned) */ updated version 12.9 notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Fix bullet shielding failures.<br />
** Remove ram scenario. XanderCat will no longer try to ram low energy opponents who are not firing. The movement was degrading bullet shielding effectiveness due to opponent data pollution. One example bot where this was a problem was jcs.Megatron.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
Note: Nothing I can do about Seraphim. After some analysis, I discovered that XanderCat's bullet shielding strategy is not flawed on Seraphim; rather, Seraphim is actively countering it against XanderCat specifically. I'll exclude him from further analysis.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:XanderCat/Wacky_Version_Problems_with_RoboJogger/RoboRunner/reply&diff=36352Thread:Talk:XanderCat/Wacky Version Problems with RoboJogger/RoboRunner/reply2017-04-03T02:29:26Z<p>Skotty: Reply to Wacky Version Problems with RoboJogger/RoboRunner</p>
<hr />
<div>As sometimes happen, writing about it made me figure it out. What was happening, that I didn't realize, was that the newer version of Robocode has an option to include the data files in the packaged robot, which is checked by default. So it was packaging data from an old version of XanderCat that I had run from Eclipse, which was totally screwing with my robot frameworks attempt to manage the robot data. <br />
<br />
If you want to save any persistent data to the data files, '''make sure you uncheck the option to include data when packaging the robot!''' <br />
<br />
Can't believe how much time I wasted figuring that out today.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:XanderCat/Wacky_Version_Problems_with_RoboJogger/RoboRunner&diff=36351Thread:Talk:XanderCat/Wacky Version Problems with RoboJogger/RoboRunner2017-04-03T02:13:51Z<p>Skotty: New thread: Wacky Version Problems with RoboJogger/RoboRunner</p>
<hr />
<div>Forgot how slow this can go. :-/ I've been trying all day to record some new statistics using the Robocode means for saving file to disk, but I'm getting really bizarre version issues. I've been updating my robot version with each change -- 12.8.1, then 12.8.2, then 12.8.3. Each time I clear robot cache, package the new version, clear the old stats file that was saved from the prior version (as in, physically delete it, so I know the old stats are gone), and then run a new challenge with the new version. However, I keep getting garbage from older versions coming out in the results. Sometimes mixed, like it's randomly running different versions.<br />
<br />
I've started trying to record the version information to the stats file each battle. I keep seeing this in the saved information:<br />
<br />
Old: xander.cat.XanderCat 12.8.1*; New: xander.cat.XanderCat 12.8.7.<br />
<br />
What that means, is it thinks the last battle was run with 12.8.1*, even though the entire challenge was run with 12.8.7. And that may actually be sort of true, because I'm getting some info in the stats file that I removed around version 12.8.4 but it shows up again, like it ran an older version for one or more of the prior battles.<br />
<br />
At the moment, I'm totally confused by it. I'm not even sure how to debug it further at the moment.</div>Skottyhttp://robowiki.net/w/index.php?title=File:Skotty-xandercat-bs-failures.png&diff=36350File:Skotty-xandercat-bs-failures.png2017-04-02T18:08:48Z<p>Skotty: </p>
<hr />
<div></div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=36349XanderCat2017-04-02T18:07:52Z<p>Skotty: Update version 12.9 info</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Fix bullet shielding failures.<br />
<br />
These are battles that XanderCat should be able to successfully bullet shield against (screenshot from RoboJogger)<br />
[[File:skotty-xandercat-bs-failures.png]]<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=RoboRumble/Contributing_to_RoboRumble&diff=36348RoboRumble/Contributing to RoboRumble2017-04-02T16:17:02Z<p>Skotty: /* From standard Robocode */ Update rumble version information</p>
<hr />
<div><div style="float: right; margin: 0.5em">__TOC__</div><br />
== Setting up ==<br />
If you entered a bot into the competition, you could consider to collaborate running the competition by using your computer to execute battles and upload results (similar to SETI@Home project). The process is fully automated, so there is no pain on doing it.<br />
<br />
Run it as much as you can! The more you run it, the faster everybody's bots will be ranked. If you find problems, refer to the RoboRumble related pages, or post your issue and we will try to solve it.<br />
<br />
=== With the ''Roborumble Superpack'' ===<br />
The ''Roborumble Superpack'' is a zip file containing an updated Robocode 1.7.3.0 install, with all bots (as of 2011/01/23) downloaded already.<br />
<br />
# Download and unzip the [http://dl.dropbox.com/u/4066735/roborumble-superpack-20110706.zip 'Roborumble Superpack'] with bots (28MB).<br />
# for a the latest robot archive (automatically updated) grab [http://robocode-archive.strangeautomata.com/participants-latest.zip latest bot archive] (26.8MB) and extract it into the "robots" directory<br />
# Edit "roborumble/roborumble.txt", "roborumble/meleerumble.txt", "roborumble/teamrumble.txt", and "roborumble/twinduel.txt" files and change the Put_Your_Name_Here to your nick or your handle.<br />
# For newer CPU owners, disable [[Dynamic Overclocking]].<br />
# There you go! You can start you client using roborumble.bat or roborumble.sh (depending on the OS)! Note, the first time it can take some time for robocode to examine the jar files.<br />
<br />
=== From standard Robocode ===<br />
If you don't wish to use the ''Roborumble Superpack'', you may run the standard Robocode installation.<br />
<br />
# Make a new, clean installation of the version of '''Robocode''' ([http://sourceforge.net/projects/robocode/files/robocode/ download link]). Download a version that matches what the [http://literumble.appspot.com/RumbleStats LiteRumble Statistics] indicates is allowed.<br />
# Edit "roborumble/roborumble.txt", "roborumble/meleerumble.txt", and "roborumble/teamrumble.txt" file and change the Put_Your_Name_Here to your nick or your handle. <br />
# You might be also ensure all the rumble server references are correct (there are 3). For Literumble, they should all begin with http://literumble.appspot.com/<br />
# Extract the zip-file [http://robocode-archive.strangeautomata.com/participants-latest.zip latest bot archive] (26.8MB) into the "robots" directory.<br />
# For newer CPU owners, disable [[Dynamic Overclocking]].<br />
# There you go!<br />
# You can start your 1vs1 client using roborumble.bat, roborumble.sh or roborumble.command (depending on the OS) <br />
# You can start your melee client using meleerumble.bat, meleerumble.sh or meleerumble.command (depending on the OS)! <br />
# You can start your team client using teamrumble.bat, teamrumble.sh or teamrumble.command (depending on the OS)! <br />
# Note, the first time it can take some time for robocode to examine the jar files.<br />
<br />
=== Get robot database ===<br />
'''If you did not get the bots in the ''Roborumble Superpack''''', it is recommended that you get a reasonably up-to-date set of robots. Grab the following zip file and extract the .jar file to your RR@H robots directory. <br><br><br />
Since 2012.05.08 you can download the <font color="red">'''LATEST'''</font> robot pack from:<br />
* http://robocode-archive.strangeautomata.com/participants-latest.zip (26.8MB) (includes 1vs1, melee, team and twin bots) <br />
The file provides an archive of all robots in the rumble, which is automatically updates on an hourly basis. Thanks to [[User:Rednaxela|Rednaxela]] for maintaining this.<br> <br><br />
For older robot versions, have a look at:<br />
* http://robocode-archive.strangeautomata.com/robots <br />
Since 2013.01.07 rumble robots archive and robots for Challenges also mirrored to GitHub repository on daily basis (download link exmple: https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/sample.Walls_1.0.jar):<br />
* https://github.com/aleksey-zhidkov/rc-repo-mirror<br />
==== 1vs1 database (dated) ====<br />
get the 300 updates since ? till 20041017:<br />
* http://robowiki.net/robocode/rrath_participants.zip (USA mirror)<br />
* http://nat.robothai.net/robocode/rrath_participants.zip (Thailand mirror)<br />
And get the 308 updates since 20041017 till 20070929:<br />
* http://home.versatel.nl/gheijenk/robocode/things/rrath_add_20070929.zip (Netherlands mirror)<br />
* http://nat.robothai.net/robocode/rrath_add_20070929.zip (Thailand mirror)<br />
And get the 166 updates since 20070929 till 20090301:<br />
* http://home.versatel.nl/gheijenk/robocode/things/rrath_add_20090301.zip (Netherlands mirror)<br />
* http://nat.robothai.net/robocode/rrath_add_20090301.zip (Thailand mirror)<br />
And get the 121 updates since 20090301 till 20090719<br />
* http://nat.robothai.net/robocode/rrath_add_20090719.zip (Thailand mirror)<br />
Get the updates since ? till 20120307:<br />
* http://sites.google.com/site/mnrobocode/robots/Participants_20120307.zip<br />
<br />
==== Melee database (dated) ====<br />
* <s>http://home.versatel.nl/gheijenk/robocode/things/ParticipantsMelee_20080726.zip</s> (''replaced by the one below'')<br />
* http://nat.robothai.net/robocode/ParticipantsMelee_20090719.zip<br />
* http://sites.google.com/site/mnrobocode/robots/ParticipantsMelee_20120307.zip<br />
<br />
==== Team database (dated) ====<br />
* http://home.versatel.nl/gheijenk/robocode/things/ParticipantsTeam_20080726.zip (Netherlands mirror)<br />
* http://nat.robothai.net/robocode/ParticipantsTeam_20080726.zip (Thailand mirror)<br />
* http://sites.google.com/site/mnrobocode/robots/ParticipantsTeams_20120307.zip<br />
<br />
==== Twin Duel database (dated) ====<br />
<br />
* http://sites.google.com/site/mnrobocode/robots/ParticipantsTwinDuel_20120307.zip<br />
<br />
<br />
== How to enter a robot into the competition ==<br />
See here: [[RoboRumble/Enter_The_Competition]]<br />
<br />
== Problem reporting ==<br />
Issues on starting off with RoboRumble can be discussed on the [[Talk:RoboRumble/Starting With RoboRumble|talk page]].<br><br />
Old issues are archived at [[RoboRumble/StartingWithRoboRumbleOld]].<br />
<br />
== Useful options in roborumble.txt ==<br />
* "'''USER'''": Your name/handle, used for identification of your roborumble client.<br />
* "'''BATTLESPERBOT'''" is the minimum number of battles a bot needs before it stops getting priority.<br />
* "'''NUMBATTLES'''", the number of battles fought on each run of roborumble.<br />
* "'''UPLOAD'''", can be used to disable uploading. Use this to disable uploading when testing a version of robocode NOT listed above. Note, the current server will reject results from incorrect versions anyway.<br />
* "'''ITERATE'''", whether to run battles indefinitely.<br />
<br />
== See Also ==<br />
{{:RoboRumble/Navigation}}</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:RoboRumble/Starting_With_RoboRumble/Robocode_1.8.1.0_and_1.8.2.0_not_available/reply_(2)&diff=36347Thread:Talk:RoboRumble/Starting With RoboRumble/Robocode 1.8.1.0 and 1.8.2.0 not available/reply (2)2017-04-02T16:11:47Z<p>Skotty: Reply to Robocode 1.8.1.0 and 1.8.2.0 not available</p>
<hr />
<div>Ah, I didn't know the version was reported there. I'll update the page that suggests older versions. Thanks.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/FirstMark_presentation_point_of_interest&diff=36339Thread:User talk:Voidious/FirstMark presentation point of interest2017-04-01T05:33:51Z<p>Skotty: New thread: FirstMark presentation point of interest</p>
<hr />
<div>I watched the video of your presentation at FirstMark. Pretty good presentation. A couple of points you may find of interest.<br />
<br />
First, I thought the question about what you have learned or what skills you have improved from doing Robocode was a good question, and something that is important to have a good answer to. So beyond yourself, you might like to know what some other Robocode users have gotten from it. For me, it has helped refine and reinforce some of my math skills and methods for analyzing data. It encouraged and helped me learn some new algorithms, and has been a good exercise in creative problem solving.<br />
<br />
Also, someone asked if Robocode was something people from Raytheon used. Raytheon is a contractor that develops a lot of software and hardware for the Department of Defense in the United States. It was a bit of an unusual question that came up because the person who asked it knew that Raytheon develops certain missile and projectile guidance systems. What makes it interesting is that I spent a number of years working on software for Raytheon. The only real connection between my Robocode work and Raytheon work is that they both involved programming, but nonetheless, at least 1 former Raytheon employee does indeed use Robocode.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Skotty/Not_enough_hours_in_the_day/reply_(2)&diff=36338Thread:User talk:Skotty/Not enough hours in the day/reply (2)2017-03-31T16:01:56Z<p>Skotty: Reply to Not enough hours in the day</p>
<hr />
<div>I did a quick review of XanderCat vs Spitfire. Spitfire is my bot that only does bullet shielding. If you do a compare of these two robots in the rumble, you can see that the bullet shielding implementation in XanderCat is still failing frequently. Spitfire outperforms XanderCat by wide margins on many robots vulnerable to bullet shielding. So while I was thinking of just doing melee work, I may also go back and see if I can fix this deficiency in XanderCat again, as doing so could make a significant impact on it's overall performance. There are two things I can do for this.<br />
<br />
First, I may need to do another round of trying to cut some fat out of XanderCat to address the missed turns issue that was previously (and I assume still is) a bit issue related to this. First on the chopping block would probably be the scenario for ramming other opponents, which was just there for fun. I'm sure there are other places that can be improved as well.<br />
<br />
Second, I may need to tweak XanderCat into sticking with the bullet shielding for longer before jumping to other modes. Possibly making it continue trying to bullet shield if the number of missed turns is enough to be interfering. There is a balance to be achieved there between improving against bullet shielding vulnerable opponents and degrading performance against opponents who are not vulnerable to bullet shielding. But based on comparisons, I think trying harder to bullet shield is probably the way to go, as XanderCat is some 20 to 30 APS points lower than Spitfire against quite a few opponents. That's pretty significant.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:XanderFramework/New_Version_of_Framework_In_The_Works&diff=36337Thread:Talk:XanderFramework/New Version of Framework In The Works2017-03-31T15:51:37Z<p>Skotty: New thread: New Version of Framework In The Works</p>
<hr />
<div>Assuming I can really carve out enough time for this, I am planning a new version of my Xander robot framework. This will be a new major version, as it will make a few fundamental changes to how it works. The primary purpose of this overhaul is to add melee support.<br />
<br />
Originally, I had developed a small amount of multi-opponent support, but it was rather limited. For instance, the snapshot history can save histories for multiple robots by storing them in a map with robot names as key values, and their snapshots as values. However, I will not be finishing out this approach for all parts of the framework. There are a lot of framework components that contain information for both self (my robot) and the opponent. I would need to expand these in a way similar to the snapshot history, and be able to store info for all opponents. But I'm not going to do this.<br />
<br />
Instead, I think I am going to divorce storing information for self and opponent in the various framework components, and just store information for a single robot. Doing this for self might be a special case for this, but I still think it will work. Thus, there will not be a single snapshot history, and a single wave history, etc. Instead, there will be one of each of the components for every robot in the battle. Then I will add some higher level management that dishes out information for each robot to the correct components for that robot. I believe this approach will ultimately be more elegant, simplify the individual components a bit, and provide more flexibility.<br />
<br />
I may also provide a few other tweaks, but the melee support will the primary focus.<br />
<br />
This will be Xander framework 3.0.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Skotty/Not_enough_hours_in_the_day/reply&diff=36336Thread:User talk:Skotty/Not enough hours in the day/reply2017-03-30T20:46:57Z<p>Skotty: Reply to Not enough hours in the day</p>
<hr />
<div>I'm honestly not too excited about trying to improve on XanderCat in 1:1 combat. Deminishing returns and all. I'm actually more interested in updating my robot framework to fully support melee combat, and then building my first real melee robot. Not sure if I will just expand XanderCat for this, or create a separate robot (maybe XanderClowder).</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:RoboRumble/Starting_With_RoboRumble/Robocode_1.8.1.0_and_1.8.2.0_not_available&diff=36335Thread:Talk:RoboRumble/Starting With RoboRumble/Robocode 1.8.1.0 and 1.8.2.0 not available2017-03-30T15:23:15Z<p>Skotty: New thread: Robocode 1.8.1.0 and 1.8.2.0 not available</p>
<hr />
<div>Currently, the Robocode download site shows versions 1.9.2.6, 1.9.2.5, 1.9.0.0, 1.8.0.0, 1.7.4.4, 1.6.1.4, and 1.0.7. Versions 1.8.1.0 and 1.8.2.0 are not available. Also, the Roborumble Superpack link is now a dead link. Are there any other versions that are okay to use? If not, we may need to host the older suitable Robocode versions somewhere and update this page accordingly.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Skotty/Not_enough_hours_in_the_day&diff=36334Thread:User talk:Skotty/Not enough hours in the day2017-03-29T08:11:11Z<p>Skotty: New thread: Not enough hours in the day</p>
<hr />
<div>I can't believe how long it has been since I was last active.<br />
<br />
Life keeps me quite busy, but I still think about RoboCode from time to time. I'm tempted to come back for awhile and update RoboJogger (finally get it to a stable 1.0 version), and maybe even work on a robot (maybe take a new look at the missed turns issue XanderCat had in the first couple of rounds).<br />
<br />
I hope everyone is doing well!</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=33965XanderCat2014-12-02T16:40:12Z<p>Skotty: Minor corrections and typo fixes.</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for surfing first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram escape scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram escape scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting in a gun. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen often with a rammer, but the ram scenario happens earlier in the component chain and thus supercedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is imbued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, and was thus for awhile named the Anti-Scarlet gun.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essence moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upper hand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earliest concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Further refine opponent wave creation on skipped turns<br />
* Experiment with increasing kill shot firepower to accommodate for the possibly of getting hit by opponent waves in the air<br />
* Possibly experiment with "gun heat waves"<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=32347XanderCat2013-11-23T04:08:30Z<p>Skotty: add plans for version 12.9</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #4/5 (v 12.8)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, version 12.6 was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for suring first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen alot with a rammer, but the ram scenario happens earier in the component chain and thus superscedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is embued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, thus the name.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essense moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upperhand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earlist concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
=== Version 12.9 (Planned) ===<br />
<br />
* Further refine opponent wave creation on skipped turns<br />
* Experiment with increasing kill shot firepower to accommodate for the possibly of getting hit by opponent waves in the air<br />
* Possibly experiment with "gun heat waves"<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Skotty/1v1_Skipped_Turns_/_Missed_Scans_Tweak&diff=32327Thread:User talk:Skotty/1v1 Skipped Turns / Missed Scans Tweak2013-11-21T17:16:32Z<p>Skotty: New thread: 1v1 Skipped Turns / Missed Scans Tweak</p>
<hr />
<div>In version 12.8 of XanderCat, I partially fixed my bullet shielding components that were being seriously hampered by skipped turns due to what we believe to be a garbage collection issue that occurs on some platforms for bots that produce a lot of garbage (yeah, XanderCat is a trashy bot). This partial fix now has me neck and neck with Gilgalad (up from 7th to roughly tied for 4th).<br />
<br />
The skipped turns remains a problem, but the bullet shielding is working much better now regardless. Originally I thought the problem was due to the time loss, but the real culprit was with how the opponent waves were being generated. When XanderCat sees an energy drop from scan to the next in an opponent that cannot be explained by anything else, it logs it as the opponent firing a bullet and creates an opponent wave for the assumed bullet. This is fairly standard. However, what happens if your robot has missed scans in a time period when the opponent has fired a shot (in my case, due to skipped turns)? <br />
<br />
XanderCat would just assume that the opponent bullet was fired on the previous tick. For example, assume you have a scan from time 40, then have skipped turns, then the next scan you get is from time 50. XanderCat would assume the bullet was fired at time 49, when it could have been fired at any time between ticks 41 and 49. This resulted in incorrect opponent waves often being created. This error doesn't affect other strategies all that much, but it does break bullet shielding quite badly.<br />
<br />
My initial fix for XanderCat 12.8 is fairly simple. If the scans are not back to back, the wave is just flagged as "estimated". Any components that then rely on processing opponent waves can take that flag into account if needed. I just have my bullet shielding controller ignore "estimated" waves so that I do not attempt to shield those waves and don't count misses against those waves in whether or not to continue shielding.<br />
<br />
A better solution, which I may consider, is to try to actually figure out what missed tick was the tick when the shot was actually fired, and then use that tick in the opponent wave creation. This could be done by analyzing opponent gun heat. Most bots will fire as soon as their gun heat reaches 0, so if you know when the previous shot was fired, you can figure out on which tick the next fired shot should have happened on. How much additional help might this be?<br />
<br />
Now, most 1v1 bots don't have problems with missed scans or skipped turns, so concerning oneself with this issue may not be worth the trouble. But it's something interesting to think about.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:User_talk:Voidious/BerryBots_updates/reply_(34)&diff=32306Thread:User talk:Voidious/BerryBots updates/reply (34)2013-11-20T02:54:45Z<p>Skotty: Reply to BerryBots updates</p>
<hr />
<div>Awesome. Very well done. Not that I'm an expert on the variety of these types of games, but I've never seen one where you could do all the coding and battles online before. <br />
<br />
Is there a way to adjust the game play speed? I don't recall seeing that. It would be nice if play could be slowed down. The default speed seems so ADD.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:LiteRumble/Roborumble_Bot_Details_Gives_Server_Error/reply_(5)&diff=32287Thread:Talk:LiteRumble/Roborumble Bot Details Gives Server Error/reply (5)2013-11-19T15:42:48Z<p>Skotty: Reply to Roborumble Bot Details Gives Server Error</p>
<hr />
<div>Thanks, Skilgannon. It's all good now.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:LiteRumble/Roborumble_Bot_Details_Gives_Server_Error&diff=32270Thread:Talk:LiteRumble/Roborumble Bot Details Gives Server Error2013-11-18T22:38:47Z<p>Skotty: New thread: Roborumble Bot Details Gives Server Error</p>
<hr />
<div>I've been getting Server Error whenever trying to see details or do a comparison with game=roborumble. It works fine for other game types.</div>Skottyhttp://robowiki.net/w/index.php?title=RoboRumble/Participants&diff=32269RoboRumble/Participants2013-11-18T21:54:19Z<p>Skotty: Replaced XanderCat 12.7 with XanderCat 12.8 -- better handling of waves when scans are missed; should mostly fix shielding failures due to skipped turns</p>
<hr />
<div>{{:RoboRumble/Navigation}}<br />
<br />
----<br />
Just add your bot name ('''as appears in the Robocode selector after packaging''', so including versionnumber) and the RobocodeRepository id number separated by "," (there must be no space after the comma).<br />
<br><br />
The list is in '''alphabetical''' order. Add your bot in the right slot.<br />
<br />
For your bot to be accepted by the RR@Home server, the following rules are mandatory:<br />
<br />
* The bot must have a package-name.<br />
* The bot must be packaged in a jar-file.<br />
* A <botname>.properties file must be present in the jar-file.<br />
* The naming of the bot must reflect the internal structure,see [http://home.versatel.nl/gheijenk/plaatjes/bot_naming.png]for sample.RamFire.<br />
<br />
The easiest way to do this is to package your bot with Robocode (Robot -> Package robot for upload).<br />
<br />
'''PLEASE MAKE SURE YOUR BOT IS NOT ALREADY ON THE LIST BEFORE YOU ADD IT.<br>IF YOU ARE ADDING A NEW VERSION OF YOUR BOT, PLEASE DELETE THE OLD ONE.'''<br />
<br />
----<br />
<pre><br />
ab.DengerousRoBatra 1.3,http://www.robocoderepository.com/BotFiles/3664/ab.DengerousRoBatra_1.3.jar<br />
abc.Shadow 3.83c,http://robocode.aclsi.pt/abc.Shadow_3.83c.jar<br />
abc.tron3.Tron 3.11,http://www.robocoderepository.com/BotFiles/2205/abc.tron3.Tron_3.11.jar<br />
abc.Tron 2.02,http://www.robocoderepository.com/BotFiles/241/abc.Tron_2.02.jar<br />
abud.ThirdRobo 1.0,http://www.robocoderepository.com/BotFiles/2479/abud.ThirdRobo_1.0.jar<br />
acogdev.alpha 0.2,https://sites.google.com/site/cqjake/robocode/acogdev.alpha_0.2.jar<br />
ad.last.Bottom 1.0,http://www.robocoderepository.com/BotFiles/1876/ad.last.Bottom_1.0.jar<br />
ad.Quest 0.10,http://www.robocoderepository.com/BotFiles/1846/ad.Quest_0.10.jar<br />
adt.Ar1 2.1,http://www.robocoderepository.com/BotFiles/2254/adt.Ar1_2.1.jar<br />
adt.Ar2 1.0,http://www.robocoderepository.com/BotFiles/2303/adt.Ar2_1.0.jar<br />
aetos.AetosFirstBot 1.0,http://robocode-archive.strangeautomata.com/robots/aetos.AetosFirstBot_1.0.jar<br />
ag.Gir 0.99,http://www.robocoderepository.com/BotFiles/3065/ag.Gir_0.99.jar<br />
agd.Mooserwirt2 2.7,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/agd.Mooserwirt2_2.7.jar<br />
agrach.Dalek 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.Dalek_1.0.jar<br />
agrach.MicroDalek 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.MicroDalek_1.0.jar<br />
agrach.RobotSlayer 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/agrach.RobotSlayer_1.0.jar<br />
ags.Glacier 0.2.7,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.Glacier_0.2.7.jar<br />
ags.micro.Carpet 1.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.micro.Carpet_1.1.jar<br />
ags.Midboss 1q.fast,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.Midboss_1q.fast.jar<br />
ags.polished.PolishedRuby 1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.polished.PolishedRuby_1.jar<br />
ags.rougedc.RougeDC willow,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ags.rougedc.RougeDC_willow.jar<br />
ahf.Acero 1.0,http://www.robocoderepository.com/BotFiles/2151/ahf.Acero_1.0.jar<br />
ahf.NanoAndrew .4,http://www.robocoderepository.com/BotFiles/2002/ahf.NanoAndrew_.4.jar<br />
ahf.r2d2.R2d2 0.86,http://www.robocoderepository.com/BotFiles/2035/ahf.r2d2.R2d2_0.86.jar<br />
ahr.ice.Ice 1.0,http://robocoderepository.com/BotFiles/3966/ahr.ice.Ice_1.0.jar<br />
AIR.iRobot 1.0,http://www.robocoderepository.com/BotFiles/3205/AIR.iRobot_1.0.jar<br />
ak.Fermat 2.0,http://www.robocoderepository.com/BotFiles/799/ak.Fermat_2.0.jar<br />
alex.Diabolo5 1.1,http://robocode-archive.strangeautomata.com/robots/alex.Diabolo5_1.1.jar<br />
alk.lap.LoudAndProud 2.23,http://www.robocoderepository.com/BotFiles/3601/alk.lap.LoudAndProud_2.23.jar<br />
alpha.BlackIce 1.0,https://docs.google.com/uc?export=download&confirm=no_antivirus&id=0B4I_xy0UZndLSkc3MVI3Y0sycW8<br />
alpha.RainingFire 1.0,https://docs.google.com/uc?export=download&id=0B4I_xy0UZndLQnVwbHBKVWd5ak0<br />
am.Miedzix 3.0,http://robocode-archive.strangeautomata.com/robots/am.Miedzix_3.0.jar<br />
amc.ROBv202 1.01,http://matron.ic.cz/robocode/amc.ROBv202_1.01.jar<br />
amc.ROBv203 1.0,http://matron.ic.cz/robocode/amc.ROBv203_1.0.jar<br />
amc.ROBv300 1.1,http://matron.ic.cz/robocode/amc.ROBv300_1.1.jar<br />
amc.ROBv301 1.1,http://matron.ic.cz/robocode/amc.ROBv301_1.1.jar<br />
amc.ROBv400 1.0,http://matron.ic.cz/robocode/amc.ROBv400_1.0.jar<br />
amarok.Rookie 1.1,http://www.robocoderepository.com/BotFiles/422/amarok.Rookie_1.1.jar<br />
amk.ChumbaMini 0.2,http://www.robocoderepository.com/BotFiles/2655/amk.ChumbaMini_0.2.jar<br />
amk.ChumbaWumba 0.3,http://www.robocoderepository.com/BotFiles/2646/amk.ChumbaWumba_0.3.jar<br />
amk.jointstrike.JointStrike 0.2,http://www.robocoderepository.com/BotFiles/2597/amk.jointstrike.JointStrike_0.2.jar<br />
amk.ShizzleStiX.ShizzleStiX 0.6,http://www.robocoderepository.com/BotFiles/2603/amk.ShizzleStiX.ShizzleStiX_0.6.jar<br />
amk.superstrike.SuperStrike 0.3,http://www.robocoderepository.com/BotFiles/2600/amk.superstrike.SuperStrike_0.3.jar<br />
amk.Punbot.Punbot 0.01,http://www.robocoderepository.com/BotFiles/2604/amk.Punbot.Punbot_0.01.jar<br />
ancientpyro.megas.kbot.KBot 1.0,https://sites.google.com/site/myrobocodedownloads/home/kbot/ancientpyro.megas.kbot.KBot_1.0.jar<br />
And.BasicSurfer FF1.6,https://sites.google.com/site/devonrobots/home/basicsurfer/And.BasicSurfer_FF1.6.jar?attredirects=0&d=1<br />
ao.T100 0.9,http://www.robocoderepository.com/BotFiles/3385/ao.T100_0.9.jar<br />
ap.Frederick 1.1,http://robocode-archive.strangeautomata.com/robots/ap.Frederick_1.1.jar<br />
apc.botM 3.0, http://www.jambe.co.nz/~james/apc.botM_3.0.jar<br />
apc.Caan 1.0, http://www.jambe.co.nz/~james/apc.Caan_1.0.jar<br />
apc.Colossus2 0.12, http://robocode-archive.strangeautomata.com/robots/apc.Colossus2_0.12.jar<br />
apc.LeeroyJenkins2 1.0,http://robocode-archive.strangeautomata.com/robots/apc.LeeroyJenkins2_1.0.jar<br />
apollokidd.ApolloKidd 0.9,http://www.robocoderepository.com/BotFiles/321/apollokidd.ApolloKidd_0.9.jar<br />
apv.Aspid 1.7,http://www.robocoderepository.com/BotFiles/1412/apv.Aspid_1.7.jar<br />
apv.AspidReloaded 0.6,http://www.robocoderepository.com/BotFiles/1985/apv.AspidReloaded_0.6.jar<br />
apv.LauLectrik 1.2,http://www.robocoderepository.com/BotFiles/1300/apv.LauLectrik_1.2.jar<br />
apv.MicroAspid 1.8,http://www.robocoderepository.com/BotFiles/2519/apv.MicroAspid_1.8.jar<br />
apv.NanoLauLectrik 1.0,http://www.robocoderepository.com/BotFiles/1399/apv.NanoLauLectrik_1.0.jar<br />
apv.NanoLauLectrikTheCannibal 1.1,http://www.robocoderepository.com/BotFiles/2147/apv.NanoLauLectrikTheCannibal_1.1.jar<br />
apv.ScruchiPu 1.0,http://www.robocoderepository.com/BotFiles/1367/apv.ScruchiPu_1.0.jar<br />
apv.test.Virus 0.6.1,http://www.robocoderepository.com/BotFiles/2645/apv.test.Virus_0.6.1.jar<br />
apv.TheBrainPi 0.5fix,http://robocode-archive.strangeautomata.com/robots/apv.TheBrainPi_0.5fix.jar<br />
ar.horizon.Horizon 1.2.2,http://www.robocoderepository.com/BotFiles/3286/ar.horizon.Horizon_1.2.2.jar<br />
ar.QuantumChromodynamics 1.2.1,http://www.robocoderepository.com/BotFiles/3220/ar.QuantumChromodynamics_1.2.1.jar<br />
ar.TheoryOfEverything 1.2.1,http://www.robocoderepository.com/BotFiles/3221/ar.TheoryOfEverything_1.2.1.jar<br />
ara.Shera 0.88,http://www.robocoderepository.com/BotFiles/1050/ara.Shera_0.88.jar<br />
areb.Union 1.06,http://www.robocoderepository.com/BotFiles/2893/areb.Union_1.06.jar<br />
arthord.micro.Apoptygma 0.4,http://www.robocoderepository.com/BotFiles/1688/arthord.micro.Apoptygma_0.4.jar<br />
arthord.micro.Muffin 0.6.1,http://www.robocoderepository.com/BotFiles/1963/arthord.micro.Muffin_0.6.1.jar<br />
arthord.KostyaTszyu Beta2,http://www.robocoderepository.com/BotFiles/2322/arthord.KostyaTszyu_Beta2.jar<br />
arthord.MannyPacquiao Delta2,http://scoutery.awardspace.com/arthord.MannyPacquiao_Delta2.jar<br />
arthord.NanoSatan Mu,http://www.robocoderepository.com/BotFiles/2157/arthord.NanoSatan_Mu.jar<br />
arthord.NanoSatanMelee Beta,http://www.robocoderepository.com/BotFiles/2088/arthord.NanoSatanMelee_Beta.jar<br />
ary.micro.Weak 1.2,http://www.robocoderepository.com/BotFiles/3433/ary.micro.Weak_1.2.jar<br />
ary.mini.Nimi 1.0,http://www.robocoderepository.com/BotFiles/3397/ary.mini.Nimi_1.0.jar<br />
ary.nano.AceSurf 1.2,http://www.robocoderepository.com/BotFiles/3352/ary.nano.AceSurf_1.2.jar<br />
ary.nano.ColorNanoP 1.1,http://www.robocoderepository.com/BotFiles/3629/ary.nano.ColorNanoP_1.1.jar<br />
ary.Crisis 1.0,http://www.robocoderepository.com/BotFiles/3495/ary.Crisis_1.0.jar<br />
ary.Help 1.0,http://robocode-archive.strangeautomata.com/robots/ary.Help_1.0.jar<br />
ary.FourWD 1.3d,http://robocode-archive.strangeautomata.com/robots/ary.FourWD_1.3d.jar<br />
ary.SMG 1.01,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/ary.SMG_1.01.jar<br />
as.xbots 1.0,http://robocode-archive.strangeautomata.com/robots/as.xbots_1.0.jar<br />
asd.Cthulhu 1.2,http://robocode-archive.strangeautomata.com/robots/asd.Cthulhu_1.2.jar<br />
asm.Statistas 0.1,http://www.robocoderepository.com/BotFiles/1989/asm.Statistas_0.1.jar<br />
av.RobAtHome 1.2,http://www.user.tu-berlin.de/vickqsjf/av.RobAtHome_1.2.jar<br />
aw.Gilgalad 1.99.7,https://sites.google.com/site/awusa94/robocode/aw.Gilgalad_1.99.7.jar?attredirects=0<br />
awesomeness.Elite 1.0,http://robocoderepository.com/BotFiles/3597/awesomeness.Elite.jar<br />
awl.Locutus 1.5,https://dl.dropboxusercontent.com/u/1589443/awl.Locutus_1.5.jar<br />
axeBots.HataMoto 3.09,http://www.robocoderepository.com/BotFiles/1655/axeBots.HataMoto_3.09.jar<br />
axeBots.Musashi 2.18,http://www.robocoderepository.com/BotFiles/1759/axeBots.Musashi_2.18.jar<br />
axeBots.Okami 1.04,http://www.robocoderepository.com/BotFiles/2016/axeBots.Okami_1.04.jar<br />
axeBots.SilverSurfer 2.53.33fix,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/axeBots.SilverSurfer_2.53.33fix.jar<br />
ayk.WallHugger 1.0,http://robocode-archive.strangeautomata.com/robots/ayk.WallHugger_1.0.jar<br />
baal.nano.N 1.42,http://webpages.charter.net/eleeleth/Robots/baal.nano.N_1.42.jar<br />
banshee.mini.Nexus6 0.2.0,http://www.robocoderepository.com/BotFiles/3467/banshee.mini.Nexus6_0.2.0.jar<br />
banshee.micro.Nexus6 0.3.0,http://www.robocoderepository.com/BotFiles/3473/banshee.micro.Nexus6_0.3.0.jar<br />
bayen.nano.Squirrel 0.2,http://www.freewebs.com/bayen/files/bayen.nano.Squirrel_0.2.jar<br />
bayen.nut.Squirrel 1.621,http://robocode-archive.strangeautomata.com/robots/bayen.nut.Squirrel_1.621.jar<br />
bayen.UbaMicro 1.4,http://www.robocoderepository.com/BotFiles/2830/bayen.UbaMicro_1.4.jar<br />
bayen.UbaRamLT 1.0,http://www.robocoderepository.com/BotFiles/2868/bayen.UbaRamLT_1.0.jar<br />
bbo.RamboT 0.3,http://www.robocoderepository.com/BotFiles/2210/bbo.RamboT_0.3.jar<br />
bbo.TheRoof 1.4.3,http://www.robocoderepository.com/BotFiles/2179/bbo.TheRoof_1.4.3.jar<br />
Bemo.Sweet30 1.6.1,http://www.stg-volleyball.de/images/Bemo.Sweet30_1.6.1.jar<br />
benhorner.PureAggression 0.2.6,http://www.robocoderepository.com/BotFiles/3421/benhorner.PureAggression_0.2.6.jar<br />
bh.PencilRain 0.01,http://www.robocoderepository.com/BotFiles/3670/bh.PencilRain-0.01.jar<br />
bigpete.Stewie 1.0,http://www.robocoderepository.com/BotFiles/2927/bigpete.Stewie_1.0.jar<br />
bing2.Melody 1.3.1,http://www.ccs.neu.edu/home/bing/robocode/bing2.Melody_1.3.1.jar<br />
bjl.LoneDragon 0.5,http://www.robocoderepository.com/BotFiles/1929/bjl.LoneDragon_0.5.jar<br />
blir.micro.blixi.Blixi 1.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/blir.micro.blixi.Blixi_1.0.jar<br />
blir.nano.Bruce R1.0.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/blir.nano.Bruce_R1.0.0.jar<br />
blir.nano.Cabbage R1.0.1,https://dl.dropboxusercontent.com/u/103112496/Robocode/blir.nano.Cabbage_R1.0.1.jar<br />
blir.nano.inch.Inchworm 1.0,https://dl.dropboxusercontent.com/u/103112496/Robocode/blir.nano.inch.Inchworm_1.0.jar<br />
blr.Chicken001 0.1,https://dl.dropbox.com/s/b1isx9axzuyl2yb/blr.Chicken001_0.1.jar?dl=1<br />
bndl.LostLion 1.2,http://www.robocoderepository.com/BotFiles/1033/bndl.LostLion_1.2.jar<br />
bk.Shooter 1.0,https://dl.dropboxusercontent.com/u/81048920/bk.Shooter_1.0.jar<br />
boe.Minerva 0.80,https://dl.dropboxusercontent.com/u/27918021/boe.Minerva_0.80.jar<br />
bons.NanoStalker 1.2,http://www.robocoderepository.com/BotFiles/1179/bons.NanoStalker_1.2.jar<br />
bots.UberBot 1.2c,https://dl.dropboxusercontent.com/u/97134235/bots.UberBot_1.2c.jar<br />
bots.UnterBot 1.0,https://dl.dropboxusercontent.com/u/97134235/bots.UnterBot_1.0.jar<br />
bp.Kuma 1.0,http://www.robocoderepository.com/BotFiles/3238/bp.Kuma_1.0.jar<br />
braaropolis.Abot 1.0,http://robocode-archive.strangeautomata.com/robots/braaropolis.Abot_1.0.jar<br />
brainfade.Fallen 0.63,http://www.robocoderepository.com/BotFiles/2250/brainfade.Fallen_0.63.jar<br />
brainfade.melee.Dusk 0.44,http://www.robocoderepository.com/BotFiles/2518/brainfade.melee.Dusk_0.44.jar<br />
bts.mega.Gnarly 1.4,http://www.bluetorchsource.com/bots/bts.mega.Gnarly_1.4.jar<br />
buba.Archivist 0.1,http://www.robocoderepository.com/BotFiles/3899/buba.Archivist_0.1.jar<br />
buba.Buba 0.3,http://www.robocoderepository.com/BotFiles/3896/buba.Buba_0.3.jar<br />
bumblebee.Bumblebee 1.0, https://dl.dropbox.com/s/ac31anjpew7ownh/bumblebee.Bumblebee_1.0.jar?dl=1<br />
bvh.fnr.Fenrir 0.36l,http://www.robocoderepository.com/BotFiles/1428/bvh.fnr.Fenrir_0.36l.jar<br />
bvh.frg.Friga 0.112dev,http://robocode-archive.strangeautomata.com/robots/bvh.frg.Friga_0.112dev.jar<br />
bvh.fry.Freya 0.82,http://robocode-archive.strangeautomata.com/robots/bvh.fry.Freya_0.82.jar<br />
bvh.hdr.Hodur 0.4,http://www.robocoderepository.com/BotFiles/1954/bvh.hdr.Hodur_0.4.jar<br />
bvh.loki.Loki 0.5,http://www.robocoderepository.com/BotFiles/885/bvh.loki.Loki_0.5.jar<br />
bvh.micro.Freya 0.3,http://www.robocoderepository.com/BotFiles/2815/bvh.micro.Freya_0.3.jar<br />
bvh.micro.Svadilfari 0.2,http://www.robocoderepository.com/BotFiles/1086/bvh.micro.Svadilfari_0.2.jar<br />
bvh.mini.Fenrir 0.39,http://www.robocoderepository.com/BotFiles/1429/bvh.mini.Fenrir_0.39.jar<br />
bvh.mini.Freya 0.55,http://robocode-archive.strangeautomata.com/robots/bvh.mini.Freya_0.55.jar<br />
bvh.mini.Mjolnir 0.3,http://www.robocoderepository.com/BotFiles/2220/bvh.mini.Mjolnir_0.3.jar<br />
bvh.mini.Wodan 0.50,http://www.robocoderepository.com/BotFiles/2064/bvh.mini.Wodan_0.50.jar<br />
bvh.tyr.Tyr 1.74,http://www.robocoderepository.com/BotFiles/886/bvh.tyr.Tyr_1.74.jar<br />
bwbaugh.nano.Tirunculus 0.0.0a,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/bwbaugh.nano.Tirunculus_0.0.0a.jar<br />
bzdp.BoxCar 2.0,http://www.robocoderepository.com/BotFiles/3703/bzdp.BoxCar_2.0.jar<br />
bzdp.Pansy 2.1,http://www.robocoderepository.com/BotFiles/3726/bzdp.Pansy_2.1.jar<br />
caimano.Furia_Ceca 0.22,http://www.robocoderepository.com/BotFiles/1843/caimano.Furia_Ceca_0.22.jar<br />
can.Pookie 1.1,http://www.robocoderepository.com/BotFiles/4086/can.Pookie-1.1.jar<br />
casey.Flee 1.0,http://www.robocoderepository.com/BotFiles/4108/casey.Flee_1.0.jar<br />
casey.Flump 1.0,https://www.sites.google.com/site/fatsandbox/robots/casey.Flump_1.0.jar<br />
cb.DeepThought 1.3,http://bomberportal.com/other/robocode/cb.DeepThought_1.3.jar<br />
cb.mega.Enigma 1.1,http://bomberportal.com/other/robocode/cb.mega.Enigma_1.1.jar<br />
cb.droid.Polyphem 1.0,http://bomberportal.com/other/robocode/cb.droid.Polyphem_1.0.jar<br />
cb.Femto 1.0,http://bomberportal.com/other/robocode/cb.Femto_1.0.jar<br />
cb.micro.Haiduc H1,http://bomberportal.com/other/robocode/cb.micro.Haiduc_H1.jar<br />
cb.Sabertooth 1.0,http://bomberportal.com/other/robocode/cb.Sabertooth_1.0.jar<br />
cb.nano.Chasseur 1.1,http://bomberportal.com/other/robocode/cb.nano.Chasseur_1.1.jar<br />
cb.test.Provocateur 1.0,http://bomberportal.com/other/robocode/cb.test.Provocateur_1.0.jar<br />
cbot.agile.Nibbler 0.2,http://www.robocoderepository.com/BotFiles/1537/cbot.agile.Nibbler_0.2.jar<br />
cbot.cbot.CBot 0.8,http://www.robocoderepository.com/BotFiles/1375/cbot.cbot.CBot_0.8.jar<br />
cf.mini.Chiva 1.0,http://www.robocoderepository.com/BotFiles/2331/cf.mini.Chiva_1.0.jar<br />
cf.OldMan.OldManXP 0.1,http://www.robocoderepository.com/BotFiles/1968/cf.OldMan.OldManXP_0.1.jar<br />
cf.proto.Shiva 2.2,http://www.robocoderepository.com/BotFiles/2409/cf.proto.Shiva_2.2.jar<br />
cf.star.Star2 1.23,http://www.robocoderepository.com/BotFiles/2255/cf.star.Star2_1.23.jar<br />
ch.rhj.rbc.RHJ1 1.0,http://www.robocoderepository.com/BotFiles/1879/ch.rhj.rbc.RHJ1_1.0.jar<br />
CharlieN.Omega.Omega 1.03,http://www.robocoderepository.com/BotFiles/3503/CharlieN.Omega.Omega_1.03.jar<br />
chase.pm.Pytko 1.0,http://robocode-archive.strangeautomata.com/robots/chase.pm.Pytko_1.0.jar<br />
chickenfuego.UrChicken2 1.0,http://www.robocoderepository.com/BotFiles/3422/chickenfuego.UrChicken2_1.0.jar<br />
cjk.Merkava 0.1.1,http://www.robocoderepository.com/BotFiles/2637/cjk.Merkava_0.1.1.jar<br />
cjm.chalk.Chalk 2.6.Be,http://scatterbright.com/robots/cjm.chalk.Chalk_2.6.Be.jar<br />
cjm.Charo 1.1,http://scatterbright.com/robots/cjm.Charo_1.1.jar<br />
cjm.Che 1.2,http://www.robocoderepository.com/BotFiles/2703/cjm.Che_1.2.jar<br />
cjm.Chomsky 1.5,http://scatterbright.com/robots/cjm.Chomsky_1.5.jar<br />
cli.Dancer 1.1,http://robocode-archive.strangeautomata.com/robots/cli.Dancer_1.1.jar<br />
cli.WasteOfAmmo 1.0,http://robocode-archive.strangeautomata.com/robots/cli.WasteOfAmmo_1.0.jar<br />
codemojo.nano.Woot 1.0,http://robocode-archive.strangeautomata.com/robots/codemojo.nano.Woot_1.0.jar<br />
com.blogspot.malinkody.DestrobotMalin 1.0,http://www.robocoderepository.com/BotFiles/4109/com.blogspot.malinkody.DestrobotMalin_1.0.jar<br />
com.cohesiva.robocode.ManOwaR 1.0,http://www.robocoderepository.com/BotFiles/4160/com.cohesiva.robocode.ManOwaR_1.0.jar<br />
com.syncleus.robocode.Dreadnaught 0.1,http://robocoderepository.com/BotFiles/3426/com.syncleus.robocode.Dreadnaught_0.1.jar<br />
conscience.Electron 1.3g,http://pmdom.altervista.org/conscience.Electron_1.3g.jar<br />
conscience.Bulldozer 1.0a,http://pmdom.altervista.org/conscience.Bulldozer_1.0a.jar<br />
conscience.Idem 1.0a,http://pmdom.altervista.org/conscience.Idem_1.0a.jar<br />
conscience.Suicidal 1.1,http://pmdom.altervista.org/conscience.Suicidal_1.1.jar<br />
cre.Karolos 0.32,http://robocode-archive.strangeautomata.com/robots/cre.Karolos_0.32.jar<br />
cs.Nene 1.0.4,http://robocode-archive.strangeautomata.com/robots/cs.Nene_1.0.4.jar<br />
cs.s2.Seraphim 2.3.1,http://robocode-archive.strangeautomata.com/robots/cs.s2.Seraphim_2.3.1.jar<br />
cs.Wren 1.0,http://robocode-archive.strangeautomata.com/robots/cs.Wren_1.0.jar<br />
csm.NthGeneration 0.04,http://www.robocoderepository.com/BotFiles/1214/csm.NthGeneration_0.04.jar<br />
csp.Eagle 3.30,http://www.robocoderepository.com/BotFiles/2436/csp.Eagle_3.30.jar<br />
css.Delitioner 0.11,http://robocode-archive.strangeautomata.com/robots/css.Delitioner_0.11.jar<br />
cuoq.Kakera 1.0,http://robocode-archive.strangeautomata.com/robots/cuoq.Kakera_1.0.jar<br />
cw.megas.Blade 0.8,http://robocode-archive.strangeautomata.com/robots/cw.megas.Blade_0.8.jar<br />
cw.megas.GhostShell GT,http://robocode-archive.strangeautomata.com/robots/cw.megas.GhostShell_GT.jar<br />
cw.megas.Gridd 0.4,http://robocode-archive.strangeautomata.com/robots/cw.megas.Gridd_0.4.jar<br />
cw.megas.Polar 3.2,http://robocode-archive.strangeautomata.com/robots/cw.megas.Polar_3.2.jar<br />
cw.megas.Silhouette 1.1,http://robocode-archive.strangeautomata.com/robots/cw.megas.Silhouette_1.1.jar?attredirects=0&d=1<br />
cx.BlestPain 1.41,http://www.robocoderepository.com/BotFiles/1671/cx.BlestPain_1.41.jar<br />
cx.CigaretBH 1.03,http://www.robocoderepository.com/BotFiles/1414/cx.CigaretBH_1.03.jar<br />
cx.Lacrimas 1.36,http://www.robocoderepository.com/BotFiles/1820/cx.Lacrimas_1.36.jar<br />
cx.micro.Blur 0.2,http://www.robocoderepository.com/BotFiles/2447/cx.micro.Blur_0.2.jar<br />
cx.micro.Smoke 0.96,http://www.robocoderepository.com/BotFiles/1037/cx.micro.Smoke_0.96.jar<br />
cx.micro.Spark 0.6,http://www.robocoderepository.com/BotFiles/1320/cx.micro.Spark_0.6.jar<br />
cx.mini.BlackSwans 0.60,http://www.robocoderepository.com/BotFiles/1158/cx.mini.BlackSwans_0.60.jar<br />
cx.mini.Cigaret 1.31,http://www.robocoderepository.com/BotFiles/1152/cx.mini.Cigaret_1.31.jar<br />
cx.mini.Nimrod 0.55,http://www.robocoderepository.com/BotFiles/1236/cx.mini.Nimrod_0.55.jar<br />
cx.nano.Smog 2.6,http://www.robocoderepository.com/BotFiles/1036/cx.nano.Smog_2.6.jar<br />
cx.Princess 1.0,http://www.robocoderepository.com/BotFiles/1343/cx.Princess_1.0.jar<br />
cyragia.Bot 1.1,http://www.robocoderepository.com/BotFiles/4098/cyragia.Bot_1.1.jar<br />
da.NewBGank 1.4,http://www.robocoderepository.com/BotFiles/3312/da.NewBGank_1.4.jar<br />
daemons.DizzyA 1.0,https://github.com/bushranger/DizzyA/blob/master/daemons.DizzyA_1.0.jar?raw=true<br />
dam.MogBot 2.9,http://www.robocoderepository.com/BotFiles/555/dam.MogBot_2.9.jar<br />
dans.Cinnamon 1.2,http://www.robocoderepository.com/BotFiles/1976/dans.Cinnamon_1.2.jar<br />
darkcanuck.Gaff 1.50,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Gaff_1.50.jar<br />
darkcanuck.Holden 1.13a,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Holden_1.13a.jar<br />
darkcanuck.Pris 0.92,http://robocode-archive.strangeautomata.com/robots/darkcanuck.Pris_0.92.jar<br />
davidalves.Firebird 0.25,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/davidalves.Firebird_0.25.jar<br />
davidalves.Phoenix 1.02,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/davidalves.Phoenix_1.02.jar<br />
davidalves.PhoenixOS 1.1,http://robocode-archive.strangeautomata.com/robots/davidalves.PhoenixOS_1.1.jar<br />
davidalves.net.Duelist 0.1.6src,http://www.robocoderepository.com/BotFiles/1000/davidalves.net.Duelist_0.1.6src.jar<br />
davidalves.net.DuelistMicro 1.22,http://www.robocoderepository.com/BotFiles/1144/davidalves.net.DuelistMicro_1.22.jar<br />
davidalves.net.DuelistMicroMkII 1.1,http://www.robocoderepository.com/BotFiles/1281/davidalves.net.DuelistMicroMkII_1.1.jar<br />
davidalves.net.DuelistMini 1.1,http://www.robocoderepository.com/BotFiles/1181/davidalves.net.DuelistMini_1.1.jar<br />
davidalves.net.DuelistNano 1.0,http://www.robocoderepository.com/BotFiles/1272/davidalves.net.DuelistNano_1.0.jar<br />
dcs.Eater_of_Worlds 1.1.3-A,http://www.robocoderepository.com/BotFiles/2578/dcs.Eater_of_Worlds_1.1.3-A.jar<br />
dcs.Eater_of_Worlds_Mini 1.0,http://www.robocoderepository.com/BotFiles/2850/dcs.Eater_of_Worlds_Mini_1.0.jar<br />
dcs.PM.Eater_of_Worlds_PM 1.2,http://www.robocoderepository.com/BotFiles/2856/dcs.PM.Eater_of_Worlds_PM_1.2.jar<br />
de.erdega.robocode.Polyphemos 0.4,http://robocode-archive.strangeautomata.com/robots/de.erdega.robocode.Polyphemos_0.4.jar<br />
deewiant.Anomaly 0.2,http://www.iki.fi/~deewiant/files/deewiant.Anomaly_0.2.jar<br />
deith.Czolgzilla 0.11,http://www.robocoderepository.com/BotFiles/3256/deith.Czolgzilla_0.11.jar<br />
demetrix.ForceMajeure 0.75,http://ever-rage.narod.ru/robowiki/demetrix.ForceMajeure_0.75.jar<br />
demetrix.nano.Neutrino 0.27,http://ever-rage.narod.ru/robowiki/demetrix.nano.Neutrino_0.27.jar<br />
demetrix.nano.SledgeHammer 0.22,http://ever-rage.narod.ru/robowiki/demetrix.nano.SledgeHammer_0.22.jar<br />
deo.CloudBot 1.3,http://robocoderepository.com/BotFiles/3644/deo.CloudBot_1.3.jar<br />
deo.FlowerBot 1.0,http://robocoderepository.com/BotFiles/3683/deo.FlowerBot_1.0.jar<br />
deo.virtual.RainbowBot 1.0,http://robocoderepository.com/BotFiles/3694/deo.virtual.RainbowBot_1.0.jar<br />
dft.Calliope 5.6,http://www.robocoderepository.com/BotFiles/237/dft.Calliope_5.6.jar<br />
dft.Cyanide 1.90,http://robocode-archive.strangeautomata.com/robots/dft.Cyanide_1.90.jar<br />
dft.Cyprus 3.0,http://www.robocoderepository.com/BotFiles/377/dft.Cyprus_3.0.jar<br />
dft.Freddie 1.32,http://robocode-archive.strangeautomata.com/robots/dft.Freddie_1.32.jar<br />
dft.Guppy 1.0,http://robocode-archive.strangeautomata.com/robots/dft.Guppy_1.0.jar<br />
dft.Immortal 1.40,http://robocode-archive.strangeautomata.com/robots/dft.Immortal_1.40.jar<br />
dft.Krazy 1.5,http://www.robocoderepository.com/BotFiles/2099/dft.Krazy_1.5.jar<br />
dft.Virgin 1.25,http://www.robocoderepository.com/BotFiles/1447/dft.Virgin_1.25.jar<br />
dggp.haiku.gpBot_0 1.1,http://www.robocoderepository.com/BotFiles/3154/dggp.haiku.gpBot_0_1.1.jar<br />
dhn.Immortal 1.0,http://www.griessersoftware.com/robocode/dhn.Immortal.1.0.jar<br />
disan.Chair 2.2.0,https://dl.dropboxusercontent.com/u/138299243/Robocode/disan.Chair_2.2.0.jar<br />
discan.mini.Exode 0.25,https://sites.google.com/site/discanroborumblebots/discan.mini.Exode_0.25.jar<br />
dittman.BlindSquirl Retired,http://home.comcast.net/~kokyunage/robocode/ugluk/dittman.BlindSquirl_Retired.jar<br />
divineomega.DivineBot 1.9.4.5,https://dl.dropboxusercontent.com/s/sk33qkpx7cfcmv6/divineomega.DivineBot_1.9.4.5.jar?dl=1&token_hash=AAGI4C3Fm8km-0aLNU3pUVE1JEZqx8UDV6qk5s8PoRgjhg<br />
divineomega.TrialBot 0.003,https://dl.dropboxusercontent.com/s/an44muntp8f0p6h/divineomega.TrialBot_0.003.jar?token_hash=AAG5XTuv2fkEkTYhNIEJ0zre-SpWgK-jvKNqQ120pFeYSA&dl=1<br />
djc.Aardvark 0.3.6,http://www.robocoderepository.com/BotFiles/652/djc.Aardvark_0.3.6.jar<br />
djdjdj.NanoSkunk10 1.0,http://davidjoerg.com/robocode/djdjdj.NanoSkunk10_1.0.jar<br />
dk.stable.Gorgatron 1.1,http://www.robocoderepository.com/BotFiles/2112/dk.stable.Gorgatron_1.1.jar<br />
dks.MicroDanMK2 1.0,http://robocode-archive.strangeautomata.com/robots/dks.MicroDanMK2_1.0.jar<br />
DM.Capriite 3.7.2,http://www.robocoderepository.com/BotFiles/2989/DM.Capriite_3.7.2.jar<br />
DM.Chicken 4.0,http://www.robocoderepository.com/BotFiles/3020/DM.Chicken_4.0.jar<br />
DM.Mijit .3,http://www.robocoderepository.com/BotFiles/3043/DM.Mijit_.3.jar<br />
dmp.micro.Aurora 1.41,http://www.robocoderepository.com/BotFiles/853/dmp.micro.Aurora_1.41.jar<br />
dmp.nano.Eve 3.41,http://www.robocoderepository.com/BotFiles/842/dmp.nano.Eve_3.41.jar<br />
donjezza.Jezza 1.0,http://www.robocoderepository.com/BotFiles/3385/donjezza.Jezza_1.0.jar<br />
donjezza.Muncho 1.0,http://www.robocoderepository.com/BotFiles/3384/donjezza.Muncho_1.0.jar<br />
drd.Dreadknoght 0.9,http://www.robocoderepository.com/BotFiles/3835/drd.Dreadknoght_0.9.jar<br />
drm.CobraBora 1.12,http://www.robocoderepository.com/BotFiles/1146/drm.CobraBora_1.12.jar<br />
drm.Magazine 0.39,http://www.robocoderepository.com/BotFiles/989/drm.Magazine_0.39.jar<br />
ds.OoV4 0.3b,http://www.robocoderepository.com/BotFiles/2851/ds.OoV4_0.3b.jar<br />
dsw.StaticD 1.0,http://robocode-archive.strangeautomata.com/robots/dsw.StaticD_1.0.jar<br />
dsx724.VSAB_EP3a 1.0,http://robocode-archive.strangeautomata.com/robots/dsx724.VSAB_EP3a_1.0.jar<br />
dsx724.VSAB_EP3_ATR 1.1,http://www.robocoderepository.com/BotFiles/3432/dsx724.VSAB_EP3_ATR_1.1.jar<br />
DTF.Kludgy 1.2b,http://www.robocoderepository.com/BotFiles/4041/DTF.Kludgy_1.2b.jar<br />
dukie.Ambassador 1.0,http://www.robocoderepository.com/BotFiles/2845/dukie.Ambassador_1.0.jar<br />
dummy.micro.HummingBird 2.14,http://www.robocoderepository.com/BotFiles/369/dummy.micro.HummingBird_2.14.jar<br />
dummy.micro.Sparrow 2.5,http://www.robocoderepository.com/BotFiles/484/dummy.micro.Sparrow_2.5.jar<br />
dummy.mini.Parakeet 2.40,http://www.robocoderepository.com/BotFiles/400/dummy.mini.Parakeet_2.40.jar<br />
dvogon.GangBang 1.0,http://www.robocoderepository.com/BotFiles/3193/dvogon.GangBang_1.0.jar<br />
dy.LevelOne 2.0,http://www.robocoderepository.com/BotFiles/3452/dy.LevelOne_2.0.jar<br />
dz.Caedo 1.4,http://www.robocoderepository.com/BotFiles/1044/dz.Caedo_1.4.jar<br />
dz.GalbaMicro 0.11,http://www.robocoderepository.com/BotFiles/2482/dz.GalbaMicro_0.11.jar<br />
dz.GalbaMini 0.121,http://robocode-archive.strangeautomata.com/robots/dz.GalbaMini_0.121.jar<br />
dz.MostlyHarmlessNano 2.1,http://www.robocoderepository.com/BotFiles/2166/dz.MostlyHarmlessNano_2.1.jar<br />
dz.OthoMicro 0.12,http://www.robocoderepository.com/BotFiles/2198/dz.OthoMicro_0.12.jar<br />
dz.OthoMini 0.15,http://www.robocoderepository.com/BotFiles/2221/dz.OthoMini_0.15.jar<br />
eat.HumblePieLite 1.0,http://www.robocoderepository.com/BotFiles/1088/eat.HumblePieLite_1.0.jar<br />
EBBU.Sim2 1.02,https://dl.dropbox.com/u/85847696/EBBU.Sim2_1.02.jar<br />
ebo.Sparse 0.02,http://www.4geeks.de/files/ebo.Sparse_0.02.jar<br />
ebo.Tahoe 1.1.79,http://www.4geeks.de/files/ebo.Tahoe_1.1.79.jar<br />
EE.LittleBig 1.0,http://www.robocoderepository.com/BotFiles/4009/EE.LittleBig_1.0.jar<br />
eem.EvBot v4.4.5,http://beamhome.dyndns.org:1680/~evmik/robocode/eem.EvBot_v4.4.5.jar<br />
EFD.AdvancedEFD 0.4.5a,http://robocode-archive.strangeautomata.com/robots/EFD.AdvancedEFD_0.4.5a.jar<br />
EH.Fusion 0.32,http://robocoderepository.com/BotFiles/4300/EH.Fusion_0.32.jar<br />
EH.Pegasus 0.113,http://robocoderepository.com/BotFiles/4304/EH.Pegasus_0.113.jar<br />
EH.kms.LightningStorm 0.11B,http://robocoderepository.com/BotFiles/4311/EH.kms.LightningStorm_0.11B.jar<br />
EH.mini.Panther 0.1C,http://robocoderepository.com/BotFiles/4310/EH.mini.Panther_0.1C.jar<br />
EH.nano.NightBird M,http://robocoderepository.com/BotFiles/4313/EH.nano.NightBird_M.jar<br />
el.Attackr 0.1,http://robocode-archive.strangeautomata.com/robots/el.Attackr_0.1.jar<br />
el.JumpShoot 0.2,http://www.robocoderepository.com/BotFiles/3360/el.JumpShoot_0.2.jar<br />
el33t.EL33tGangstarr2 2.0,http://www.robocoderepository.com/BotFiles/2069/el33t.EL33tGangstarr2_2.0.jar<br />
eld.Hmm 1.0,http://robocode-archive.strangeautomata.com/robots/eld.Hmm_1.0.jar<br />
element.Earth 1.1,http://www.robocoderepository.com/BotFiles/3587/element.Earth_1.1.jar<br />
elloco.Flower 0.1r1,http://www.robocoderepository.com/BotFiles/3242/elloco.Flower_0.1r1.jar<br />
elloco.Kabuto 0.2r,http://www.robocoderepository.com/BotFiles/3229/elloco.Kabuto_0.2r.jar<br />
elvbot.ElverionBot 0.3,http://www.robocoderepository.com/BotFiles/3541/elvbot.ElverionBot_0.3.jar<br />
emp.Yngwie 1.11,http://www.robocoderepository.com/BotFiles/1928/emp.Yngwie_1.11.jar<br />
erdnis.Rover 0.3,http://www.free-games-fun.com/erdnis.Rover_0.3.jar<br />
eskimo.micro.Echo 0.1,http://robocoderepository.com/BotFiles/3969/eskimo.micro.Echo_0.1.jar<br />
et.Predator 1.8,http://www.robocoderepository.com/BotFiles/668/et.Predator_1.8.jar<br />
ethdsy.Malacka 2.4,http://www.robocoderepository.com/BotFiles/1159/ethdsy.Malacka_2.4.jar<br />
evd.X1 0.01,http://www.robocoderepository.com/BotFiles/3503/evd.X1_0.01.jar<br />
exauge.GateKeeper 1.1.121g,http://www.robocoderepository.com/BotFiles/3928/exauge.GateKeeper_1.1.121g.jar<br />
exauge.LemonDrop 1.6.130,http://www.robocoderepository.com/BotFiles/3911/exauge.LemonDrop_1.6.130.jar<br />
exauge.Leopard 1.1.019,http://www.robocoderepository.com/BotFiles/3917/exauge.Leopard_1.1.019.jar<br />
extra.LightSauce 0.01,http://robocoderepository.com/BotFiles/4031/extra.LightSauce_0.01.jar<br />
extra.Sauce .01,http://robocoderepository.com/BotFiles/4029/extra.Sauce_.01.jar<br />
Ex.Survival 3.7,http://robocode-archive.strangeautomata.com/robots/Ex.Survival_3.7.jar?attredirects=0&d=1<br />
fala.robocode.FalaRobot 1.0,http://www.robocoderepository.com/BotFiles/3474/fala.robocode.FalaRobot_1.0.jar<br />
FatalFlaw.FatalFlaw 1.0.5,http://www.robocoderepository.com/BotFiles/4133/FatalFlaw.FatalFlaw_1.0.5.jar<br />
fcr.First 1.0,http://www.robocoderepository.com/BotFiles/3362/fcr.First_1.0.jar<br />
Fenix.FenixTrack 1.0,http://www.robocoderepository.com/BotFiles/1627/Fenix.FenixTrack_1.0.jar<br />
florent.FloatingTadpole 1.2.6,http://www.robocoderepository.com/BotFiles/2675/florent.FloatingTadpole_1.2.6.jar<br />
florent.small.LittleAngel 1.8,http://www.robocoderepository.com/BotFiles/2917/florent.small.LittleAngel_1.8.jar<br />
florent.test.Toad 0.14t,http://robocode-archive.strangeautomata.com/robots/florent.test.Toad_0.14t.jar<br />
florent.XSeries.X2 0.17,http://wesley3.free.fr/florent.XSeries.X2_0.17.jar<br />
fm.claire 1.7,http://www.robocoderepository.com/BotFiles/2251/fm.claire_1.7.jar<br />
fm.mammillarias 1.3,http://www.robocoderepository.com/BotFiles/2238/fm.mammillarias_1.3.jar<br />
fnc.bandit.Bandit 5.2.0,http://www.robocoderepository.com/BotFiles/2155/fnc.bandit.Bandit_5.2.0.jar<br />
fnc.bandit2002.Bandit2002 4.0.2,http://www.robocoderepository.com/BotFiles/2202/fnc.bandit2002.Bandit2002_4.0.2.jar<br />
frag.FragBot 1.0,http://robocode-archive.strangeautomata.com/robots/frag.FragBot_1.0.jar<br />
franzor.Lizt 1.3.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/franzor.Lizt_1.3.1.jar<br />
froh.micro.Aversari 0.31,https://dl.dropbox.com/u/60122033/Bots/froh.micro.Aversari_0.31.jar<br />
fromHell.BlackBox 0.1,http://fromhell.schreiende-stille.de/Robocode/Java/fromHell.BlackBox_0.1.jar<br />
fromHell.C22H30N2O2S 2.2,http://fromhell.schreiende-stille.de/Robocode/Java/fromHell.C22H30N2O2S_2.2.jar<br />
fromHell.C4H10O 1.5.1,http://fromhell.schreiende-stille.de/Robocode/Java/fromHell.C4H10O_1.5.1.jar<br />
fromHell.CHCl3 1.4.2,http://fromhell.schreiende-stille.de/Robocode/Java/fromHell.CHCl3_1.4.2.jar<br />
fruits.NanoStrawbery 1.3,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/fruits.NanoStrawbery_1.3.jar<br />
fullsail.LaxativeTeaTwo 1.0,http://www.robocoderepository.com/BotFiles/3403/fullsail.LaxativeTeaTwo_1.0.jar<br />
fullsail.TimbotNoPrediction 1.0,http://robocode-archive.strangeautomata.com/robots/fullsail.TimbotNoPrediction_1.0.jar<br />
fullsail.SweetTea 1.1,http://robocode-archive.strangeautomata.com/robots/fullsail.SweetTea_1.1.jar<br />
fushi.PvP1.PvP1 2004-02-16,http://www.robocoderepository.com/BotFiles/2023/fushi.PvP1.PvP1_2004-02-16.jar<br />
fw.Number1 1.0b,http://robocode-archive.strangeautomata.com/robots/fw.Number1_1.0b.jar<br />
gadsky.Gadsky 1.01,http://www.robocoderepository.com/BotFiles/3595/gadsky.Gadsky_1.01.jar<br />
Gecko.ultimateGeckoBot 1.0,http://www.robocoderepository.com/BotFiles/4039/Gecko.ultimateGeckoBot_1.0.jar<br />
geep.mini.GPBotA 1.0,http://www.robocoderepository.com/BotFiles/2361/geep.mini.GPBotA_1.0.jar<br />
geep.mini.GPBotB 1.1,http://www.robocoderepository.com/BotFiles/2363/geep.mini.GPBotB_1.1.jar<br />
genprog.Gajeel 1.0,http://www.robocoderepository.com/BotFiles/4287/genprog.Gajeel_1.0.jar<br />
genprog.Rinmorikazu 1.0,http://www.robocoderepository.com/BotFiles/4286/genprog.Rinmorikazu_1.0.jar<br />
genprog.Zafaran 1.0,http://www.robocoderepository.com/BotFiles/4288/genprog.Zafaran_1.0.jar<br />
germ.TheMind .2,http://www.robocoderepository.com/BotFiles/2525/germ.TheMind_.2.jar<br />
gf.Centaur.Centaur 0.6.7,http://www.robocoderepository.com/BotFiles/4066/gf.Centaur.Centaur_0.6.7.jar<br />
gg.Squaraus 0.6,http://www.robocoderepository.com/BotFiles/1788/gg.Squaraus_0.6.jar<br />
gg.Wolverine 2.0,http://robocode-archive.strangeautomata.com/robots/gg.Wolverine_2.0.jar<br />
gh.GresSuffurd 0.3.14,http://home.versatel.nl/gheijenk/robocode/jarfiles/gh.GresSuffurd_0.3.14.jar<br />
gh.GrubbmGrb 1.2.4,http://home.versatel.nl/gheijenk/robocode/jarfiles/gh.GrubbmGrb_1.2.4.jar<br />
gh.GrypRepetyf 0.13,http://www.robocoderepository.com/BotFiles/2650/gh.GrypRepetyf_0.13.jar<br />
gh.micro.Grinnik 0.7,http://www.robocoderepository.com/BotFiles/3208/gh.micro.Grinnik_0.7.jar<br />
gh.micro.GrubbmThree 0.9,http://www.robocoderepository.com/BotFiles/2444/gh.micro.GrubbmThree_0.9.jar<br />
gh.mini.Gruwel 0.9,http://www.robocoderepository.com/BotFiles/2511/gh.mini.Gruwel_0.9.jar<br />
gh.nano.Grofvuil 0.2,http://www.robocoderepository.com/BotFiles/2553/gh.nano.Grofvuil_0.2.jar<br />
gimp.GimpBot 0.1,http://www.robocoderepository.com/BotFiles/2434/gimp.GimpBot_0.1.jar<br />
gio.RealGioBot 1.0,http://www.robocoderepository.com/BotFiles/2521/gio.RealGioBot_1.0.jar<br />
gjr.Cephalosporin 0.2,http://www.robocoderepository.com/BotFiles/2240/gjr.Cephalosporin_0.2.jar<br />
gm.GaetanoA 2.15,http://www.robocoderepository.com/BotFiles/2188/gm.GaetanoA_2.15.jar<br />
goblin.Bender 2.4,http://www.robocoderepository.com/BotFiles/1871/goblin.Bender_2.4.jar<br />
grybgoofy.GoofyBot 0.10,http://www.robocoderepository.com/BotFiles/2196/grybgoofy.GoofyBot_0.10.jar<br />
gtf.robocode.Strafer 2.1.1,http://www.cirp.org/tmp/robocode/gtf.robocode.Strafer-2.1.1.jar<br />
gu.MicroScoob 1.3,http://www.robocoderepository.com/BotFiles/2086/gu.MicroScoob_1.3.jar<br />
gwah.GBotMarkIV 1.0,http://robocode-archive.strangeautomata.com/robots/gwah.GBotMarkIV_1.0.jar<br />
gwah.GerryBotMkII 1.5.1,http://robocode-archive.strangeautomata.com/robots/gwah.GerryBotMkII_1.5.1.jar<br />
ha2.T2 0.2,http://www.robocoderepository.com/BotFiles/4225/ha2.T2_0.2.jar<br />
ha2.T2b 0.2b,http://www.robocoderepository.com/BotFiles/4227/ha2.T2b_0.2b.jar<br />
ha2.T3 0.1,http://www.robocoderepository.com/BotFiles/4228/ha2.T3_0.1.jar<br />
ha2.T3 0.2,http://www.robocoderepository.com/BotFiles/4229/ha2.T3_0.2.jar<br />
hamilton.Hamilton 1.0,http://www.robocoderepository.com/BotFiles/1408/hamilton.Hamilton_1.0.jar<br />
hapiel.Spiral 0.1,http://robocoderepository.com/BotFiles/3997/hapiel.Spiral_0.1.jar<br />
Heal.TekitokaBot 1.0,http://www.robocoderepository.com/BotFiles/4285/Heal.TekitokaBot_1.0.jar<br />
hirataatsushi.Neo 1.6,http://www.robocoderepository.com/BotFiles/1081/hirataatsushi.Neo_1.6.jar<br />
hirataatsushi.Trinity 0.003,http://www.robocoderepository.com/BotFiles/1145/hirataatsushi.Trinity_0.003.jar<br />
hlavko.nano.Phoenix 1.0, http://robocode.hmark.eu/hlavko.nano.Phoenix_1.0.jar<br />
hlavko.nano.Ringo 1.0d, http://robocode.hmark.eu/hlavko.nano.Ringo_1.0d.jar<br />
hlavko.nano.Ringo 2.0, http://robocode.hmark.eu/hlavko.nano.Ringo_2.0.jar<br />
hlavko.micro.Flex 1.5, http://robocode.hmark.eu/hlavko.micro.Flex_1.5.jar<br />
homerbots.h1 1.0,http://www.robocoderepository.com/BotFiles/2999/homerbots.h1_1.0.jar<br />
hp.Athena 0.1,http://www.robocoderepository.com/BotFiles/3415/hp.Athena_0.1.jar<br />
hs.SimpleHBot 1.3,http://www.robocoderepository.com/BotFiles/4112/hs.SimpleHBot_1.3.jar<br />
hvilela.HVilela 0.9,http://robocode-archive.strangeautomata.com/robots/hvilela.HVilela_0.9.jar<br />
ICS4U1.Patrick_White_Schrodinger 1.1,http://www.robocoderepository.com/BotFiles/4087/ICS4U1.Patrick_White_Schrodinger_1.1.jar<br />
ins.MobyNano 0.8,http://www.robocoderepository.com/BotFiles/939/ins.MobyNano_0.8.jar<br />
intruder.PrairieWolf 2.61,http://robocode-archive.strangeautomata.com/robots/intruder.PrairieWolf_2.61.jar<br />
ivor.prophet.Prophet 0.01,http://www.ivan.php5.sk/ivor.prophet.Prophet_0.01.jar<br />
is.fon.rs.FonDestroyer3084 1.0,http://www.robocoderepository.com/BotFiles/4047/is.fon.rs.FonDestroyer3084_1.0.jar<br />
is.fon.rs.Kamikaza 1.0,https://dl.dropboxusercontent.com/u/81048920/is.fon.rs.Kamikaza_1.0.jar<br />
jaara.LambdaBot 1.1,http://www.robocoderepository.com/BotFiles/3514/jaara.LambdaBot_1.1.jar<br />
jab.avk.ManuelGallegus 0.6,http://robocode-archive.strangeautomata.com/robots/jab.avk.ManuelGallegus_0.6.jar<br />
jab.DiamondStealer 5,http://robocode-archive.strangeautomata.com/robots/jab.DiamondStealers_5.jar<br />
jab.micro.Sanguijuela 0.8,http://robocode-archive.strangeautomata.com/robots/jab.micro.Sanguijuela_0.8.jar<br />
janm.Jammy 1.0,http://www.robocoderepository.com/BotFiles/3543/janm.Jammy_1.0.jar<br />
jam.micro.RaikoMicro 1.44,http://www.robocoderepository.com/BotFiles/1983/jam.micro.RaikoMicro_1.44.jar<br />
jam.mini.Raiko 0.43,http://www.robocoderepository.com/BotFiles/1922/jam.mini.Raiko_0.43.jar<br />
jam.RaikoMX 0.32,http://www.robocoderepository.com/BotFiles/1961/jam.RaikoMX_0.32.jar<br />
japs.Serenity 1.0,http://www.robocoderepository.com/BotFiles/2217/japs.Serenity_1.0.jar<br />
japs.Sjonniebot 0.9.1,http://www.robocoderepository.com/BotFiles/2203/japs.Sjonniebot_0.9.1.jar<br />
jasolo.Sonda 0.55,http://www.robocoderepository.com/BotFiles/1534/jasolo.Sonda_0.55.jar<br />
jaw.Mouse 0.11,http://www.robocoderepository.com/BotFiles/2472/jaw.Mouse_0.11.jar<br />
jaw.KarenCain 0.11,http://www.robocoderepository.com/BotFiles/2474/jaw.KarenCain_0.11.jar<br />
jaybot.adv.bots.JayBot 2.0,http://robocode-archive.strangeautomata.com/robots/jaybot.adv.bots.JayBot_2.0.jar<br />
jaybot.bots.Oddball 4.0,http://robocode-archive.strangeautomata.com/robots/jaybot.bots.Oddball_4.0.jar<br />
jbot.Rabbit2 1.1,http://robocode-archive.strangeautomata.com/robots/jbot.Rabbit2_1.1.jar<br />
jcs.AutoBot 4.2.1,http://www.robocoderepository.com/BotFiles/2616/jcs.AutoBot_4.2.1.jar<br />
jcs.Decepticon 2.5.3,http://www.robocoderepository.com/BotFiles/2620/jcs.Decepticon_2.5.3.jar<br />
jcs.Megatron 1.2,http://www.robocoderepository.com/BotFiles/2632/jcs.Megatron_1.2.jar<br />
jcs.Seth 1.8,http://robocode-archive.strangeautomata.com/robots/jcs.Seth_1.8.jar<br />
jcw.ArcherOne 1.0,http://robocode-archive.strangeautomata.com/robots/jcw.ArcherOne_1.0.jar<br />
jdw.Hornet 1.0,http://robocode-archive.strangeautomata.com/robots/jdw.Hornet_1.0.jar<br />
jekl.DarkHallow .90.9,http://www.robocoderepository.com/BotFiles/2296/jekl.DarkHallow_.90.9.jar<br />
jekl.Jekyl .70,http://www.robocoderepository.com/BotFiles/1837/jekl.Jekyl_.70.jar<br />
jekl.mini.BlackPearl .91,http://www.robocoderepository.com/BotFiles/1875/jekl.mini.BlackPearl_.91.jar<br />
jep.nano.Hawkwing 0.4.1,http://www.robocoderepository.com/BotFiles/1561/jep.nano.Hawkwing_0.4.1.jar<br />
jep.nano.Hotspur 0.1,http://www.robocoderepository.com/BotFiles/1877/jep.nano.Hotspur_0.1.jar<br />
jep.Terrible 0.4.1,http://www.robocoderepository.com/BotFiles/1536/jep.Terrible_0.4.1.jar<br />
jeremyreeder.Bully 1,http://thesafehouse.info/robocode/jeremyreeder.Bully_1.jar<br />
jeremyreeder.collective.Prophet 5,http://thesafehouse.info/robocode/jeremyreeder.collective.Prophet_5.jar<br />
jeremyreeder.Vincent 2011.12.09,http://www.robocoderepository.com/BotFiles/3993/jeremyreeder.Vincent_2011.12.09.jar<br />
jf.Dodger 1.3,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/jf.Dodger_1.3.jar<br />
jgap.JGAP12584 1.0,http://www.robocoderepository.com/BotFiles/3383/jgap.JGAP12584_1.0.jar<br />
jgap.JGAP130166 1.0,http://www.robocoderepository.com/BotFiles/3371/jgap.JGAP130166_1.0.jar<br />
jgap.JGAP23423 1.0,http://www.robocoderepository.com/BotFiles/3378/jgap.JGAP23423_1.0.jar<br />
jgap.JGAP6139 1.0,http://www.robocoderepository.com/BotFiles/3372/jgap.JGAP6139_1.0.jar<br />
jgap.JGAP7247_2 1.0,http://www.robocoderepository.com/BotFiles/3382/jgap.JGAP7247_2_1.0.jar<br />
jgap.JGAP7958 1.0,http://www.robocoderepository.com/BotFiles/3373/jgap.JGAP7958_1.0.jar<br />
jje.BagPuss 1.2,http://robocode-archive.strangeautomata.com/robots/jje.BagPuss_1.2.jar<br />
jk.mega.DrussGT 3.1.3,https://dl.dropboxusercontent.com/u/4066735/jk.mega.DrussGT_3.1.3.jar<br />
jk.melee.Neuromancer 4.3,https://dl.dropboxusercontent.com/u/4066735/jk.melee.Neuromancer_4.3.jar<br />
jk.micro.Cotillion 0.8,https://dl.dropboxusercontent.com/u/4066735/jk.micro.Cotillion_0.8.jar<br />
jk.mini.CunobelinDC 1.2,https://dl.dropboxusercontent.com/u/4066735/jk.mini.CunobelinDC_1.2.jar<br />
jk.nano.Machete 2.0, https://dl.dropboxusercontent.com/u/4066735/jk.nano.Machete_2.0.jar<br />
jk.precise.EnergyDome 1.6,https://dl.dropboxusercontent.com/u/4066735/jk.precise.EnergyDome_1.6.jar<br />
jk.precise.Wintermute 0.7,http://robocode-archive.strangeautomata.com/robots/jk.precise.Wintermute_0.7.jar<br />
jk.sheldor.nano.Yatagan 1.2.3,https://dl.dropboxusercontent.com/u/4066735/jk.sheldor.nano.Yatagan_1.2.3.jar<br />
jmcd.BeoWulf 2.8,http://www.robocoderepository.com/BotFiles/1377/jmcd.BeoWulf_2.8.jar<br />
joe.ADinosaur 1.0,http://www.robocoderepository.com/BotFiles/2822/joe.ADinosaur_1.0.jar<br />
josago.Jorgito 0.16,http://www.robocoderepository.com/BotFiles/4000/josago.Jorgito_0.16.jar<br />
jp.Perpy 16.0,http://www.robocoderepository.com/BotFiles/3001/jp.Perpy_16.0.jar<br />
jp.SineWall 1.0,http://www.robocoderepository.com/BotFiles/2968/jp.SineWall_1.0.jar<br />
jrm.Test0 1.0,http://www.robocoderepository.com/BotFiles/3636/jrm.Test0_1.0.jar<br />
js.PinBall 1.6,http://www.robocoderepository.com/BotFiles/684/js.PinBall_1.6.jar<br />
jsal.Jsalbot 1.0,http://robocode-archive.strangeautomata.com/robots/jsal.Jsalbot_1.0.jar<br />
jt.SpearmintCT Alpha,http://www.robocoderepository.com/BotFiles/2164/jt.SpearmintCT_Alpha.jar<br />
justin.DemonicRage 3.20,http://robocode-archive.strangeautomata.com/robots/justin.DemonicRage_3.20.jar<br />
jw.Booring 1.11,http://www.robocoderepository.com/BotFiles/1250/jw.Booring_1.11.jar<br />
jwirde.Gort 2.0,https://docs.google.com/uc?export=download&id=0B5g5k-WHNBJicHpNNXotVE9aNHc<br />
jwst.DAD.DarkAndDarker 1.1,http://robocode-archive.strangeautomata.com/robots/jwst.DAD.DarkAndDarker_1.1.jar<br />
kanishk.Fr0z3n 1.1,http://robocode-archive.strangeautomata.com/robots/kanishk.Fr0z3n_1.1.jar<br />
kano.gamma.KanoGamma 1.8,http://www.robocoderepository.com/BotFiles/1098/kano.gamma.KanoGamma_1.8.jar<br />
kawam.kmBot9 1.0,http://www.robocoderepository.com/BotFiles/967/kawam.kmBot9_1.0.jar<br />
kawigi.f.FhqwhgadsMicro 1.0,http://www.robocoderepository.com/BotFiles/1673/kawigi.f.FhqwhgadsMicro_1.0.jar<br />
kawigi.micro.Shiz 1.1,http://www.robocoderepository.com/BotFiles/2007/kawigi.micro.Shiz_1.1.jar<br />
kawigi.mini.Coriantumr 1.1,http://www.robocoderepository.com/BotFiles/1988/kawigi.mini.Coriantumr_1.1.jar<br />
kawigi.mini.Fhqwhgads 1.1,http://www.robocoderepository.com/BotFiles/1604/kawigi.mini.Fhqwhgads_1.1.jar<br />
kawigi.nano.FunkyChicken 1.1,http://www.robocoderepository.com/BotFiles/1512/kawigi.nano.FunkyChicken_1.1.jar<br />
kawigi.nano.ThnikkaBot 0.9,http://www.robocoderepository.com/BotFiles/2059/kawigi.nano.ThnikkaBot_0.9.jar<br />
kawigi.robot.Girl 1.2,http://www.robocoderepository.com/BotFiles/2124/kawigi.robot.Girl_1.2.jar<br />
kawigi.sbf.Barracuda 1.0,http://www.robocoderepository.com/BotFiles/1535/kawigi.sbf.Barracuda_1.0.jar<br />
kawigi.sbf.FloodHT 0.9.2,http://www.robocoderepository.com/BotFiles/1552/kawigi.sbf.FloodHT_0.9.2.jar<br />
kawigi.sbf.FloodMicro 1.5,http://www.robocoderepository.com/BotFiles/1381/kawigi.sbf.FloodMicro_1.5.jar<br />
kawigi.sbf.FloodMini 1.4,http://www.robocoderepository.com/BotFiles/1462/kawigi.sbf.FloodMini_1.4.jar<br />
kawigi.sbf.FloodNano 1.2,http://www.robocoderepository.com/BotFiles/1421/kawigi.sbf.FloodNano_1.2.jar<br />
kawigi.sbf.FloodSonnet 0.9,http://www.robocoderepository.com/BotFiles/1779/kawigi.sbf.FloodSonnet_0.9.jar<br />
kawigi.sbf.Teancum 1.3,http://www.robocoderepository.com/BotFiles/1470/kawigi.sbf.Teancum_1.3.jar<br />
kawigi.spare.SpareParts 0.7.6nosnd,http://www.robocoderepository.com/BotFiles/1335/kawigi.spare.SpareParts_0.7.6nosnd.jar<br />
kb.PingPong 1.0,http://www.griessersoftware.com/robocode/kb.PingPong.1.0.jar<br />
kc.micro.Needle 0.101,http://www.robocoderepository.com/BotFiles/3379/kc.micro.Needle_0.101.jar<br />
kc.micro.Thorn 1.252,http://robocode-archive.strangeautomata.com/robots/kc.micro.Thorn_1.252.jar<br />
kc.micro.WaveShark 0.31,http://www.robocoderepository.com/BotFiles/3822/kc.micro.WaveShark_0.31.jar<br />
kc.mini.Vyper 0.311,http://robocode-archive.strangeautomata.com/robots/kc.mini.Vyper_0.311.jar<br />
kc.nano.Splinter 1.2,http://robocode-archive.strangeautomata.com/robots/kc.nano.Splinter_1.2.jar<br />
kc.serpent.Hydra 0.21,http://robocode-archive.strangeautomata.com/robots/kc.serpent.Hydra_0.21.jar<br />
kc.serpent.WaveSerpent 2.11,http://robocode-archive.strangeautomata.com/robots/kc.serpent.WaveSerpent_2.11.jar<br />
kcn.percept.PerceptBot 2.3,http://www.robocoderepository.com/BotFiles/1075/kcn.percept.PerceptBot_2.3.jar<br />
kcn.unnamed.Unnamed 1.21,http://www.robocoderepository.com/BotFiles/1969/kcn.unnamed.Unnamed_1.21.jar<br />
kenran.InfiniteObscurity 0.8,https://dl.dropboxusercontent.com/u/66821565/robots/kenran.InfiniteObscurity_0.8.jar<br />
kenran.mega.Pantheist 1.1,http://robocode-archive.strangeautomata.com/robots/kenran.mega.Pantheist_1.1.jar<br />
kid.Gladiator .7.2,http://robocode-archive.strangeautomata.com/robots/kid.Gladiator_.7.2.jar<br />
kid.Toa .0.5,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/kid.Toa_.0.5.jar<br />
KiraNL.Cataris 1.0,http://robocode-archive.strangeautomata.com/robots/KiraNL.Cataris_1.0.jar<br />
KiraNL.Chupacabra 0.5,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.Chupacabra_0.5.jar<br />
KiraNL.ChupaLite 0.4,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.ChupaLite_0.4.jar<br />
KiraNL.SpaceKees 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/KiraNL.SpaceKees_0.1.jar<br />
kinsen.melee.Angsaichmophobia 1.8c,http://robocode-archive.strangeautomata.com/robots/kinsen.melee.Angsaichmophobia_1.8c.jar<br />
kinsen.nano.Charp 1.0,https://dl.dropbox.com/s/xivyqm5qi4z2bvp/kinsen.nano.Charp_1.0.jar?dl=1<br />
kinsen.nano.Hoplomachy 1.6,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Hoplomachy_1.6.jar<br />
kinsen.nano.Quarrelet 1.0,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Quarrelet_1.0.jar<br />
kinsen.nano.Senticous 1.0,http://robocode-archive.strangeautomata.com/robots/kinsen.nano.Senticous_1.0.jar<br />
kjc.etc.Dharok 1.0,http://www.robocoderepository.com/BotFiles/3293/kjc.etc.Dharok_1.0.jar<br />
kjc.MailManX 2.0,http://www.robocoderepository.com/BotFiles/3288/kjc.MailManX_2.0.jar<br />
kjc.Karaykan 1.0,http://www.robocoderepository.com/BotFiles/3289/kjc.Karaykan_1.0.jar<br />
klein.GottesKrieger 1.1,http://www.robocoderepository.com/BotFiles/3258/klein.GottesKrieger_1.1.jar<br />
kms.Golden 0.10,http://www.robocoderepository.com/BotFiles/4316/kms.Golden_0.10.jar<br />
kneels.ToNoone 0.2,http://www.schickt.de/robocode/kneels.ToNoone_0.2.jar<br />
kneels.nano.Derp 0.2,http://www.schickt.de/robocode/kneels.nano.Derp_0.2.jar<br />
Krabb.fe4r.Fe4r 0.4,http://www.robocoderepository.com/BotFiles/2766/Krabb.fe4r.Fe4r_0.4.jar<br />
Krabb.sliNk.Garm 0.9u,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/Krabb.sliNk.Garm_0.9u.jar<br />
Krabb.krabby.Krabby 1.18b,http://robocode-archive.strangeautomata.com/robots/Krabb.krabby.Krabby_1.18b.jar<br />
Krabb.krabby2.Krabby2 1.9o,http://robocode-archive.strangeautomata.com/robots/Krabb.krabby2.Krabby2_1.9o.jar<br />
krillr.mini.JointStrike 2.0.0,http://robocode-archive.strangeautomata.com/robots/krillr.mini.JointStrike_2.0.0.jar<br />
krillr.mega.Psyche 0.0.3,http://robocode-archive.strangeautomata.com/robots/krillr.mega.Psyche_0.0.3.jar<br />
kronenthaler.Basilisk 1.0,http://www.robocoderepository.com/BotFiles/4051/kronenthaler.Basilisk_1.0.jar<br />
krzysiek.robbo2.Robbo 1.0.0,http://robocode-archive.strangeautomata.com/robots/krzysiek.robbo2.Robbo_1.0.0.jar<br />
kurios.DOSexe .9a,http://www.kuriosly.com/roborumble/kurios.DOSexe_.9a.jar<br />
kvk.HebusLeTroll 0.41,http://www.robocoderepository.com/BotFiles/2125/kvk.HebusLeTroll_0.41.jar<br />
labg.Cataclysm 2.05,http://www.robocoderepository.com/BotFiles/2399/labg.Cataclysm_2.05.jar<br />
lancel.Lynx 1.09,http://www.robocoderepository.com/BotFiles/3992/lancel.Lynx_1.09.jar<br />
lazarecki.mega.PinkerStinker 0.7,http://www.robocoderepository.com/BotFiles/3838/lazarecki.mega.PinkerStinker_0.7.jar<br />
leb.ShootAnArrow 0.1,http://www.robocoderepository.com/BotFiles/2648/leb.ShootAnArrow_0.1.jar<br />
lechu.Ala 0.0.4,http://www.robocoderepository.com/BotFiles/3497/lechu.Ala_0.0.4.jar<br />
lechu.Lechu 1.1,http://www.robocoderepository.com/BotFiles/3480/lechu.Lechu_1.1.jar<br />
Legend.Biogon 1.5,http://robocode-archive.strangeautomata.com/robots/Legend.Biogon_1.5.jar?attredirects=0&d=1<br />
Legend.BoulderZY 1.4.9,http://robocode-archive.strangeautomata.com/robots/Legend.BoulderZY_1.4.9.jar?attredirects=0&d=1<br />
Legend.Qetro 1.6,http://robocode-archive.strangeautomata.com/robots/Legend.Qetro_1.6.jar?attredirects=0&d=1<br />
Legend.X_FireFly 1.3,http://robocode-archive.strangeautomata.com/robots/Legend.X_FireFly_1.3.jar?attredirects=0&d=1<br />
lessonz.robocode.Oz 0.5.0,https://dl.dropbox.com/u/9231432/robocode/lessonz.robocode.Oz-0.5.0.jar<br />
lion.Kresnanano 1.0,http://www.robocoderepository.com/BotFiles/2295/lion.Kresnanano_1.0.jar<br />
lk.nano.Avesnar 1.1,http://www.robocoderepository.com/BotFiles/1597/lk.nano.Avesnar_1.1.jar<br />
lmk.ACPFinal 0.2,http://pillow.rscheme.org/lmk.ACPFinal_0.2.jar<br />
Lo_Ian.Gandalf_V4 4.0,http://www.robocoderepository.com/BotFiles/4305/Lo_Ian.Gandalf_V4_4.0.jar<br />
lorneswork.Predator 1.0,http://www.robocoderepository.com/BotFiles/2609/lorneswork.Predator_1.0.jar<br />
logiblocs.Fire 1.0,https://dl.dropboxusercontent.com/u/66369360/logiblocs.Fire_1.0.jar<br />
logiblocs.SittingDroid 1.0,https://dl.dropboxusercontent.com/u/66369360/logiblocs.SittingDroid_1.0.jar<br />
lrem.Spectre 0.4.4,http://www.robocoderepository.com/BotFiles/2253/lrem.Spectre_0.4.4.jar<br />
lrem.magic.TormentedAngel Antiquitie,http://robocode-archive.strangeautomata.com/robots/lrem.magic.TormentedAngel_Antiquitie.jar<br />
lrem.micro.MoggFanatic 0.2,http://www.robocoderepository.com/BotFiles/2639/lrem.micro.MoggFanatic_0.2.jar<br />
lrem.micro.FalseProphet Alpha,http://www.robocoderepository.com/BotFiles/2415/lrem.micro.FalseProphet_Alpha.jar<br />
lrem.quickhack.QuickHack 1.0,http://www.robocoderepository.com/BotFiles/2555/lrem.quickhack.QuickHack_1.0.jar<br />
lucasslf.Dodger 1.0,http://robocode-archive.strangeautomata.com/robots/lucasslf.Dodger_1.0.jar<br />
lucasslf.HariSeldon 0.2.1,http://robocode-archive.strangeautomata.com/robots/lucasslf.HariSeldon_0.2.1.jar<br />
lucasslf.Wiggins 0.6,http://robocode-archive.strangeautomata.com/robots/lucasslf.Wiggins_0.6.jar<br />
lunchie.Lunchbox 0.93,http://robocode-archive.strangeautomata.com/robots/lunchie.Lunchbox_0.93.jar<br />
lundal.Mark8 2012.09.15,https://dl.dropbox.com/s/gcs13tapwtwpdwc/lundal.Mark8_2012.09.15.jar<br />
lw.LuthersTest 0.1,http://robocode-archive.strangeautomata.com/robots/lw.LuthersTest_0.1.jar<br />
lxx.ConceptA 0.8,https://github.com/aleksey-zhidkov/ConceptA/raw/master/builds/lxx.ConceptA_0.8.jar<br />
lxx.Tomcat 3.68,https://github.com/aleksey-zhidkov/Tomcat/raw/develop/builds/lxx.Tomcat_3.68.jar<br />
m3thos.Eva00 1.1,http://robocode-archive.strangeautomata.com/robots/m3thos.Eva00_1.1.jar<br />
m3thos.Eva02 0.7.1,http://robocode-archive.strangeautomata.com/robots/m3thos.Eva02_0.7.1.jar<br />
m3thos.mini.Eva01 0.5.5,http://robocode-archive.strangeautomata.com/robots/m3thos.mini.Eva01_0.5.5.jar<br />
ma.is.fon.rs.RobotA 0.01,http://www.robocoderepository.com/BotFiles/4048/ma.is.fon.rs.RobotA_0.01.jar<br />
madmath.Cow 0.1.1,http://www.robocoderepository.com/BotFiles/3476/madmath.Cow_0.1.1.jar<br />
mae.Mae1 1.1,http://www.robocoderepository.com/BotFiles/4267/mae.Mae1_1.1.jar<br />
mahrgell.mahrram 1.3,http://www.robocoderepository.com/BotFiles/4284/mahrgell.mahrram_1.3.jar<br />
marcinek.TopGun 1.3,http://www.robocoderepository.com/BotFiles/3458/marcinek.TopGun_1.3.jar<br />
maribo.FollowFire 1.11,http://www.robocoderepository.com/BotFiles/4281/maribo.FollowFire_1.11.jar<br />
maribo.IotaCT 1.0,http://www.robocoderepository.com/BotFiles/4189/maribo.IotaCT_1.0.jar<br />
maribo.melee.BMV 0.1,http://www.robocoderepository.com/BotFiles/4289/maribo.melee.BMV_0.1.jar<br />
maribo.Omicron 1.0,http://www.robocoderepository.com/BotFiles/4191/maribo.Omicron_1.0.jar<br />
marksteam.Phoenix 1.0,http://www.robocoderepository.com/BotFiles/2749/marksteam.Phoenix_1.0.jar<br />
matt.advanced.Katana 1.0,http://www.robocoderepository.com/BotFiles/2498/matt.advanced.Katana_1.0.jar<br />
matt.BlueMind 0.8.00,http://www.robocoderepository.com/BotFiles/2685/matt.BlueMind_0.8.00.jar<br />
matt.UnderDark3 2.4.34,http://www.robocoderepository.com/BotFiles/2485/matt.UnderDark3_2.4.34.jar<br />
matt.UnderDark4 0.4.00,http://www.robocoderepository.com/BotFiles/2644/matt.UnderDark4_0.4.00.jar<br />
mb.Beast 0.4.1,http://cdn.bitbucket.org/mbrahm/robodownloads/downloads/mb.Beast_0.4.1.jar<br />
mb.Monte 0.1.0,http://cdn.bitbucket.org/mbrahm/robodownloads/downloads/mb.Monte_0.1.0.jar<br />
mbh.Mbh 0.1,http://www.robocoderepository.com/BotFiles/3365/mbh.Mbh_0.1.jar<br />
mbro.BelajarBot 0.0.3,http://www.robocoderepository.com/BotFiles/2471/mbro.BelajarBot_0.0.3.jar<br />
mbro.Detektor3 0.1.1,http://www.robocoderepository.com/BotFiles/2478/mbro.Detektor3_0.1.1.jar<br />
mc.Messapia 0.1.8,http://www.robocoderepository.com/BotFiles/2223/mc.Messapia_0.1.8.jar<br />
mcb.Audace 1.3,http://www.robocoderepository.com/BotFiles/3424/mcb.Audace_1.3.jar<br />
McS.Spanky_test 0.1a,http://www.robocoderepository.com/BotFiles/4067/McS.Spanky_test_0.1a.jar<br />
md.November 1.0,http://www.robocoderepository.com/BotFiles/1004/md.November_1.0.jar<br />
md.Pasta 1.1,http://www.robocoderepository.com/BotFiles/1014/md.Pasta_1.1.jar<br />
md.VelociRaptor 1.3,http://www.robocoderepository.com/BotFiles/232/md.VelociRaptor_1.3.jar<br />
mdouet.BotKicker 2.0,http://www.robocoderepository.com/BotFiles/1478/mdouet.BotKicker_2.0.jar<br />
metal.small.MCool 1.21,http://www.robocoderepository.com/BotFiles/1698/metal.small.MCool_1.21.jar<br />
metal.small.dna2.MCoolDNA 1.5,http://www.robocoderepository.com/BotFiles/2354/metal.small.dna2.MCoolDNA_1.5.jar<br />
microtestbotpack.MicroTestBot 1.0,https://dl.dropboxusercontent.com/u/4547352/robocode/microtestbotpack.MicroTestBot_1.0.jar<br />
mjhjd.MattHussey1 1.1,https://dl.dropbox.com/u/90567837/mjhjd.MattHussey1_1.1.jar<br />
mk.Alpha 0.2.1,http://robocode-archive.strangeautomata.com/robots/mk.Alpha_0.2.1.jar<br />
mladjo.AIR 0.7,http://www.robocoderepository.com/BotFiles/3187/mladjo.AIR_0.7.jar<br />
mladjo.GnuKlub 0.1,http://robocode-archive.strangeautomata.com/robots/mladjo.GnuKlub_0.1.jar<br />
mladjo.Grrrrr 0.9,http://www.robocoderepository.com/BotFiles/3189/mladjo.Grrrrr_0.9.jar<br />
mladjo.iRobot 0.3,http://www.robocoderepository.com/BotFiles/3149/mladjo.iRobot_0.3.jar<br />
mladjo.Startko 1.0,http://www.robocoderepository.com/BotFiles/3186/mladjo.Startko_1.0.jar<br />
mld.DustBunny 3.8,http://www.robocoderepository.com/BotFiles/3650/mld.DustBunny_3.8.jar<br />
mld.Infinity 2.2,http://www.robocoderepository.com/BotFiles/3591/mld.Infinity_2.2.jar<br />
mld.LittleBlackBook 1.69e,http://robocode-archive.strangeautomata.com/robots/mld.LittleBlackBook_1.69e.jar<br />
mld.jdc.nano.LittleBlackBook 1.0,http://www.robocoderepository.com/BotFiles/4295/mld.jdc.nano.LittleBlackBook_1.0.jar<br />
mld.Moebius 2.9.3,http://www.robocoderepository.com/BotFiles/3634/mld.Moebius_2.9.3.jar<br />
mld.Wisdom 1.0,http://www.robocoderepository.com/BotFiles/3640/mld.Wisdom_1.0.jar<br />
mmb.Roskilde 0.5,http://www.robocoderepository.com/BotFiles/3965/mmb.Roskilde_0.5.jar<br />
mme.NikeEnhanced 2.0,http://www.robocoderepository.com/BotFiles/2828/mme.NikeEnhanced_2.0.jar<br />
mn.micro.perceptual.Mimic 1.0.0,http://dl.dropbox.com/s/3m8lbyarqc06tps/mn.micro.perceptual.Mimic_1.0.0.jar?dl=1<br />
mn.nano.perceptual.Impact 1.3.0,http://dl.dropbox.com/s/njuuaycr3qswlgu/mn.nano.perceptual.Impact_1.3.0.jar?dl=1<br />
mn.Combat 3.21.1,http://dl.dropboxusercontent.com/s/kpmfcyl7f8kdima/mn.Combat_3.21.1.jar<br />
mn.SuperSittingDuck 1.0.2,http://robocode-archive.strangeautomata.com/robots/mn.SuperSittingDuck_1.0.2.jar<br />
mnt.AHEB 0.6a,http://www.robocoderepository.com/BotFiles/2417/mnt.AHEB_0.6a.jar<br />
mnt.SurferBot 0.2.5,http://www.robocoderepository.com/BotFiles/2433/mnt.SurferBot_0.2.5.jar<br />
morbid.MorbidPriest 1.0,http://www.robocoderepository.com/BotFiles/1758/morbid.MorbidPriest_1.0.jar<br />
mrm.MightyMoose .2,http://robocode-archive.strangeautomata.com/robots/mrm.MightyMoose_.2.jar<br />
ms.Ares 0.19,http://www.robocoderepository.com/BotFiles/730/ms.Ares_0.19.jar<br />
mue.Ascendant 1.2.27,http://mue.sonar-echo.de/robocode/mue.Ascendant_1.2.27.jar<br />
mue.Hyperion 0.8,http://www.robocoderepository.com/BotFiles/2224/mue.Hyperion_0.8.jar<br />
muf.CrazyKitten 0.9,http://www.robocoderepository.com/BotFiles/1946/muf.CrazyKitten_0.9.jar<br />
mwj.A1176183 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/mwj.A1176183_1.0.jar<br />
myl.micro.Avipes 1.00,http://www.robocoderepository.com/BotFiles/1347/myl.micro.Avipes_1.00.jar<br />
myl.micro.NekoNinja 1.30,http://www.robocoderepository.com/BotFiles/944/myl.micro.NekoNinja_1.30.jar<br />
myl.micro.Predator 1.50,http://www.robocoderepository.com/BotFiles/1097/myl.micro.Predator_1.50.jar<br />
myl.micro.Troodon 1.10,http://www.robocoderepository.com/BotFiles/1226/myl.micro.Troodon_1.10.jar<br />
myl.nano.Graviton 1.10,http://www.robocoderepository.com/BotFiles/770/myl.nano.Graviton_1.10.jar<br />
myl.nano.Kakuru 1.20,http://www.robocoderepository.com/BotFiles/1330/myl.nano.Kakuru_1.20.jar<br />
myl.nano.KomoriNinja 1.1,http://www.robocoderepository.com/BotFiles/978/myl.nano.KomoriNinja_1.1.jar<br />
mym.EdgeStalker 1.0,http://www.robocoderepository.com/BotFiles/3956/mym.EdgeStalker_1.0.jar<br />
mz.Adept 2.65,http://www.robocoderepository.com/BotFiles/2090/mz.Adept_2.65.jar<br />
mz.AdeptBSB 1.03,http://www.robocoderepository.com/BotFiles/2113/mz.AdeptBSB_1.03.jar<br />
mz.Movement 1.8,http://www.robocoderepository.com/BotFiles/2145/mz.Movement_1.8.jar<br />
mz.NanoDeath 2.56,http://www.robocoderepository.com/BotFiles/2010/mz.NanoDeath_2.56.jar<br />
mz.NanoGod 2.02,http://www.robocoderepository.com/BotFiles/1996/mz.NanoGod_2.02.jar<br />
nammyung.ModelT 0.23,http://www.robocoderepository.com/BotFiles/969/nammyung.ModelT_0.23.jar<br />
nan.Ihivatar_Mk_1 1.0,http://dl.dropbox.com/s/4oxw831xuu9yui0/nan.Ihivatar_Mk_1_1.0.jar?dl=1<br />
nanoskank.NanoSkank 1.0,http://robocode-archive.strangeautomata.com/robots/nanoskank.NanoSkank_1.0.jar<br />
nat.BlackHole 2.0gamma,http://nat.robothai.net/robots/nat.BlackHole_2.0gamma.jar<br />
nat.Hikari dev0001,http://nat.robothai.net/robots/nat.Hikari_dev0001.jar<br />
nat.micro.Reepicheep 0.1a,http://nat.robothai.net/robots/nat.micro.Reepicheep_0.1a.jar<br />
nat.nano.Ocnirp 1.73,http://nat.robothai.net/robots/nat.nano.Ocnirp_1.73.jar<br />
nat.nano.OcnirpPM 1.0,http://nat.robothai.net/robots/nat.nano.OcnirpPM_1.0.jar<br />
nat.nano.OcnirpSNG 1.0b,http://nat.robothai.net/robots/nat.nano.OcnirpSNG_1.0b.jar<br />
nat.Samekh 0.4,http://nat.robothai.net/robots/nat.Samekh_0.4.jar<br />
ncj.MoxieBot 1.0,http://www.robocoderepository.com/BotFiles/4003/ncj.MoxieBot_1.0.jar<br />
ndn.DyslexicMonkey 1.1,http://www.robocoderepository.com/BotFiles/1141/ndn.DyslexicMonkey_1.1.jar<br />
NDH.GuessFactor 1.0, http://www.robocoderepository.com/BotFiles/3949/NDH.GuessFactor_1.0.jar<br />
ne.Chimera 1.2,http://www.robocoderepository.com/BotFiles/3276/ne.Chimera_1.2.jar<br />
nexus.One 1.0,http://robocode-archive.strangeautomata.com/robots/nexus.One_1.0.jar<br />
nexus.Prototype 1.0,http://robocode-archive.strangeautomata.com/robots/nexus.Prototype_1.0.jar<br />
nexus.Two 0.2,https://dl.dropbox.com/s/glol05xymwbb0a7/nexus.Two_0.2.jar<br />
nexus.Experimental 0.2,https://dl.dropbox.com/s/kxeorcrx6jwlm2e/nexus.Experimental_0.2.jar<br />
ngf.nano.Sparky 0.1.5,http://robocode-archive.strangeautomata.com/robots/ngf.nano.Sparky_0.1.5.jar<br />
nic.Nicator 2.4,http://www.robocoderepository.com/BotFiles/193/nic.Nicator_2.4.jar<br />
nic.SnippetBot 1.0,http://www.robocoderepository.com/BotFiles/286/nic.SnippetBot_1.0.jar<br />
nkn.mini.Jskr0 0.1,http://www.robocoderepository.com/BotFiles/3852/nkn.mini.Jskr0_0.1.jar<br />
NG.LegatusLegionis 1.2,http://www.robocoderepository.com/BotFiles/4026/NG.LegatusLegionis_1.2.jar<br />
non.mega.NaN 0.1,http://www.robocoderepository.com/BotFiles/1960/non.mega.NaN_0.1.jar<br />
non.mega.NoName 0.0,http://www.robocoderepository.com/BotFiles/1957/non.mega.NoName_0.0.jar<br />
Noran.BitchingElk 0.054,http://www.robocoderepository.com/BotFiles/1855/Noran.BitchingElk_0.054.jar<br />
Noran.RandomTargeting 0.02,http://www.robocoderepository.com/BotFiles/1849/Noran.RandomTargeting_0.02.jar<br />
nova.Snow 1.0,http://www.robocoderepository.com/BotFiles/3623/nova.Snow_1.0.jar<br />
ntc.Cannon 1.12test,http://www.robocoderepository.com/BotFiles/3815/ntc.Cannon_1.12test.jar<br />
ntc.Evader 1.2,http://www.robocoderepository.com/BotFiles/3355/ntc.Evader_1.2.jar<br />
ntc.Knowledge 1.1,http://www.robocoderepository.com/BotFiles/3354/ntc.Knowledge_1.1.jar<br />
ntc.Lasers.Lasers 0.9,http://www.robocoderepository.com/BotFiles/3359/ntc.Lasers.Lasers_0.9.jar<br />
ntc.Plains 0.9,http://www.robocoderepository.com/BotFiles/3381/ntc.Plains_0.9.jar<br />
ntc.Swim 0.9,http://www.robocoderepository.com/BotFiles/3820/ntc.Swim_0.9.jar<br />
ntw.Sighup 1.5,http://robocode-archive.strangeautomata.com/robots/ntw.Sighup_1.5.jar<br />
ntw.Sigsys 1.6,http://robocode-archive.strangeautomata.com/robots/ntw.Sigsys_1.6.jar<br />
nz.jdc.micro.HedgehogGF 1.5,http://www.robocoderepository.com/BotFiles/4291/nz.jdc.micro.HedgehogGF_1.5.jar<br />
nz.jdc.micro.HedgehogP 1.2,http://www.robocoderepository.com/BotFiles/3622/nz.jdc.micro.HedgehogP_1.2.jar<br />
nz.jdc.nano.AralT 1.1,http://www.robocoderepository.com/BotFiles/4269/nz.jdc.nano.AralT_1.1.jar<br />
nz.jdc.nano.AralR 1.1,http://www.robocoderepository.com/BotFiles/4268/nz.jdc.nano.AralR_1.1.jar<br />
nz.jdc.nano.NeophytePattern 1.1,http://www.robocoderepository.com/BotFiles/4244/nz.jdc.nano.NeophytePattern_1.1.jar<br />
nz.jdc.nano.NeophytePRAL 1.4,http://www.robocoderepository.com/BotFiles/4250/nz.jdc.nano.NeophytePRAL_1.4.jar<br />
nz.jdc.nano.NeophyteSRAL 1.3,http://www.robocoderepository.com/BotFiles/4246/nz.jdc.nano.NeophyteSRAL_1.3.jar<br />
nz.jdc.nano.PatternAdept 1.0,http://www.robocoderepository.com/BotFiles/4271/nz.jdc.nano.PatternAdept_1.0.jar<br />
nz.jdc.nano.PralDeGuerre 1.2,http://www.robocoderepository.com/BotFiles/4293/nz.jdc.nano.PralDeGuerre_1.2.jar<br />
nzeemin.Izh 0.5,http://nzeemin-opensrc.googlecode.com/files/nzeemin.Izh_0.5.jar<br />
oa.weak.BotherBot 0.1,http://www.robocoderepository.com/BotFiles/2956/oa.weak.BotherBot_0.1.jar<br />
oa.weak.FlyMk1 0.1,http://www.robocoderepository.com/BotFiles/2958/oa.weak.FlyMk1_0.1.jar<br />
ola.Puffin 1.0,http://www.robocoderepository.com/BotFiles/3380/ola.Puffin_1.0.jar<br />
omens.CannonfodderMicro 1.4,https://dl.dropbox.com/s/ye675r93lpgpuei/omens.CannonfodderMicro_1.4.jar<br />
omens.CannonfodderNano 1.4,https://dl.dropbox.com/s/u94wp86uo34feue/omens.CannonfodderNano_1.4.jar<br />
oog.melee.Capulet 1.2,https://sites.google.com/site/crazybassoon/oog.melee.Capulet_1.2.jar<br />
oog.melee.Mercutio 1.0,http://www.robocoderepository.com/BotFiles/3848/oog.melee.Mercutio_1.0.jar<br />
oog.micro.MagicD3 0.41,http://www.robocoderepository.com/BotFiles/3801/oog.micro.MagicD3_0.41.jar<br />
oog.micro.Maui 1.2,http://robocode-archive.strangeautomata.com/robots/oog.micro.Maui_1.2.jar<br />
oog.micro.SavantMicro 1.1,http://robocode-archive.strangeautomata.com/robots/oog.micro.SavantMicro_1.1.jar<br />
oog.mini.AlphaDragon 0.1,http://www.robocoderepository.com/BotFiles/4015/oog.mini.AlphaDragon_0.1.jar<br />
oog.nano.Caligula 1.15,http://www.robocoderepository.com/BotFiles/4022/oog.nano.Caligula_1.15.jar<br />
oog.nano.Fuatisha 1.1,http://www.robocoderepository.com/BotFiles/4045/oog.nano.Fuatisha_1.1.jar<br />
oog.nano.MagicD2 2.4,http://www.robocoderepository.com/BotFiles/3749/oog.nano.MagicD2_2.4.jar<br />
oog.nano.SavantVS 1.1,http://www.robocoderepository.com/BotFiles/3714/oog.nano.SavantVS_1.1.jar<br />
oog.nano.SavantWS 0.1,http://www.robocoderepository.com/BotFiles/3709/oog.nano.SavantWS_0.1.jar<br />
oog.PricklyPear 1.0.6,http://robocode-archive.strangeautomata.com/robots/oog.PricklyPear_1.0.6.jar<br />
ouroboros.Dragon 0.0.3,https://dl.dropboxusercontent.com/u/98946154/robocode/ouroboros.Dragon_0.0.3.jar<br />
pa.Improved 1.1,http://robocode-archive.strangeautomata.com/robots/pa.Improved_1.1.jar<br />
pa3k.Manta 1.20,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Manta_1.20.jar<br />
pa3k.Quark 1.02,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Quark_1.02.jar<br />
pa3k.Viper 5.03,https://dl.dropboxusercontent.com/u/21124688/robocode/pa3k.Viper_5.03.jar<br />
pac.ABC 2.1,https://dl.dropbox.com/u/5439044/Robocode/pac.ABC_2.1.jar<br />
pak.JakeTheTestingRobot .1b,http://www.robocoderepository.com/BotFiles/3373/pak.JakeTheTestingRobot_.1b.jar<br />
pak.Dargon 1.0b,http://www.robocoderepository.com/BotFiles/3388/pak.Dargon_1.0b.jar<br />
paket.MojRobot 1.0,https://dl.dropbox.com/s/faovho732zgpvq8/paket.MojRobot_1.0.jar?dl=1<br />
panzer.Panzer 0.2,http://www.robocoderepository.com/BotFiles/4008/panzer.Panzer_0.2.jar<br />
paolord.TheHulk 1.0,http://www.robocoderepository.com/BotFiles/3595/paolord.TheHulk_1.0.jar<br />
patson.PatsonTestBot 1.0,http://www.robocoderepository.com/BotFiles/3324/patson.PatsonTestBot_1.0.jar<br />
paulk.PaulV3 1.7,http://www.robocoderepository.com/BotFiles/3502/paulk.PaulV3_1.7.jar<br />
pb.Oscillator 1.0,http://www.robocoderepository.com/BotFiles/2070/pb.Oscillator_1.0.jar<br />
pe.mini.SandboxMini 1.2,http://www.robocoderepository.com/BotFiles/917/pe.mini.SandboxMini_1.2.jar<br />
pe.minimelee.SandboxMiniMelee 1.1,http://www.robocoderepository.com/BotFiles/934/pe.minimelee.SandboxMiniMelee_1.1.jar<br />
pe.SandboxDT 3.02,http://www.robocoderepository.com/BotFiles/793/pe.SandboxDT_3.02.jar<br />
pe.SandboxLump 1.52,http://www.robocoderepository.com/BotFiles/731/pe.SandboxLump_1.52.jar<br />
pedersen.Hubris 2.4,http://home.comcast.net/~kokyunage/robocode/hubris/pedersen.Hubris_2.4.jar<br />
pedersen.Ugluk 1.0,http://home.comcast.net/~kokyunage/robocode/ugluk/pedersen.Ugluk_1.0.jar<br />
pez.clean.Swiffer 0.2.9,http://www.robocoderepository.com/BotFiles/1883/pez.clean.Swiffer_0.2.9.jar<br />
pez.frankie.Frankie 0.9.6.1,http://www.robocoderepository.com/BotFiles/1565/pez.frankie.Frankie_0.9.6.1.jar<br />
pez.gloom.GloomyDark 0.9.2,http://www.robocoderepository.com/BotFiles/1741/pez.gloom.GloomyDark_0.9.2.jar<br />
pez.mako.Mako 1.5,http://www.robocoderepository.com/BotFiles/1317/pez.mako.Mako_1.5.jar<br />
pez.micro.Aristocles 0.3.7,http://www.robocoderepository.com/BotFiles/1923/pez.micro.Aristocles_0.3.7.jar<br />
pez.mini.ChironexFleckeri 0.5,http://www.robocoderepository.com/BotFiles/2513/pez.mini.ChironexFleckeri_0.5.jar<br />
pez.mini.Gouldingi 1.5,http://www.robocoderepository.com/BotFiles/1351/pez.mini.Gouldingi_1.5.jar<br />
pez.mini.Pugilist 2.5.1f,https://dl.dropboxusercontent.com/u/3259215/robocode/bots/pez.mini.Pugilist_2.5.1f.jar<br />
pez.mini.Tityus 0.9.1,http://www.robocoderepository.com/BotFiles/1657/pez.mini.Tityus_0.9.1.jar<br />
pez.mini.VertiLeach 0.4.0,http://www.robocoderepository.com/BotFiles/1744/pez.mini.VertiLeach_0.4.0.jar<br />
pez.nano.Icarus 0.3,http://www.robocoderepository.com/BotFiles/2353/pez.nano.Icarus_0.3.jar<br />
pez.nano.LittleEvilBrother 0.1,http://www.robocoderepository.com/BotFiles/2056/pez.nano.LittleEvilBrother_0.1.jar<br />
pez.rumble.Ali 0.4.9,http://www.robocoderepository.com/BotFiles/2416/pez.rumble.Ali_0.4.9.jar<br />
pez.rumble.CassiusClay 2rho.02no,https://dl.dropboxusercontent.com/u/3259215/robocode/bots/pez.rumble.CassiusClay_2rho.02no.jar<br />
pfvicm.Sobieski 7.2.3b,http://www.robocoderepository.com/BotFiles/2911/pfvicm.Sobieski_7.2.3b.jar<br />
ph.micro.Pikeman 0.4.5,http://www.robocoderepository.com/BotFiles/2364/ph.micro.Pikeman_0.4.5.jar<br />
ph.mini.Archer 0.6.6,http://www.robocoderepository.com/BotFiles/2326/ph.mini.Archer_0.6.6.jar<br />
ph.musketeer.Musketeer 0.6,http://www.robocoderepository.com/BotFiles/2281/ph.musketeer.Musketeer_0.6.jar<br />
ph.Thinker 0.2.5,http://www.robocoderepository.com/BotFiles/2336/ph.Thinker_0.2.5.jar<br />
pi.Dark 10,http://robocode-archive.strangeautomata.com/robots/pi.Dark_10.jar<br />
pl.Drum 0.1,http://robocode-archive.strangeautomata.com/robots/pl.Drum_0.1.jar<br />
pl.mskiba.Hilton 0.4,https://dl.dropbox.com/u/1209595/robots/pl.mskiba.Hilton_0.4.jar<br />
pl.Patton.GeneralPatton 1.54,http://robocode-archive.strangeautomata.com/robots/pl.Patton.GeneralPatton_1.54.jar<br />
pla.Memnoch 0.5,http://www.robocoderepository.com/BotFiles/2211/pla.Memnoch_0.5.jar<br />
PK.Twardy 0.4.2,http://www.robocoderepository.com/BotFiles/3272/PK.Twardy_0.4.2.jar<br />
pkbots.BoyTDSurfer 1.0,http://robocode-archive.strangeautomata.com/robots/pkbots.BoyTDSurfer_1.0.jar<br />
pkdeken.Paladin 1.0,http://www.robocoderepository.com/BotFiles/3556/pkdeken.Paladin_1.0.jar<br />
PkKillers.PkAssassin 1.0,http://www.robocoderepository.com/BotFiles/3485/PkKillers.PkAssassin_1.0.jar<br />
pmc.SniperBot 1.0,http://robocode-archive.strangeautomata.com/robots/pmc.SniperBot_1.0.jar<br />
Polkwane.Piyane 0.7b,https://dl.dropbox.com/s/mztcvf13ab41or5/Polkwane.Piyane_0.7b.jar?token_hash=AAH-IVvOaiKm2CWOaEKosx9APzGrfMWF-jpbOJaY_bFnow&dl=1<br />
Polkwane.Intensive 1.0,http://robowiki.net/w/images/1/1d/Polkwane.Intensive_1.0.jar<br />
populations.TrainStoopidbot 0.01,http://www.robocoderepository.com/BotFiles/4052/populations.TrainStoopidbot_0.01.jar<br />
positive.Portia 1.26e,http://robocode-archive.strangeautomata.com/robots/positive.Portia_1.26e.jar<br />
povik.nano.Smilee 0.2.1,http://www.robocoderepository.com/BotFiles/3950/povik.nano.Smilee_0.2.1.jar<br />
projectx.ProjectNano 2.0,http://robocode-archive.strangeautomata.com/robots/projectx.ProjectNano_2.0.jar<br />
projectx.TestNano 1.0,http://www.robocoderepository.com/BotFiles/3444/projectx.TestNano_1.0.jar<br />
PSW.Relentless 0.1,http://www.robocoderepository.com/BotFiles/4082/PSW.Relentless_0.1.jar<br />
pulsar.PulsarMax 0.8.9,http://www.robocoderepository.com/BotFiles/2227/pulsar.PulsarMax_0.8.9.jar<br />
pulsar.PulsarNano 0.2.4,http://www.robocoderepository.com/BotFiles/2335/pulsar.PulsarNano_0.2.4.jar<br />
pulsar.Nanis 0.3,http://www.robocoderepository.com/BotFiles/2560/pulsar.Nanis_0.3.jar<br />
qohnil.blot.BlotBot 3.61,http://www.robocoderepository.com/BotFiles/546/qohnil.blot.BlotBot_3.61.jar<br />
qualidafial.MajorDick 1.0.1,http://dl.dropboxusercontent.com/sh/n570kf8rsq6fuw2/vVQSIJJnAS/qualidafial.MajorDick_1.0.1.jar<br />
Queens_teamrobot.UltraRazor 1.0,http://www.robocoderepository.com/BotFiles/2108/Queens_teamrobot.UltraRazor_1.0.jar<br />
quietus.Invader 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/quietus.Invader_0.1.jar<br />
quietus.NarrowRadar 0.1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/quietus.NarrowRadar_0.1.jar<br />
qwaker00.Gandhi 1.0.1mini,https://dl.dropbox.com/u/29826809/bots/qwaker00.Gandhi_1.0.1mini.jar<br />
qwaker00.Ahchoo 1.1.j6,https://dl.dropbox.com/u/29826809/bots/qwaker00.Ahchoo_1.1.j6.jar<br />
racso.Crono 1.0,http://oscargomez.net/files/racso.Crono_1.0.jar<br />
racso.Frog 0.9,http://oscargomez.net/files/racso.Frog_0.9.jar<br />
radnor.DoctorBob 1.42,http://www.robocoderepository.com/BotFiles/2133/radnor.DoctorBob_1.42.jar<br />
radnor.RamRod 1.0,http://www.robocoderepository.com/BotFiles/2085/radnor.RamRod_1.0.jar<br />
rampancy.Durandal 2.2d,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/rampancy.Durandal_2.2d.jar<br />
rampancy.micro.Epiphron 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/rampancy.micro.Epiphron_1.0.jar<br />
rapture.Rapture 2.13,http://www.robocoderepository.com/BotFiles/15/rapture.Rapture_2.13.jar<br />
ratosh.nano.Debo 1.36,http://www.robocoderepository.com/BotFiles/1702/ratosh.nano.Debo_1.36.jar<br />
ratosh.Nobo 0.21,http://www.robocoderepository.com/BotFiles/1612/ratosh.Nobo_0.21.jar<br />
ratosh.Wesco 1.4,http://www.robocoderepository.com/BotFiles/1914/ratosh.Wesco_1.4.jar<br />
rc.yoda.Yoda 1.0.6c.fix,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/rc.yoda.Yoda_1.0.6c.fix.jar<br />
rc.RCBot 2.0,http://robocode-archive.strangeautomata.com/robots/rc.RCBot_2.0.jar<br />
rcb.Vanessa03 0,http://www.robocoderepository.com/BotFiles/1364/rcb.Vanessa03_0.jar<br />
rcp.Kuramatron 1.0,http://www.robocoderepository.com/BotFiles/3307/rcp.Kuramatron_1.0.jar<br />
rdt199.Warlord 0.73,http://www.robocoderepository.com/BotFiles/1130/rdt199.Warlord_0.73.jar<br />
reaper.Reaper 1.1,http://www.robocoderepository.com/BotFiles/3412/reaper.Reaper_1.1.jar<br />
reeder.caden.Elmo 1,http://reederhome.net/colin/Elmo_1.jar<br />
reeder.caden.Grover 1.0,http://reederhome.net/colin/Grover_1.0.jar<br />
reeder.colin.WallGuy3 1.0,http://reederhome.net/colin/WallGuy3_1.0.jar<br />
repositorio.NanoStep 1.0,http://robocode-archive.strangeautomata.com/robots/repositorio.NanoStep_1.0.jar<br />
rfj.Sunburn 1.1,http://www.robocoderepository.com/BotFiles/1060/rfj.Sunburn_1.1.jar<br />
rijteam.SmartDodge 1.1,http://www.robocoderepository.com/BotFiles/2959/rijteam.SmartDodge_1.1.jar<br />
rjw.RabidWombat 0.71,http://rjw.walkertribe.com/robocode/rjw.RabidWombat_0.71.jar<br />
rnatest.MendelBot 1.0,http://dl.dropboxusercontent.com/s/ci2x5gxbtceo4r2/rnatest.MendelBot_1.0.jar<br />
robar.haiku.Spike 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.haiku.Spike_1.0.jar<br />
robar.micro.Gladius 1.15,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.micro.Gladius_1.15.jar<br />
robar.micro.Kirbyi 1.0,http://hunrobar.freeblog.hu/files/myrobots/robar.micro.Kirbyi_1.0.jar<br />
robar.micro.Topaz 0.25,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.micro.Topaz_0.25.jar<br />
robar.nano.Assertive 0.3,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/robar.nano.Assertive_0.3.jar<br />
robar.nano.BlackWidow 1.3,http://www.robocoderepository.com/BotFiles/3574/robar.nano.BlackWidow_1.3.jar<br />
robar.nano.Breeze 0.3,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Breeze_0.3.jar<br />
robar.nano.Mosquito 1.1,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Mosquito_1.1.jar<br />
robar.nano.MosquitoPM 1.0,http://www.robocoderepository.com/BotFiles/3559/robar.nano.MosquitoPM_1.0.jar<br />
robar.nano.Prestige 1.0,http://www.robocoderepository.com/BotFiles/3507/robar.nano.Prestige_1.0.jar<br />
robar.nano.Pugio 1.49,http://www.robocoderepository.com/BotFiles/3710/robar.nano.Pugio_1.49.jar<br />
robar.nano.Scytodes 0.3,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Scytodes_0.3.jar<br />
robar.nano.Vespa 0.95,http://hunrobar.freeblog.hu/files/myrobots/robar.nano.Vespa_0.95.jar<br />
robin.SCALPHC 1.0,http://www.fairyapp.com.au/robin.SCALPHC_1.0.jar<br />
robin.SCALPBot 1.0,http://www.fairyapp.com.au/robin.SCALPBot_1.0.jar<br />
robin.SCALPBotB 1.1,http://www.fairyapp.com.au/robin.SCALPBotB_1.1.jar<br />
robin.SCALPWHC 1.1,http://www.fairyapp.com.au/robin.SCALPWHC_1.1.jar<br />
robo.PartsBot 1.1,http://robocode-archive.strangeautomata.com/robots/robo.PartsBot_1.1.jar<br />
RobotMarco.MarcoV 0.1,http://www.robocoderepository.com/BotFiles/3941/RobotMarco.MarcoV_0.1.jar<br />
romz.robot.circular.WildRabbit 0.9.6, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.circular.WildRabbit_0.9.6.jar<br />
romz.robot.guessfactor.TeasingFox 0.2, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.guessfactor.TeasingFox_0.2.jar<br />
romz.robot.Test 0.1.0, https://dl.dropboxusercontent.com/u/19698591/robocode/romz.robot.Test_0.1.0.jar<br />
rsim.micro.uCatcher 0.1,http://robocode-archive.strangeautomata.com/robots/rsim.micro.uCatcher_0.1.jar<br />
rsim.mini.BulletCatcher 0.4,http://www.robocoderepository.com/BotFiles/3737/rsim.mini.BulletCatcher_0.4.jar<br />
rsk1.RSK1 4.0,http://www.robocoderepository.com/BotFiles/3284/rsk1.RSK1_4.0.jar<br />
rtk.Tachikoma 1.0,http://www.robocoderepository.com/BotFiles/4121/rtk.Tachikoma1.0.jar<br />
ruc.nano.Zealot 0.2,http://www.robocoderepository.com/BotFiles/1229/ruc.nano.Zealot_0.2.jar<br />
rus.vv.Dzhigit 1.1,http://www.robocoderepository.com/BotFiles/4002/rus.vv.Dzhigit1.1.jar<br />
rus.vv.Snezhok 1.1,http://www.robocoderepository.com/BotFiles/3998/rus.vv.Snezhok1.1.jar<br />
ry.LightningBug 1.0,http://www.robocoderepository.com/BotFiles/3472/ry.LightningBug_1.0.jar<br />
ry.VirtualGunExperiment 1.2.0,http://www.robocoderepository.com/BotFiles/3662/ry.VirtualGunExperiment_1.2.0.jar<br />
ry.Worst 1.0,http://www.robocoderepository.com/BotFiles/3645/ry.Worst_1.0.jar<br />
rz.Aleph 0.34,http://www.robocoderepository.com/BotFiles/1993/rz.Aleph_0.34.jar<br />
rz.Apollon 0.23,http://www.robocoderepository.com/BotFiles/2098/rz.Apollon_0.23.jar<br />
rz.Artist 0.2,http://www.robocoderepository.com/BotFiles/2156/rz.Artist_0.2.jar<br />
rz.GlowBlow 2.31,http://www.robocoderepository.com/BotFiles/1354/rz.GlowBlow_2.31.jar<br />
rz.GlowBlowAPM 1.0,http://www.robocoderepository.com/BotFiles/1382/rz.GlowBlowAPM_1.0.jar<br />
rz.GlowBlowMelee 1.4,http://www.robocoderepository.com/BotFiles/1436/rz.GlowBlowMelee_1.4.jar<br />
rz.HawkOnFire 0.1,http://www.robocoderepository.com/BotFiles/1575/rz.HawkOnFire_0.1.jar<br />
rz.SmallDevil 1.502,http://www.robocoderepository.com/BotFiles/1322/rz.SmallDevil_1.502.jar<br />
sadoner.killer 0.2,http://www.robocoderepository.com/BotFiles/4020/sadoner.killer_0.2.jar<br />
sam.ChipmunkDuelist 1.0,http://www.robocoderepository.com/BotFiles/3094/sam.ChipmunkDuelist_1.0.jar<br />
sam.Samspin 1.0,http://www.robocoderepository.com/BotFiles/2823/sam.Samspin_1.0.jar<br />
sample.Corners 1.0,http://www.robocoderepository.com/BotFiles/1/sample.Corners_1.0.jar<br />
sample.Crazy 1.0,http://www.robocoderepository.com/BotFiles/2/sample.Crazy_1.0.jar<br />
sample.Fire 1.0,http://www.robocoderepository.com/BotFiles/3/sample.Fire_1.0.jar<br />
sample.MyFirstJuniorRobot 1.0,http://robocode-archive.strangeautomata.com//robots/sample.MyFirstJuniorRobot_1.0.jar<br />
sample.MyFirstRobot 1.0,http://www.robocoderepository.com/BotFiles/4/sample.MyFirstRobot_1.0.jar<br />
sample.RamFire 1.0,http://www.robocoderepository.com/BotFiles/5/sample.RamFire_1.0.jar<br />
sample.SittingDuck 1.0,http://www.robocoderepository.com/BotFiles/6/sample.SittingDuck_1.0.jar<br />
sample.SpinBot 1.0,http://www.robocoderepository.com/BotFiles/7/sample.SpinBot_1.0.jar<br />
sample.Target 1.0,http://www.robocoderepository.com/BotFiles/8/sample.Target_1.0.jar<br />
sample.Tracker 1.0,http://www.robocoderepository.com/BotFiles/9/sample.Tracker_1.0.jar<br />
sample.TrackFire 1.0,http://www.robocoderepository.com/BotFiles/10/sample.TrackFire_1.0.jar<br />
sample.VelociRobot 1.0,http://robocode-archive.strangeautomata.com//robots/sample.VelociRobot_1.0.jar<br />
sample.Walls 1.0,http://www.robocoderepository.com/BotFiles/11/sample.Walls_1.0.jar<br />
satan.R0 0.2,http://satan.so/robocode/satan.R0_0.2.jar<br />
satan.White 0.26,http://satan.so/robocode/satan.White_0.26.jar<br />
sanyi.mikrobi.Roberto 1.0,http://www.robocoderepository.com/BotFiles/3929/sanyi.mikrobi.Roberto_1.0.jar<br />
sch.Simone 0.3d,http://www.robocoderepository.com/BotFiles/374/sch.Simone_0.3d.jar<br />
serenity.moonlightBat 1.17,http://www.robocoderepository.com/BotFiles/2877/serenity.moonlightBat_1.17.jar<br />
serenity.nonSense 1.39,http://www.robocoderepository.com/BotFiles/3586/serenity.nonSense_1.39.jar<br />
serenity.serenityFire 1.29,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/serenity.serenityFire_1.29.jar<br />
SFS.SamsSecondRobot 1.0,http://www.robocoderepository.com/BotFiles/4148/SFS.SamsSecondRobot_1.0.jar<br />
sgp.JollyNinja 3.53,http://www.robocoderepository.com/BotFiles/183/sgp.JollyNinja_3.53.jar<br />
sgp.MadHatter 4.13,http://www.robocoderepository.com/BotFiles/156/sgp.MadHatter_4.13.jar<br />
sgp.nano.FurryLeech 1.0,http://www.robocoderepository.com/BotFiles/802/sgp.nano.FurryLeech_1.0.jar<br />
sgp.ShiningBeetle 1.1,http://www.robocoderepository.com/BotFiles/498/sgp.ShiningBeetle_1.1.jar<br />
sgp.SleepingGoat 1.1,http://www.robocoderepository.com/BotFiles/500/sgp.SleepingGoat_1.1.jar<br />
SHAM.WOW 1.4,http://robocode-archive.strangeautomata.com/robots/SHAM.WOW_1.4.jar<br />
sheldor.melee.nano.TestMelee 0.1,http://www.robocoderepository.com/BotFiles/4217/sheldor.melee.nano.TestMelee_0.1.jar<br />
sheldor.micro.EpeeistMicro 2.0.0,http://www.robocoderepository.com/BotFiles/4292/sheldor.micro.EpeeistMicro_2.0.0.jar<br />
sheldor.nano.Epeeist 1.1.0,http://www.robocoderepository.com/BotFiles/4237/sheldor.nano.Epeeist_1.1.0.jar<br />
sheldor.nano.Foilist 2.0.0,http://www.robocoderepository.com/BotFiles/4239/sheldor.nano.Foilist_2.0.0.jar<br />
sheldor.nano.PointInLine 1.0,http://www.robocoderepository.com/BotFiles/4207/sheldor.nano.PointInLine_1.0.jar<br />
sheldor.nano.PointInLineRRAL 1.0.0,http://www.robocoderepository.com/BotFiles/4259/sheldor.nano.PointInLineRRAL_1.0.0.jar<br />
sheldor.nano.Retreat 1.0,http://www.robocoderepository.com/BotFiles/4208/sheldor.nano.Retreat_1.0.jar<br />
sheldor.nano.Sabreur 1.1.2,http://www.robocoderepository.com/BotFiles/4257/sheldor.nano.Sabreur_1.1.2.jar<br />
sheldor.nano.Sabreuse 1.0.0,http://www.robocoderepository.com/BotFiles/4258/sheldor.nano.Sabreuse_1.0.0.jar<br />
shinh.Entangled 0.3,http://www.robocoderepository.com/BotFiles/1070/shinh.Entangled_0.3.jar<br />
shrub.Silver v048,http://www.robocoderepository.com/BotFiles/449/shrub.Silver_v048.jar<br />
shrub.Vapour v159,http://www.robocoderepository.com/BotFiles/2654/shrub.Vapour_v159.jar<br />
shu.nitro.LENIN .T34,http://www.robocoderepository.com/BotFiles/1956/shu.nitro.LENIN_.T34.jar<br />
sigterm.Sigterm 1.0,http://robocode-archive.strangeautomata.com/robots/sigterm.Sigterm_1.0.jar<br />
simonton.beta.LifelongObsession 0.5.1,http://www.robocoderepository.com/BotFiles/3195/simonton.beta.LifelongObsession_0.5.1.jar<br />
simonton.GFNano_D 3.1b,http://www.robocoderepository.com/BotFiles/3114/simonton.GFNano_D_3.1b.jar<br />
simonton.nano.WeekendObsession_S 1.7,http://www.robocoderepository.com/BotFiles/3117/simonton.nano.WeekendObsession_S_1.7.jar<br />
simonton.mega.SniperFrog 1.0.fix2,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/simonton.mega.SniperFrog_1.0.fix2.jar<br />
simonton.micro.GFMicro 1.0,http://robocode-archive.strangeautomata.com/robots/simonton.micro.GFMicro_1.0.jar<br />
simonton.micro.WeeklongObsession 3.4.1,http://robocode-archive.strangeautomata.com/robots/simonton.micro.WeeklongObsession_3.4.1.jar<br />
simonton.mini.WeeksOnEnd 1.10.4,http://robocode-archive.strangeautomata.com/robots/simonton.mini.WeeksOnEnd_1.10.4.jar<br />
SK.SimpleKiller 1.0,http://www.robocoderepository.com/BotFiles/4129/SK.SimpleKiller_1.0.jar<br />
skm.butterfly 1.0,http://www.robocoderepository.com/BotFiles/3868/sean1.jar<br />
skm.Ryubot 1.0,http://www.robocoderepository.com/BotFiles/3594/skm.Ryubot_1.0.jar<br />
skm.PateranBotlock2 1.0,http://www.robocoderepository.com/BotFiles/3591/skm.PateranBotlock2_1.0.jar<br />
sL300.Mozart life,http://www.robocoderepository.com/BotFiles/1992/sL300.Mozart_life.jar<br />
sm.Devil 7.3,http://www.robocoderepository.com/BotFiles/1481/sm.Devil_7.3.jar<br />
sng.arco.Arco 0.0,http://www.robocoderepository.com/BotFiles/3279/sng.arco.Arco_0.0.jar<br />
sos.SOS 1.0,http://www.robocoderepository.com/BotFiles/3489/sos.SOS_1.0.jar<br />
spartancompany.Spartan2 1.0,http://robocode-archive.strangeautomata.com/robots/spartancompany.Spartan2_1.0.jar<br />
spin.Bugstard 0.012b,https://dl.dropbox.com/s/jvm89xy5z5911ws/spin.Bugstard_0.012b.jar?dl=1<br />
spinnercat.CopyKat 1.2.3,http://www.robocoderepository.com/BotFiles/3818/spinnercat.CopyKat_1.2.3.jar<br />
spinnercat.Limit .01,http://www.robocoderepository.com/BotFiles/3659/spinnercat.Limit_.01.jar<br />
spinnercat.Kitten 1.6,http://www.robocoderepository.com/BotFiles/3819/spinnercat.Kitten_1.6.jar<br />
spinnercat.haiku.Refrigerator 1.1,http://www.robocoderepository.com/BotFiles/3688/spinnercat.haiku.Refrigerator_1.1.jar<br />
spinnercat.mega.Tardis 1.2,http://www.robocoderepository.com/BotFiles/3692/spinnercat.mega.Tardis_1.2.jar<br />
spinnercat.Robovirus 2.718,http://www.robocoderepository.com/BotFiles/3657/spinnercat.Robovirus_2.718.jar<br />
sp.Megas.AGravitatorExcel 1.4,http://www.robocoderepository.com/BotFiles/4153/sp.Megas.AGravitatorExcel_1.4.jar<br />
sp.Minis.Survival 1.0,http://robocode-archive.strangeautomata.com/robots/sp.Minis.Survival_1.0.jar?attredirects=0&d=1<br />
sp.Megas.Trident 2.7,http://robocode-archive.strangeautomata.com/robots/sp.Megas.Trident_2.7.jar?attredirects=0&d=1<br />
sp.Micros.WallAvoider 1.0,http://robocode-archive.strangeautomata.com/robots/sp.Micros.WallAvoider_1.0.jar?attredirects=0&d=1<br />
sp.Minis.LNightHawk 1.2,http://www.robocoderepository.com/BotFiles/4166/sp.Minis.LNightHawk_1.2.jar<br />
sp.Nanos.CopyMachine 1.0,http://www.robocoderepository.com/BotFiles/4172/sp.Nanos.CopyMachine_1.0.jar<br />
sqTank.waveSurfing.LionWWSVMvoid 0.01,http://www.robocoderepository.com/BotFiles/3436/sqTank.waveSurfing.LionWWSVMvoid_0.01.jar<br />
squidM.SquidmanNano 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/squidM.SquidmanNano_1.0.jar<br />
squidM.SurfinUSA 1.0,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/squidM.SurfinUSA_1.0.jar<br />
starpkg.StarViewerZ 1.26,http://www.robocoderepository.com/BotFiles/1931/starpkg.StarViewerZ_1.26.jar<br />
staticline.whiskey.Whiskey 0.6,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/staticline.whiskey.Whiskey_0.6.jar<br />
stefw.Tigger 0.0.23,http://robocode-archive.strangeautomata.com/robots/stefw.Tigger_0.0.23.jar<br />
stelo.Chord 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.Chord_1.0.jar<br />
stelo.FretNano 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.FretNano_1.1.jar<br />
stelo.Lifestealer 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.Lifestealer_1.0.jar<br />
stelo.MatchupMini 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupMini_1.1.jar<br />
stelo.MatchupMicro 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupMicro_1.2.jar<br />
stelo.MatchupAGF 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupAGF_1.1.jar<br />
stelo.MatchupWS 1.2c,http://robocode-archive.strangeautomata.com/robots/stelo.MatchupWS_1.2c.jar<br />
stelo.Mirror 1.1,http://www.robocoderepository.com/BotFiles/3034/stelo.Mirror_1.1.jar<br />
stelo.MirrorMicro 1.1,http://robocode-archive.strangeautomata.com/robots/stelo.MirrorMicro_1.1.jar<br />
stelo.MirrorNano 1.4,http://robocode-archive.strangeautomata.com/robots/stelo.MirrorNano_1.4.jar<br />
stelo.MoojukNano 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.MoojukNano_1.2.jar<br />
stelo.PastFuture 2.1.9,http://www.robocoderepository.com/BotFiles/3910/stelo.PastFuture_2.1.9.jar<br />
stelo.PatternRobot 1.0,http://www.robocoderepository.com/BotFiles/2995/stelo.PatternRobot_1.0.jar<br />
stelo.PianistNano 1.3,http://robocode-archive.strangeautomata.com/robots/stelo.PianistNano_1.3.jar<br />
stelo.RamTrackSurfer 1.2,http://robocode-archive.strangeautomata.com/robots/stelo.RamTrackSurfer_1.2.jar<br />
stelo.Randomness 1.1,http://www.robocoderepository.com/BotFiles/3021/stelo.Randomness_1.1.jar<br />
stelo.Spread 0.3,http://www.robowiki.net/w/images/a/a5/Stelo.Spread_0.3.jar<br />
stelo.SteloTestNano 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.SteloTestNano_1.0.jar<br />
stelo.UnfoolableNano 1.0,http://robocode-archive.strangeautomata.com/robots/stelo.UnfoolableNano_1.0.jar<br />
stelo.UntouchableNano 1.4,http://robocode-archive.strangeautomata.com/robots/stelo.UntouchableNano_1.4.jar<br />
step.nanoPri 1.0,http://www.robocoderepository.com/BotFiles/2996/step.nanoPri_1.0.jar<br />
step.NanoBidu 1.0,http://www.robocoderepository.com/BotFiles/3014/step.NanoBidu_1.0.jar<br />
stf.PanzerGeneral 0.1,http://www.robocoderepository.com/BotFiles/2233/stf.PanzerGeneral_0.1.jar<br />
stordy.StordyBot 1.0,http://robocode-archive.strangeautomata.com/robots/stordy.StordyBot_1.0.jar<br />
strider.Festis 1.2.1,http://www.robocoderepository.com/BotFiles/2355/strider.Festis_1.2.1.jar<br />
strider.Mer 1.1.0,http://www.robocoderepository.com/BotFiles/2360/strider.Mer_1.1.0.jar<br />
stuff.Vlad 0.1,http://www.robocoderepository.com/BotFiles/3701/stuff.Vlad_0.1.jar<br />
suh.mega.WaveSurferGF 1.04,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.mega.WaveSurferGF_1.04.jar<br />
suh.mega.WaveSurferPG 1.06,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.mega.WaveSurferPG_1.06.jar<br />
suh.micro.MirrorPM 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.micro.MirrorPM_1.00.jar<br />
suh.micro.WallPM 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.micro.WallPM_1.00.jar<br />
suh.nano.AngularMirrorC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.AngularMirrorC_1.00.jar<br />
suh.nano.AntiGravityL 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.AntiGravityL_1.01.jar<br />
suh.nano.CornerRL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CornerRL_1.00.jar<br />
suh.nano.CrossC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossC_1.00.jar<br />
suh.nano.CrossH 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossH_1.00.jar<br />
suh.nano.CrossL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.CrossL_1.00.jar<br />
suh.nano.MirrorH 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MirrorH_1.01.jar<br />
suh.nano.MirrorL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MirrorL_1.00.jar<br />
suh.nano.MyFirstAdvancedRobot 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.MyFirstAdvancedRobot_1.00.jar<br />
suh.nano.OscillatorL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.OscillatorL_1.00.jar<br />
suh.nano.RammingC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.RammingC_1.00.jar<br />
suh.nano.RandomPM 1.02,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.RandomPM_1.02.jar<br />
suh.nano.StopAndGoL 1.01,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.StopAndGoL_1.01.jar<br />
suh.nano.TargetC 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetC_1.00.jar<br />
suh.nano.TargetH 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetH_1.00.jar<br />
suh.nano.TargetL 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetL_1.00.jar<br />
suh.nano.TargetR 1.00,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.TargetR_1.00.jar<br />
suh.nano.Worst 1.02,https://dl.dropboxusercontent.com/u/200722583/Robocode/suh.nano.Worst_1.02.jar<br />
sul.NanoR2 1.32,http://www.robocoderepository.com/BotFiles/3348/sul.NanoR2_1.32.jar<br />
sul.Pinkbot 1.1,http://www.robocoderepository.com/BotFiles/3346/sul.Pinkbot_1.1.jar<br />
sul.Bicephal 1.2,http://www.robocoderepository.com/BotFiles/3343/sul.Bicephal_1.2.jar<br />
sul.BlueBot 1.0,http://www.robocoderepository.com/BotFiles/3347/sul.BlueBot_1.0.jar<br />
supersample.SuperBoxBot 1.0,http://www.robocoderepository.com/BotFiles/3994/supersample.SuperBoxBot_1.0.jar<br />
supersample.SuperCorners 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperCorners_1.0.jar<br />
SuperSample.SuperCrazy 1.0,http://robocode-archive.strangeautomata.com/robots/SuperSample.SuperCrazy_1.0.jar<br />
supersample.SuperMercutio 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperMercutio_1.0.jar<br />
supersample.SuperRamFire 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperRamFire_1.0.jar<br />
supersample.SuperSpinBot 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperSpinBot_1.0.jar<br />
supersample.SuperTracker 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperTracker_1.0.jar<br />
supersample.SuperTrackFire 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperTrackFire_1.0.jar<br />
supersample.SuperWalls 1.0,http://robocode-archive.strangeautomata.com//robots/supersample.SuperWalls_1.0.jar<br />
syl.Centipede 0.5,http://www.robocoderepository.com/BotFiles/1254/syl.Centipede_0.5.jar<br />
synapse.Geomancy 15,http://robocode-archive.strangeautomata.com/robots/synapse.Geomancy_15.jar<br />
synapse.rsim.GeomancyBS 0.11,http://robocode-archive.strangeautomata.com/robots/synapse.rsim.GeomancyBS_0.11.jar<br />
synnalagma.NeuralPremier 0.51,http://www.robocoderepository.com/BotFiles/1557/synnalagma.NeuralPremier_0.51.jar<br />
synnalagma.test.MiniNeural 1.1,http://www.robocoderepository.com/BotFiles/1754/synnalagma.test.MiniNeural_1.1.jar<br />
tad.Dalek98 0.98,http://robocode-archive.strangeautomata.com/robots/tad.Dalek98_0.98.jar<br />
takeBot.SpinSpiral 1.2,http://www.robocoderepository.com/BotFiles/312/takeBot.SpinSpiral_1.2.jar<br />
takeBot.SpiralCrash 1.0,http://www.robocoderepository.com/BotFiles/1013/takeBot.SpiralCrash_1.0.jar<br />
takeBot.WeavingWiggle 1.1,http://www.robocoderepository.com/BotFiles/1012/takeBot.WeavingWiggle_1.1.jar<br />
tango.Recrimpo 2.51,http://www.robocoderepository.com/BotFiles/2015/tango.Recrimpo_2.51.jar<br />
taqho.taqbot 1.0,http://www.robocoderepository.com/BotFiles/1316/taqho.taqbot_1.0.jar<br />
tcf.Drifter 29,http://www.7sun.com/robocode/robots/tcf.Drifter_29.jar<br />
tcf.Repat3 2,http://www.robocoderepository.com/BotFiles/3328/tcf.Repat3_2.jar<br />
TCMI.Enyo 0.4,http://www.timthegeek.com/other/robocode/TCMI.Enyo_0.4.jar<br />
TCMI.nano.Copper 0.2,http://www.timthegeek.com/other/robocode/TCMI.nano.Copper_0.2.jar<br />
techdude.kombat.FlamingKombat 1.5,http://www.robocoderepository.com/BotFiles/2810/techdude.kombat.FlamingKombat_1.5.jar<br />
techdude.Class2C.Class2C 0.1,http://www.robocoderepository.com/BotFiles/3078/techdude.Class2C.Class2C_0.1.jar<br />
test.Podgy 4.0,http://www.robocoderepository.com/BotFiles/3214/test.Podgy_4.0.jar<br />
test.Fuzzer 1.0.1,http://www.robocoderepository.com/BotFiles/3345/test.Fuzzer_1.0.1.jar<br />
tex.Longbot 0.4,https://sites.google.com/a/pelt.cc/pelt/home/my-roborcode-project/tex.Longbot_0.4.jar?attredirects=0&d=1<br />
testantiswapgun.AntiSwap 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/testantiswapgun.AntiSwap_1.0.jar<br />
throxbot.ThroxBot 0.1,http://www.robocoderepository.com/BotFiles/2548/throxbot.ThroxBot_0.1.jar<br />
tide.pear.Pear 0.62.1,http://www.robocoderepository.com/BotFiles/2393/tide.pear.Pear_0.62.1.jar<br />
timmit.micro.TimXJ 0.22,http://www.robocoderepository.com/BotFiles/1683/timmit.micro.TimXJ_0.22.jar<br />
timmit.mini.TimVA 0.43,http://www.robocoderepository.com/BotFiles/1681/timmit.mini.TimVA_0.43.jar<br />
timmit.nano.TimCat 0.13,http://www.robocoderepository.com/BotFiles/1600/timmit.nano.TimCat_0.13.jar<br />
timmit.nano.TimDog 0.33,http://www.robocoderepository.com/BotFiles/1602/timmit.nano.TimDog_0.33.jar<br />
timmit.TimmiT 0.22,http://www.robocoderepository.com/BotFiles/1468/timmit.TimmiT_0.22.jar<br />
TJ.Exupery 1.39,http://www.robocoderepository.com/BotFiles/3970/TJ.Exupery1.39.jar<br />
tjk.AFlatNatural 1.0,https://dl.dropboxusercontent.com/u/75978227/tjk.AFlatNatural_1.0.jar<br />
tjk.deBroglie rev0108,https://dl.dropboxusercontent.com/u/75978227/tjk.deBroglie_rev0108.jar<br />
tkt.RedShift 1.1.CS.0,https://github.com/ttaomae/robocode-tkt-redshift/raw/codesize/release/tkt.RedShift_1.1.CS.0.jar<br />
tlp.ThreeLeggedPig 1,https://dl.dropboxusercontent.com/u/75978227/roborumble_refuge/tlp.ThreeLeggedPig_1.jar<br />
tm.Yuugao 1.0,http://www.robocoderepository.com/BotFiles/1056/tm.Yuugao_1.0.jar<br />
tobe.calypso.Calypso 4.1,http://www.robocoderepository.com/BotFiles/784/tobe.calypso.Calypso_4.1.jar<br />
tobe.Fusion 1.0,http://www.robocoderepository.com/BotFiles/649/tobe.Fusion_1.0.jar<br />
tobe.mini.Charon 0.9,http://www.robocoderepository.com/BotFiles/836/tobe.mini.Charon_0.9.jar<br />
tobe.Relativity 3.9,http://www.robocoderepository.com/BotFiles/360/tobe.Relativity_3.9.jar<br />
tobe.Saturn lambda,http://www.robocoderepository.com/BotFiles/685/tobe.Saturn_lambda.jar<br />
tornyil.bottomup.BottomUp 1.05,http://www.alpha-consulting.hu/robo/tornyil.bottomup.BottomUp_1.05.jar<br />
tornyil.Lajcsi2.Lajcsi2sm 1.0,http://www.alpha-consulting.hu/robo/tornyil.Lajcsi2.Lajcsi2sm_1.0.jar<br />
toz.Gnome 1.1,http://robocode-archive.strangeautomata.com/robots/toz.Gnome_1.1.jar<br />
trab.Crusader 0.1.7,http://www.stud.ntnu.no/~grashei/bots/trab.Crusader_0.1.7.jar<br />
trab.nano.AinippeNano 1.3,http://www.stud.ntnu.no/~grashei/bots/trab.nano.AinippeNano_1.3.jar<br />
traker.Eraser 1,http://robocode-archive.strangeautomata.com/robots/traker.Eraser_1.jar<br />
tvv.micro.Antares 1.1.1,https://sites.google.com/site/tvvrobots/tvv.micro.Antares_1.1.1.jar?attredirects=0&d=1<br />
tvv.nano.Polaris 1.2,https://sites.google.com/site/tvvrobots/tvv.nano.Polaris_1.2.jar?attredirects=0&d=1<br />
tw.Exterminator 1.0,http://www.robocoderepository.com/BotFiles/3607/tw.Exterminator_1.0.jar<br />
tzu.TheArtOfWar 1.2,http://robocode-archive.strangeautomata.com/robots/tzu.TheArtOfWar_1.2.jar<br />
ua.kiiv.kosyak.robocode.tn1.Tn1 2.0,http://www.robocoderepository.com/BotFiles/4072/ua.kiiv.kosyak.robocode.tn1.Tn1_2.0.jar<br />
uccc.Dorito 1.12,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.Dorito_1.12.jar<br />
uccc.MilkyWay 1.01,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.MilkyWay_1.01.jar<br />
uccc.RingDing 1.12,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.RingDing_1.12.jar<br />
uccc.Scrapple 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/uccc.Scrapple_1.0.jar<br />
ultra.Defender 1.2,http://teamgallego.com/dl/bots/ultra.Defender_1.2.jar<br />
unarmedlad.nano.VirginSteele 2.2,https://dl.dropbox.com/s/nt32eas7mzp7wbe/unarmedlad.nano.VirginSteele_2.2.jar<br />
urdos.URDOS 1.3,http://robocode-archive.strangeautomata.com/robots/urdos.URDOS_1.3.jar<br />
usa.nano.Nemo 2.0,http://www.robocoderepository.com/BotFiles/2045/usa.nano.Nemo_2.0.jar<br />
vic.Locke 0.7.5.5,http://www.robocoderepository.com/BotFiles/2115/vic.Locke_0.7.5.5.jar<br />
vft.Valkyrie 1.0,http://www.robocoderepository.com/BotFiles/3009/vft.Valkyrie_1.0.jar<br />
vft.Hrist 1.0,http://robocode-archive.strangeautomata.com/robots/vft.Hrist_1.0.jar<br />
vjik.UnViolation 1.1,http://www.robocoderepository.com/BotFiles/3886/vjik.UnViolation_1.1.jar<br />
voidious.Diamond 1.8.22,http://www.dijitari.com/void/robocode/voidious.Diamond_1.8.22.jar<br />
voidious.Dookious 1.573c,https://dl.dropbox.com/u/72179384/voidious.Dookious_1.573c.jar<br />
voidious.micro.Jen 1.11,https://dl.dropbox.com/u/72179384/voidious.micro.Jen_1.11.jar<br />
voidious.mini.Komarious 1.88,https://dl.dropbox.com/u/72179384/voidious.mini.Komarious_1.88.jar<br />
voidious.perceptual.RetroGirl 1.0.0,https://dl.dropbox.com/u/72179384/voidious.perceptual.RetroGirl_1.0.0.jar<br />
vort.Chaser 0.0.3,https://github.com/Vort/Chaser/blob/master/packed/vort.Chaser_0.0.3.jar?raw=true<br />
vuen.Fractal 0.55,http://www.robocoderepository.com/BotFiles/1579/vuen.Fractal_0.55.jar<br />
WarfaJibril.Jibril_Warfa_Andromeda 1.11,http://www.robocoderepository.com/BotFiles/4089/WarfaJibril.Jibril_Warfa_Andromeda_1.11.jar<br />
wcsv.Engineer.Engineer 0.5.4,http://robocode-archive.strangeautomata.com/robots/wcsv.Engineer.Engineer_0.5.4.jar<br />
wcsv.PowerHouse.PowerHouse 1.7e3,http://robocode-archive.strangeautomata.com/robots/wcsv.PowerHouse.PowerHouse_1.7e3.jar<br />
wcsv.mega.PowerHouse2 0.2,http://robocode-archive.strangeautomata.com/robots/wcsv.mega.PowerHouse2_0.2.jar<br />
wcsv.Stampede 1.3.3,http://www.robocoderepository.com/BotFiles/2527/wcsv.Stampede_1.3.3.jar<br />
wcsv.Stampede2.Stampede2 1.1.0,http://www.robocoderepository.com/BotFiles/2714/wcsv.Stampede2.Stampede2_1.1.0.jar<br />
WdV.Lesserbee 0.01,http://www.robocoderepository.com/BotFiles/4046/WdV.Lesserbee_0.01.jar<br />
whind.Constitution 0.7.1,http://www.robocoderepository.com/BotFiles/2812/whind.Constitution_0.7.1.jar<br />
whind.Strength 0.6.4,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/whind.Strength_0.6.4.jar<br />
whind.StrengthBee 0.6.4,http://whindgames.50webs.com/otherstuff/whind.StrengthBee_0.6.4.jar<br />
whind.Wisdom 0.5.1,http://www.robocoderepository.com/BotFiles/2742/whind.Wisdom_0.5.1.jar<br />
whitesquare.robots.SkynetAdvanced 1.1,https://dl.dropbox.com/s/6epm51goxqp7p0h/whitesquare.robots.SkynetAdvanced_1.1.jar?dl=1<br />
WidowMakersAtWar.EpicCow 1.0,https://sites.google.com/site/dereksrobots/home/epiccow/WidowMakersAtWar.EpicCow_1.0.jar?attredirects=0&d=1<br />
wiki.BasicBulletShielder 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.BasicBulletShielder_1.0.jar<br />
wiki.BasicGFSurfer 1.02,http://robocode-archive.strangeautomata.com/robots/wiki.BasicGFSurfer_1.02.jar<br />
wiki.mako.MakoHT 1.2.2.1,http://www.robocoderepository.com/BotFiles/1374/wiki.mako.MakoHT_1.2.2.1.jar<br />
wiki.mini.BlackDestroyer 0.9.0,http://www.robocoderepository.com/BotFiles/1927/wiki.mini.BlackDestroyer_0.9.0.jar<br />
wiki.mini.GouldingiHT 1.0,http://www.robocoderepository.com/BotFiles/1383/wiki.mini.GouldingiHT_1.0.jar<br />
wiki.mini.Griffon 0.1,http://www.robocoderepository.com/BotFiles/1774/wiki.mini.Griffon_0.1.jar<br />
wiki.mini.Sedan 1.0,http://www.robocoderepository.com/BotFiles/1676/wiki.mini.Sedan_1.0.jar<br />
wiki.nano.DevilFISH 1.0,http://www.robocoderepository.com/BotFiles/2235/wiki.nano.DevilFISH_1.0.jar<br />
wiki.nano.RaikoNano 1.1,http://www.robocoderepository.com/BotFiles/2163/wiki.nano.RaikoNano_1.1.jar<br />
wiki.SuperSampleBot.SuperSittingDuck 1.0,http://robocode-archive.strangeautomata.com/robots/wiki.SuperSampleBot.SuperSittingDuck_1.0.jar<br />
wiki.WaveRammer 1.0,http://www.robocoderepository.com/BotFiles/3505/wiki.WaveRammer_1.0.jar<br />
wiki.Wolverine 2.1,http://robocode-archive.strangeautomata.com/robots/wiki.Wolverine_2.1.jar<br />
wilson.Chameleon 0.91,http://www.robocoderepository.com/BotFiles/1608/wilson.Chameleon_0.91.jar<br />
winamp32.micro.MicroMacro 1.0,http://www.robocoderepository.com/BotFiles/2891/winamp32.micro.MicroMacro_1.0.jar<br />
wit.Chuliath 1.0,http://www.robocoderepository.com/BotFiles/2306/wit.Chuliath_1.0.jar<br />
wit.Deep7 2.0,http://www.robocoderepository.com/BotFiles/2313/wit.Deep7_2.0.jar<br />
wompi.Kowari 1.6,http://www.casepool.de/robocode/wompi.Kowari_1.6.jar<br />
wompi.Numbat 1.9,http://www.casepool.de/robocode/wompi.Numbat_1.9.jar<br />
xander.cat.Fiona 1.4,http://www.distantvisions.net/robocode/xander.cat.Fiona_1.4.jar<br />
xander.cat.Mikey 1.2,http://www.distantvisions.net/robocode/xander.cat.Mikey_1.2.jar<br />
xander.cat.SamAxe 1.1,http://www.distantvisions.net/robocode/xander.cat.SamAxe_1.1.jar<br />
xander.cat.Spitfire 1.4,http://www.distantvisions.net/robocode/xander.cat.Spitfire_1.4.jar<br />
xander.cat.XanderCat 12.8,http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
xiongan.Xiongan 1.1,http://www.robocoderepository.com/BotFiles/3565/xiongan.Xiongan_1.1.jar<br />
yagami.Tidus 0.11,http://www.robocoderepository.com/BotFiles/4123/yagami.Tidus_0.11.jar<br />
yarghard.Y101 1.0,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/yarghard.Y101_1.0.jar<br />
yabot.YaBot 0.1,http://robocode-archive.strangeautomata.com/robots/yabot.YaBot_0.1.jar<br />
yk.JahMicro 1.0,http://www.robocoderepository.com/BotFiles/3033/yk.JahMicro_1.0.jar<br />
yk.JahRoslav 1.1,http://www.robocoderepository.com/BotFiles/3032/yk.JahRoslav_1.1.jar<br />
zen.Lindada 0.2,http://www.robocoderepository.com/BotFiles/1679/zen.Lindada_0.2.jar<br />
zeze2.OperatorZeze 1.05,http://www.robocoderepository.com/BotFiles/3330/zeze2.OperatorZeze_1.05.jar<br />
zezinho.QuerMePegarKKKK 1.0,http://www.vamoslogo.com.br/zezinho.QuerMePegarKKKK_1.0.jar<br />
zch.David 0.21,http://www.robocoderepository.com/BotFiles/3575/zch.David_0.21.jar<br />
zch.Hirkan 0.11,http://www.robocoderepository.com/BotFiles/1288/zch.Hirkan_0.11.jar<br />
zh.UnderDog 0.0.2,http://www.robocoderepository.com/BotFiles/3053/zh.UnderDog_0.0.2.jar<br />
zignd.ZigIndexOutOfRange 1.1,https://dl.dropboxusercontent.com/s/fbq6nfybjjemp34/zignd.ZigIndexOutOfRange_1.1.jar<br />
zyx.mega.YersiniaPestis 3.0,http://robocode-archive.strangeautomata.com/robots/zyx.mega.YersiniaPestis_3.0.jar<br />
zyx.micro.Ant 1.1,http://www.robocoderepository.com/BotFiles/3481/zyx.micro.Ant_1.1.jar<br />
zyx.nano.Ant 1.1,http://www.robocoderepository.com/BotFiles/3493/zyx.nano.Ant_1.1.jar<br />
zyx.nano.EscherichiaColi 1.0,http://robocode-archive.strangeautomata.com/robots/zyx.nano.EscherichiaColi_1.0.jar<br />
zyx.nano.RedBull 1.0,http://robocode-archive.strangeautomata.com/robots/zyx.nano.RedBull_1.0.jar<br />
zzx.Ignohis 8.0,https://sites.google.com/site/devonrobots/home/wave-surfers/zzx.Ignohis_8.0.jar?attredirects=0&d=1<br />
zzx.StormHead 1.0.1,http://robocoderepository.com/BotFiles/4193/zzx.StormHead_1.0.1.jar<br />
zzx.Gron 1.14,http://robocoderepository.com/BotFiles/4194/zzx.Gron_1.14.jar<br />
zzx.Serunyr 2.0.2,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/zzx.Serunyr_2.0.2.jar<br />
nz.A7Ibwenape A7Ibwen1.0,http://www.robocoderepository.com/BotFiles/4294/nz.A7Ibwenape_A7Ibwen1.0.jar<br />
</pre><br />
----<br />
'''''No chatting on this page. Use the /ParticipantsChat page for that.'''''<br />
<br />
'''''Removed due to Out Of Memory Exceptions in long battles'''''<br />
cs.ags.Scarlet 1.1c,http://file.csdgn.org/robocode/cs.ags.Scarlet_1.1c.jar<br />
<br />
'''''Removed because the jarcontent/filename is not correct'''''<br><br />
''cberendt.Bot1 0.160''<br><br />
''dmsr.MiniR101 0.6''<br><br />
''henriquevilela.TieFighter 0.1,3224''<br><br />
''jgap.Aspirant_7980_gen7 1.0,3552''br><br />
''jgap.Aspirant_13029_gen7 1.0,3553''<br><br />
''techdude.Carruthers 1.2.6''<br><br />
''uccc.Orbiter 1.0''<br><br />
''WhoAmI.WhoAmI 1.00''<br><br />
Nucleii.ED4 1.0,http://www.robocoderepository.com/BotFiles/4091/Nucleii.ED4_1.0.jar<br />
<br />
'''''Removed due to being a team'''''<br />
sp.Minis.GeneBotUpgrade 1.1,http://robocode-archive.strangeautomata.com/robots/sp.Minis.GeneBotUpgrade_1.1.jar?attredirects=0&d=1<br />
<br />
'''''Removed until file corruption is resolved:'''''<br />
<br />
''cas.CelsoKiller 1.0,3465''<br />
<br />
'''''Removed due to almost always giving '0' scores:'''''<br />
<br />
''lazarecki.PinkerStinker 0.1,http://www.robocoderepository.com/BotFiles/3824/lazarecki.PinkerStinker_0.1.jar''<br />
<br />
'''''Removed because it's incorrectly packaged:'''''<br />
<br />
''Indesh.Indesh 1.1,http://jakobserlier.250free.com/Indesh.jar''<br />
<br />
''loganom.FirstRobot 0.1, http://www.loganom.com/robocode/loganom.FirstRobot_0.1.jar''<br />
<br />
''<br />
fruits.micro.Cherry 1.1,http://robocode-archive.strangeautomata.com/robots/fruits.micro.Cherry_1.1.jar''<br />
<br />
'''''Removed due to invalid line'''''<br />
<br />
''Legend.LNightHawk,http://robocoderepository.com/BotFiles/4167/Legend.LNightHawk.class''<br><br />
''WidowMakersAtWar.Hollow,http://http://www.robocoderepository.com/BotDetail/4169/WidowMakersAtWar.Hollow.jar''<br />
<br />
'''''Removed due to requiring Java 7'''''<br />
<br />
''fromHell.C4H10O 1.5,http://fromhell.schreiende-stille.de/Robocode/Java/fromHell.C4H10O_1.5.jar''<br><br />
''stranger.nano.TestBot 1.0,https://dl.dropboxusercontent.com/u/18119890/stranger.nano.TestBot_1.0.jar''<br><br />
''com.timothyveletta.FuzzyBot 1.1,https://github.com/aleksey-zhidkov/rc-repo-mirror/raw/master/com.timothyveletta.FuzzyBot_1.1.jar''<br />
<br />
----<br />
<br />
'''''Removed due to WontFix issues in Robocode 1.7+:'''''<br><br />
''* Hviela: ([[http://sourceforge.net/tracker/?func=detail&aid=2953268&group_id=37202&atid=419486 SF #2953268]])''<br><br />
'': hvilela.HVilela 0.9.3,http://henrique.vilela.googlepages.com/hvilela.HVilela_0.9.3.jar''<br><br />
''* Barney (Tries to write files without using RobocodeOutputStream. Robocode 1.7 punishes for that more harshly which will give 0 scores)<br><br />
'': Homer.Barney 1.0,http://www.robocoderepository.com/BotFiles/1932/Homer.Barney_1.0.jar<br></div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=32268XanderCat2013-11-18T21:50:41Z<p>Skotty: Updated version information for 12.8</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #5* (v 12.6)<br />
| current_version = 12.8<br />
| codesize = 58,581 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.8.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, it was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for suring first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen alot with a rammer, but the ram scenario happens earier in the component chain and thus superscedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is embued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, thus the name.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essense moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upperhand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earlist concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
<i>Framework Changes</i><br />
* Removed the "waste basket" utility.<br />
* Added a skipped turn simulator that can be used during testing.<br />
<i>XanderCat Changes</i><br />
* Updated created wave objects from opponent bullets fired when scans are missed (for example, if there are skipped turns) to flag them as estimated (the system doesn't know exactly on what scan the bullet was fired because we don't have back to back scans).<br />
* Bullet shielding controller no longer accepts estimated opponent waves as valid waves to shield against. This won't prevent hits on us but will prevent a hit from an estimated wave from being seen as a shielding failure (as it's really a scan failure).<br />
* Adjusted shielding energy level condition for shielding scenario to accept reduced effectiveness on first couple of rounds to account for skipped turns early in the game (I didn't fix the skipped turns problem, I just worked around it).<br />
<br />
<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=32267XanderCat2013-11-18T21:01:57Z<p>Skotty: /* Version 12.8 (Planned) */ updated notes -- I'm on to something!</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #5* (v 12.6)<br />
| current_version = 12.7<br />
| codesize = 58,628 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.7.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, it was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for suring first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen alot with a rammer, but the ram scenario happens earier in the component chain and thus superscedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is embued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, thus the name.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essense moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upperhand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earlist concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 (In Development) ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. <br />
<br />
After more research, it appears as though the problem caused by the skipped turns is not so much with timing (or insufficient time) causing shielding misses, but rather a problem with how opponent wave objects are created when the opponents bullet was fired on a skipped turn! Fixing this may be enough to make the shielding work even with the missed turns, plus there may be a latent benefit of eliminating/reducing tracking errors in general. Therefore...<br />
<br />
Changes in this version include:<br />
* Updated created wave objects from opponent bullets fired on skipped turns to make them more accurate (and flag them as estimated if uncertainty exists).<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=32262XanderCat2013-11-18T17:22:05Z<p>Skotty: /* Version 12.8 (Planned) */ updated notes</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #5* (v 12.6)<br />
| current_version = 12.7<br />
| codesize = 58,628 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.7.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, it was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for suring first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen alot with a rammer, but the ram scenario happens earier in the component chain and thus superscedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is embued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, thus the name.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essense moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upperhand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earlist concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 (Planned) ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. Possibilities include:<br />
* Going back to an object pooling approach.<br />
* Using a backing array (hidden as much as possible) for frequently constructed and thrown away objects like snapshots (in 1v1, 2 snapshots are created on every tick, and usually 2 are thrown away every tick as well).<br />
* Updating shielding scenario so that it ignores failures when turns have been skipped. This may end up being the best approach and will likely be what I try first.<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=XanderCat&diff=32261XanderCat2013-11-18T17:17:53Z<p>Skotty: /* Version 12.8 (Planned) */ revised</p>
<hr />
<div>[[Category:Bots|XanderCat]]<br />
<br />
{{Infobox Robot<br />
| bgcolour = LightBlue<br />
| author = [[User:Skotty|Skotty]]<br />
| extends = [[AdvancedRobot]]<br />
| image = XanderCatLogo-small.png<br />
| targeting = [[GuessFactor Targeting|GF]] / [[Linear_Targeting|Linear]] / [[Circular_Targeting|Circular]] / Anti-Mirror / [[Bullet_Shielding|Bullet Shielding]]<br />
| movement = [[Wave Surfing|WS(GoTo)]] / Anti-Mirror / RamEscape / Ram / IdealPosition<br />
| released = 2011-5-20 (v 1.0)<br />
| best_rating = #5* (v 12.6)<br />
| current_version = 12.7<br />
| codesize = 58,628 (lol)<br />
| license = GCWCD<br />
| download_link = http://www.distantvisions.net/robocode/xander.cat.XanderCat_12.7.jar<br />
}}<br />
<br />
== Introduction ==<br />
<br />
MegaBot based on my [[XanderFramework|Xander Robot Framework]] with pluggable guns, radars, and drives. XanderCat is the flagship of my robot fleet. It is a multi-mode robot using multiple guns and drives organized into a ''component chain''. It's main gun is a guess factor gun, and the main drive is a wave surfing drive (GoTo-style), but a number of other guns and drives exist for special situations. Both the main gun and drive are currently using a hybrid form of dynamic clustering. The drive is somewhat unique in that it decides where it wants to go and goes there directly (no orbiting -- though the path still is somewhat orbital in nature due to MEAs and distancing -- and no wall stick while driving). XanderCat also makes use of my [[XanderPaintingFramework|Xander Painting Framework]] for development and debugging.<br />
<br />
(*) As of 2013, it was ranked #7 in the rumble, but can rank as high as #5 if a solution for the first round garbage collection problem can be implemented. It is unusual to have a garbage collection issue in Java, but Robocode is an unusual game. On some platforms, garbage collection in the first round can cause multiple skipped turns on large robots that create a lot of objects. This is true for XanderCat. XanderCat is further affected by this issue because it causes the bullet shielding mode to fail some of the time, when otherwise it would have worked.<br />
<br />
'''Best against:''' Generally a good performer; probably most notable for having simple yet effective anti-mirroring capabilities.<br />
<br />
'''Worst against:''' Currently DrussGT, Diamond, and Tomcat are still quite deadly to XanderCat.<br />
<br />
'''Favorite Robots To Beat:''' <br />
* lazarecki.mega.PinkerStinker 0.7 - because I don't like it's name.<br />
* da.NewBGank 1.4 - because of it's name and because it can be beat by a large margin by exploiting a "newbie" bug in it, which is pleasantly ironic.<br />
<br />
'''Past Version Notes:''' For information on versions prior to the current series, see the [[XanderCat/History]] page.<br />
<br />
'''Name Origin?'''<br />
<br />
Xander comes from my son's name Alexander. Cat was originally meant to be of the feline variety, as I like cats, have used the term in other software projects, and it seemed appropriate. Cat could also be associated with the tractor variety, which I think also works (a tractor with a gun), and I'm fine if people make that association too.<br />
<br />
'''Hybrid Dynamic Clustering?'''<br />
<br />
XanderCat uses Dynamic Clustering (DC) in the sense that data about past waves is stored in a tree structure. For each wave, past data is pulled from the tree that as closely as possible matches the current situation, and that data is used to decide where to aim or drive. However, once the data is pulled, how to use it differs from classic DC. In classic DC, some form of kernel density algorithm is used to determine what to do. In the XanderCat hybrid approach, it behaves more like VCS, in that the data is logged into a factor array, and that array is surfed in the GoTo style.<br />
<br />
'''Surfing Multiple Waves?'''<br />
<br />
Starting with version 9.5, XanderCat now surfs up to 2 waves at a time. The general approach is as follows:<br />
# Calculate the first n best factor angles to drive to for the next wave to hit, each of which must be separated by a given amount. Each has an associated danger value.<br />
# From the end points of the n factor angles, continue to predict into the future surfing of the second wave to hit. For the second wave, only the best factor angle is used.<br />
# Add the first wave danger value to the corresponding second wave danger value for both the factor angles of the first wave. Choose which first wave factor angle to drive to by which has the lowest combined danger value. (Note: The calculation is a little more complicated, taking wave distance and bullet power into account, but the basic idea is the same.)<br />
<br />
Note the image below, where:<br />
* a = reachable factor range for first wave<br />
* b = minimum distance that must exist between choices<br />
* c = first choice for surfing first wave<br />
* d = second choice for suring first wave<br />
* e = current robot position<br />
<br />
If the sum of the danger values represented by orange lines was less than the sum of the danger values represented by the red lines, the second choice for the first wave would be used.<br />
<br />
[[File:skotty-2wsrf.png]]<br />
<br />
'''Saving Data Between Battles?'''<br />
<br />
XanderCat does save data between battles, but that data is not used by the robot and does not effect performance any. It is collected solely for my own analysis. It helps me find problems and decide on where improvements are needed. I also just like statistics. Of course, I only get statistics on battles run by my own machine. Below is an example some data it collected:<br />
<br />
Key:<br />
# Opponent = Opponent robot name and version<br />
# G1 Shots = Shots taken by the main guess factor gun<br />
# G2 Shots = Shots taken by the Anti-Scarlet guess factor gun<br />
# CD Scenario = Percentage of time the CircularDriverScenario was applied against the opponent<br />
# PD Engage = Number of times my bullet fire power was dropped (see v10.21 notes for what this means)<br />
# Flattener = Percent of total time the flattener was engaged<br />
# My HR = My overall hit ratio<br />
# Opponent HR = Opponent overall hit ratio<br />
<br />
{| border="1" cellpadding="4"<br />
!Opponent<br />
!G1 Shots<br />
!G2 Shots<br />
!CD Scenario<br />
!PD Engage<br />
!Flattener<br />
!My HR<br />
!Opponent HR<br />
|-<br />
| techdude.kombat.FlamingKombat 1.5<br />
| 8<br />
| 62<br />
| 78.5%<br />
| 0<br />
| 0.0%<br />
| 73.5%<br />
| 3.4%<br />
|-<br />
| test.Fuzzer 1.0.1<br />
| 449<br />
| 13<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 60.6%<br />
| 9.9%<br />
|-<br />
| test.Podgy 4.0<br />
| 465<br />
| 387<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 22.0%<br />
| 7.2%<br />
|-<br />
| throxbot.ThroxBot 0.1 <br />
| 747<br />
| 12<br />
| 0.0%<br />
| 0<br />
| 0.0%<br />
| 30.9%<br />
| 5.5%<br />
|-<br />
| tide.pear.Pear 0.62.1 <br />
| 806<br />
| 490<br />
| 0.0%<br />
| 10<br />
| 7.0%<br />
| 13.0%<br />
| 11.2%<br />
|}<br />
<br />
In addition to saving data on each robot, it can save a generic set of data about performance against the field as a group. As an example, to get an idea of early, mid-game, and late game performance, I log the number of round wins for each round. Example (to keep the table short, I left out rows for rounds 3 through 31):<br />
<br />
{| border="1" cellpadding="4"<br />
! Round<br />
! Wins<br />
! % Wins<br />
|-<br />
| 0<br />
| 615<br />
| 88.9%<br />
|-<br />
| 1<br />
| 630<br />
| 91.0%<br />
|-<br />
| 2<br />
| 613<br />
| 88.6%<br />
|-<br />
| ...<br />
|<br />
|<br />
|-<br />
| 32<br />
| 644<br />
| 93.1%<br />
|-<br />
| 33<br />
| 654<br />
| 94.5%<br />
|-<br />
| 34<br />
| 644<br />
| 93.1%<br />
|-<br />
| Total<br />
| 692<br />
| <br />
|}<br />
<br />
== Multi-Mode Scenarios / Component Chain ==<br />
<br />
'''Component Chain:'''<br />
<pre><br />
Default --> Basic Radar<br />
|<br />
v<br />
RamLowEnergyScenario -> Ram Drive, Ram Gun (fires no bullets; just a placeholder for the gun)<br />
|<br />
v<br />
BulletShieldingScenario -> Bullet Shielding Drive, Bullet Shielding Gun<br />
|<br />
v<br />
RamEscapeScenario --> Ram Escape Drive, Linear Gun<br />
|<br />
v<br />
AntiMirrorScenario --> Anti-Mirror Drive, Anti-Mirror Gun<br />
|<br />
v<br />
NoBulletWavesScenario --> Ideal Position Drive<br />
|<br />
v<br />
CircularDriverScenario --> Circular Gun<br />
|<br />
v<br />
Defaults --> Guess Factor Gun Array, Drive Array<br />
| ______|_______________<br />
| / \<br />
| Targeting Detector Drive Main Wave Surfing Drive<br />
__________|___________<br />
/ \<br />
Original Gun Anti-Surfer Gun<br />
</pre><br />
<br />
'''Ram Low Energy Scenario'''<br />
<br />
This scenario attempts to ram the opponent if the opponent is at low energy and has stopped firing bullets. Should the <br />
opponent who stopped firing bullets suddenly fire a bullet at close range during the ram attempt, the low energy cutoff<br />
can be reduced further (fool me twice, shame on me). Also, this scenario will only engage if our own robot is over some<br />
minimum energy level threshold.<br />
<br />
To ram the opponent, the ram drive uses three approach methods depending on distance from opponent. At far distances,<br />
the ram drive will just drive directly at the opponent. At short distance, the ram drive uses a linear intercept. At<br />
intermediate distances, the ram drive uses a blending of the two.<br />
<br />
'''Bullet Shielding Scenario'''<br />
<br />
This scenario attempts to use bullet shielding against the opponent. The bullet shielding components basically follow the standard approach, except I didn't bother trying to make the bullet lines cross at their segment midpoints, so there may be an improvement to make there some day? Determining ''when'' to use this scenario is a bit complex, and includes 9 different conditions that must be met for the scenario to apply.<br />
<br />
'''Ram Escape Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be ramming. At present, this works be simply testing the opponent's distance being under some threshold. This sometimes happens against robots who are not really ramming -- this can happen due to initial round positioning, or just due to drive paths that happen to run too close together -- but in these cases there is no real disadvantage to using the ram scenario to back away from the opponent. This distance of ram detection will increase the more the ram scenario is applied. This makes the ram scenario kick in sooner and more often against the real rammers who ram consistently.<br />
<br />
When this scenario is applied, a Ram Escape Drive is paired with a linear targeting gun. At present, this is the only place in which I utilize linear targeting. The Ram Escape Drive attempts to drive away from the enemy as much as possible, and uses turning to try and dodge some of the opponents shots (for example, it may change the direction of turn at the moment an opponent shot is detected).<br />
<br />
'''Anti-Mirror Scenario'''<br />
<br />
This scenario applies whenever the opponent appears to be using a mirroring drive strategy. The countering technique is to plan a drive path into the future such that it is known where to shoot in order to hit the mirrored position in the future. At present, this can be fooled by creative mirrorers that utilize a delay or position shifting.<br />
<br />
'''No-Bullet-Waves Scenario'''<br />
<br />
This scenario applies whenever the opponent has no bullets in the air (note: this can happen alot with a rammer, but the ram scenario happens earier in the component chain and thus superscedes this scenario). When the opponent has no bullets in the air, the Ideal Position Drive takes over and moves the robot directly to what it perceives as the ideal position on the battlefield given the battlefield size and the current position of the opponent.<br />
<br />
I've attempted to replace this somewhat crude drive a few times, but each time resulted in a lower overall score in the RoboRumble, giving rise to the idea that this drive is embued with magical powers.<br />
<br />
'''Circular Driver Scenario'''<br />
<br />
This scenario doesn't affect overall performance much, but it does two things that make me feel better: first, it brings back my circular gun, which otherwise would not be in use. I once spent a lot of time on it, and would like it to be used somewhere. Second, it makes me feel better when pitted against simple circular drivers like SpinBot, where my guess factor gun still misses quite a few shots, but my circular gun can hit nearly every time. <br />
<br />
To make this scenario as effective as possible without degrading any performance elsewhere, it is not enough for an opponent to appear to be moving in a circular path at the time a shot is taken. The opponent must have been moving (and still be moving) in a consistent circular path. Furthermore, that path must not intersect any walls before the shot would reach them. The circular movement path is predicted into the future until the bullet would arrive to check for this. ''(Note: Using prediction for this is not really a good idea; I should have just checked the bounds of the circle. I will make this change in some future version.)''<br />
<br />
'''Default Gun Array'''<br />
<br />
The gun array consists of several guess factor guns. This is not too computationally expensive because they are currently all using the same cached copy of data. They just use the selected data differently when building the factor array to use for aiming. The Anti-Surfing Gun uses a certain amount of data rolling. This technique was first implemented to counter Scarlet, who at one time was trouncing my robot far worse than any other, thus the name.<br />
<br />
'''Default Drive Array'''<br />
<br />
The drive array consists of two drives: what I currently call the Targeting Detector Drive and the Main Wave Surfing Drive. Both drives are ''direct'' wave surfing drives. They just differ in what data they use to surf. I use the term ''direct'' to indicate how the drive moves the robot; the robot is moved at a fixed angle until it reaches the desired surfing factor angle for the current wave, in essense moving there directly in as straight a line as possible rather than using an orbital path. However, in action, it may still appear to use a somewhat orbital path, as where to move is recalculated for the same wave under various conditions -- such as when the waves are updated due to new bullet shadows, or the opponent moves too far away from it's predicted path.<br />
<br />
''Main Wave Surfing Drive''<br />
<br />
This drive uses Dynamic Clustering with a KD Tree for it's data management. A simple equation is used to determine how many nearest neighbor data points to pull, and those points are logged into a factor array to surf.<br />
<br />
''Targeting Detector Drive''<br />
<br />
This drive uses a combination of ''targeting detectors'' that are designed to detect specific types of targeting. Each targeting detector can add a data point to the factor array, with the data point weight based on how often the detector thinks it is detecting it's specific form of targeting. This system is designed to improve scores against robots that use predictable targeting (non-guess-factor), something I have had trouble getting my main wave surfing approach to handle as well as other top robots.<br />
<br />
'''Bullet Shielding Protection'''<br />
<br />
All main guns are wrapped by my ''BSProtectedGun'' wrapper/decorator class. It is a different animal from my original version. My original version shifted the target's position slightly to avoid perfect aim shots, a technique that works well against the basic shielder's such as uCatcher. However, it was generally ineffective against moving shielders like MoxieBot. At the same time, my normal aiming technique for my latest guess factor guns is not vulnerable to the stand-still shielders (by chance more than design). Therefore, the latest incarnation of my BSProtectedGun attempts to handle shielding using a new strategy that does not rely on shifted aims, and focuses more on protecting against on-the-move shielders. <br />
<br />
When bullet shielding is detected, the BSProtectedGun will check the energy levels of both robots. So long as my energy level is more than the opponents, the BSProtectedGun will halt firing and wait for the shielding opponent to fire first, then the BSProtectedGun fires immediately after the opponent. This ensures that the opponent's shot is not a shielding shot. It is still possible that the opponent could fire a second shielding shot before the my shot reaches them, but in practice this hasn't been an issue. This could also fail against perfect shielders where my energy level never exceeds the opponent's, but again, in practice this hasn't been an issue. If it did ever become an issue, I would keep basically the same strategy, but start shifting target position again like in the original gun.<br />
<br />
This strategy has an interesting yet not surprising result against MoxieBot. MoxieBot shields on the move, but the shielding is never perfect, and my robot can usually get the upperhand on energy at some point in the round. When this happens, my robot stops firing and waits for MoxieBot to fire first. However, MoxieBot in turn is waiting for me to fire before it fires, resulting in a stalemate where no one is firing. This in turn results in Robocode activating the stalemate energy drain. Neither robot incorrectly detects the energy drain as an opponent bullet, so the stalemate continues until the energy drain kills one of the robots. However, since my robot only stopped firing after getting the upper hand on energy, my robot gets the win. End result, a somewhat higher score against MoxieBot, and ''much'' higher survival.<br />
<br />
To improve on this further, I am considering possibly using chase bullets when my energy level is less than the opponent's, which should make it harder for the opponent to shield.<br />
<br />
= Version Notes =<br />
<br />
== Version Ranks ==<br />
<br />
Note: Best Change and Worst Change are the change from previous version against the given opponent.<br />
<br />
Note: Starting from version 6.4 onward in the table, I am ignoring nat.BlackHole 2.0gamma and nat.Samekh 0.4, as scores against them always fluctuate rather wildly.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!1-on-1 Rank<br />
!Top<br />
!Best Change<br />
!% Score Change<br />
!Worst Change<br />
!% Score Change<br />
|-<br />
| 1.0<br />
| ~475 / 805<br />
| 59%<br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 2.0<br />
| 386 / 806<br />
| 48%<br />
| mld.Wisdom 1.0<br />
| 4.18 -> 76.13<br />
| SuperSample.SuperCrazy 1.0<br />
| 61.97 -> 37.00<br />
|-<br />
| 2.1<br />
| 320 / 805<br />
| 40%<br />
| dz.MostlyHarmlessNano 2.1<br />
| 20.90 -> 63.01<br />
| jf.Dodger 1.1<br />
| 78.98 -> 41.10<br />
|-<br />
| 3.0<br />
| 148 / 805<br />
| 18%<br />
| gg.Wolverine 2.0<br />
| 41.08 -> 94.57<br />
| xiongan.Xiongan 1.1<br />
| 100.0 -> 74.39<br />
|-<br />
| 3.1<br />
| 145 / 804<br />
| 18%<br />
| zyx.nano.RedBull 1.0<br />
| 53.4 -> 85.3<br />
| pulsar.PulsarNano 0.2.4<br />
| 89.3 -> 64.2<br />
|-<br />
| 3.2<br />
| 116 / 806<br />
| 14%<br />
| ags.polished.PolishedRuby 1<br />
| 28.5 -> 83.5<br />
| rsim.micro.uCatcher 0.1<br />
| 91.7 -> 31.8<br />
|-<br />
| 3.3<br />
| 115 / 806<br />
| 14%<br />
| nat.Samekh 0.4<br />
| 24.9 -> 64.9<br />
| simonton.micro.GFMicro 1.0<br />
| 62.2 -> 39.2<br />
|-<br />
| 3.4<br />
| 85 / 806<br />
| 11%<br />
| dsx724.VSAB_EP3a 1.0<br />
| 67.2 -> 93.4<br />
| intruder.PrairieWolf 2.61<br />
| 65.6 -> 48.4<br />
|-<br />
| 3.5.1<br />
| 94 / 805<br />
| 12%<br />
| rsim.micro.uCatcher 0.1<br />
| 21.3 -> 96.4<br />
| nat.BlackHole 2.0gamma<br />
| 69.2 -> 42.5<br />
|-<br />
| 3.8<br />
| 81 / 805<br />
| 10%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 36.5 -> 49.8<br />
| mn.Combat 1.0<br />
| 80.1 -> 60.8<br />
|-<br />
| 3.9<br />
| 75 / 805<br />
| 9.3%<br />
| pez.mini.ChironexFleckeri 0.5<br />
| 42.2 -> 64.9<br />
| rsim.mini.BulletCatcher 0.4<br />
| 57.7 -> 7.0<br />
|-<br />
| 4.0<br />
| 92 / 805<br />
| 11%<br />
| rsim.mini.BulletCatcher 0.4<br />
| 7.0 -> 72.1<br />
| nat.Samekh 0.4<br />
| 73.3 -> 45.2<br />
|-<br />
| 4.1<br />
| 74 / 805 (73.66 APS)<br />
| 9.2% <br />
| nat.Samekh 0.4<br />
| 45.2 -> 75.7<br />
| staticline.whiskey.Whiskey 0.6<br />
| 75.5 -> 57.5<br />
|-<br />
| 4.2<br />
| 74 / 805 (73.73 APS)<br />
| 9.2% <br />
| mladjo.iRobot 0.3<br />
| 53.8 -> 69.9<br />
| jcs.AutoBot 4.2.1<br />
| 60.1 -> 35.1<br />
|-<br />
| 4.3<br />
| 74 / 805 (73.92 APS)<br />
| 9.2% <br />
| kc.mini.Vyper 0.311<br />
| 33.0 -> 53.0<br />
| positive.Portia 1.26e<br />
| 60.0 -> 36.2<br />
|-<br />
| 4.4<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| pez.frankie.Frankie 0.9.6.1<br />
| 45.9 -> 62.8<br />
| fromHell.CHCI3 0.1.4<br />
| 74.4 -> 55.7<br />
|-<br />
| 4.4.1<br />
| 71 / 805 (74.11 APS)<br />
| 8.8% <br />
| brainfade.Fallen 0.63<br />
| 45.7 -> 65.5<br />
| jam.micro.RaikoMicro 1.44<br />
| 64.0 -> 49.8<br />
|-<br />
| 4.5.1<br />
| 71 / 805 (74.25 APS)<br />
| 8.8% <br />
| spinnercat.CopyKat 1.2.3<br />
| 51.6 -> 69.3<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 54.4 -> 38.6<br />
|-<br />
| 4.6<br />
| 71 / 805 (74.35 APS)<br />
| 8.8% <br />
| deo.virtual.RainbowBot 1.0<br />
| 54.8 -> 69.1<br />
| jab.DiamondStealer 5<br />
| 80.6 -> 61.7<br />
|-<br />
| 4.8<br />
| 57 / 803 (76.46 APS)<br />
| 7.1% <br />
| ar.QuantumChromodynamics 1.2.1<br />
| 69.2 -> 90.5<br />
| nat.BlackHole 2.0gamma<br />
| 60.8 -> 42.0<br />
|-<br />
| 5.0<br />
| 70 / 805 (74.37 APS)<br />
| 8.7% <br />
| deo.FlowerBot 1.0<br />
| 53.4 -> 84.6<br />
| kcn.unnamed.Unnamed 1.21<br />
| 79.1 -> 58.0<br />
|-<br />
| 5.1<br />
| 49 / 815 (78.59 APS)<br />
| 6.0% <br />
| ary.SMG 1.01<br />
| 35.5 -> 90.3<br />
| nat.BlackHole 2.0gamma<br />
| 54.4 -> 33.0<br />
|-<br />
| 5.1.1<br />
| 49 / 815 (78.75 APS)<br />
| 6.0% <br />
| rz.Apollon 0.23<br />
| 69.6 -> 94.0<br />
| nat.Samekh 0.4<br />
| 72.7 -> 53.6<br />
|-<br />
| 6.1.8<br />
| 59 / 806 (76.65 APS)<br />
| 7.3% <br />
| cx.Princess 1.0<br />
| 47.8 -> 65.1<br />
| toz.Gnome 1.1<br />
| 88.4 -> 61.6<br />
|-<br />
| 6.2<br />
| 59 / 806 (76.84 APS)<br />
| 7.3% <br />
| nat.BlackHole 2.0gamma<br />
| 42.1 -> 67.0<br />
| stelo.RamTrackSurfer 1.2<br />
| 89.2 -> 72.9<br />
|-<br />
| 6.3<br />
| 56 / 806 (77.04 APS)<br />
| 6.9% <br />
| kid.Gladiator .7.2<br />
| 47.7 -> 65.5<br />
| nat.BlackHole 2.0gamma<br />
| 53.4 -> 33.3<br />
|-<br />
| 6.4<br />
| 51 / 806 (78.22 APS)<br />
| 6.3% <br />
| dmp.micro.Aurora 1.41<br />
| 62.1 -> 79.1<br />
| myl.micro.NekoNinja 1.30<br />
| 77.3 -> 61.3<br />
|-<br />
| 6.5<br />
| 48 / 808 (78.70 APS)<br />
| 5.9% <br />
| ncj.MoxieBot 1.0<br />
| 76.9 -> 92.6<br />
| bayen.nut.Squirrel 1.621<br />
| 89.3 -> 74.9<br />
|-<br />
| 6.7<br />
| 45 / 807 (79.17 APS)<br />
| 5.6% <br />
| apv.ScruchiPu 1.0<br />
| 57.9 -> 79.5<br />
| trab.nano.AinippeNano 1.3<br />
| 91.4 -> 74.7<br />
|-<br />
| 6.8<br />
| 42 / 808 (79.69 APS)<br />
| 5.2% <br />
| trab.nano.AinippeNano 1.3<br />
| 72.2 -> 89.5<br />
| rampancy.Durandal 2.2d<br />
| 81.5 -> 69.4<br />
|-<br />
| 9.0<br />
| 46 / 827 (79.73 APS)<br />
| 5.6% <br />
| N/A<br />
| N/A<br />
| N/A<br />
| N/A<br />
|-<br />
| 9.0.1<br />
| 45 / 827 (80.03 APS)<br />
| 5.4% <br />
| ary.SMG 1.01<br />
| 50.5 -> 76.4<br />
| ncj.MoxieBot 1.0<br />
| 95.5 -> 75.5<br />
|-<br />
| 9.1<br />
| 43 / 828 (80.25 APS)<br />
| 5.2% <br />
| kc.mini.Vyper 0.311<br />
| 54.7 -> 60.7<br />
| ab.DangerousRoBatra 1.3<br />
| 74.0 -> 66.7<br />
|-<br />
| 9.2<br />
| 38 / 828 (80.84 APS)<br />
| 4.6%<br />
| Bemo.Sweet30 1.6.1<br />
| 57.9 -> 68.3<br />
| kenran.mega.Pantheist<br />
| 75.3 -> 57.1<br />
|-<br />
| 9.3<br />
| 34 / 829 (81.35 APS)<br />
| 4.1%<br />
| ags.micro.Carpet 1.1<br />
| 76.3 -> 89.2<br />
| ary.SMG 1.01<br />
| 81.2 -> 64.9<br />
|-<br />
| 9.4<br />
| 33 / 830 (81.55 APS)<br />
| 4.0%<br />
| kenran.mega.Panthiest<br />
| 73.9 -> 85.3<br />
| bayen.nut.Squirrel 1.621<br />
| 88.8 -> 80.9<br />
|-<br />
| 9.5<br />
| 30 / 830 (81.71 APS)<br />
| 3.6%<br />
| wiki.BasicGFSurfer<br />
| 65.3 -> 75.5<br />
| rampancy.Durandal 2.2d<br />
| 80.3 -> 67.6<br />
|-<br />
| 9.6<br />
| 28 / 830 (81.91 APS)<br />
| 3.4%<br />
| darkcanuck.Gaff 1.50<br />
| 43.3 -> 52.4<br />
| kenran.mega.Panthiest 1.1<br />
| 89.6 -> 78.9<br />
|-<br />
| 9.7.1<br />
| 25 / 832 (82.05 APS)<br />
| 3.0%<br />
| rampancy.Durandal 2.2d<br />
| 77.8 -> 88.3<br />
| brainfade.Fallen 0.63<br />
| 64.0 -> 57.0<br />
|-<br />
| 9.8<br />
| 25 / 832 (82.12 APS, 1600 PL)<br />
| 3.0%<br />
| asm.Statistas 0.1<br />
| 70.4 -> 77.1<br />
| wcsv.PowerHouse.PowerHouse 1.7e3<br />
| 53.9 -> 46.8<br />
|-<br />
| 9.9.5<br />
| 24 / 831 (82.37 APS, 1604 PL)<br />
| 2.9%<br />
| ncj.MoxieBot 1.0<br />
| 74.9 -> 86.0<br />
| cx.mini.Cigaret 1.31<br />
| 64.9 -> 55.2<br />
|-<br />
| 9.15<br />
| 20 / 833 (82.74 APS, 1646 PL)<br />
| 2.4%<br />
| janm.Jammy 1.0<br />
| 75.2 -> 91.4<br />
| davidalves.net.DuelistMicro 1.22<br />
| 72.1 -> 63.8<br />
|-<br />
| 10.13<br />
| 19 / 837 (82.98 APS, 1658 PL)<br />
| 2.3%<br />
| whind.StrengthBee 0.6.4<br />
| 56.8 -> 67.8<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 74.6 -> 63.9<br />
|-<br />
| 10.15<br />
| 19 / 837 (83.11 APS, 1658 PL)<br />
| 2.3%<br />
| cf.proto.Chiva 2.2<br />
| 61.5 -> 68.0<br />
| florent.XSeries.X2 0.17<br />
| 62.3 -> 56.7<br />
|-<br />
| 10.18.1<br />
| 16 / 837 (83.20 APS, 1656 PL)<br />
| 1.9%<br />
| jab.avk.ManuelGallegus 0.6<br />
| 70.4 -> 82.1<br />
| dft.Virgin 1.25<br />
| 73.6 -> 63.2<br />
|-<br />
| 10.22<br />
| 16 / 837 (83.59 APS, 1664 PL)<br />
| 1.9%<br />
| voidious.mini.Komarious 1.88<br />
| 54.4 -> 65.8<br />
| robar.micro.Topaz<br />
| 74.1 -> 65.5<br />
|-<br />
| 11.0<br />
| 10 / 840 (84.26 APS, 1668 PL)<br />
| 1.2%<br />
| florent.XSeries.X2 0.17<br />
| 58.6 -> 70.0<br />
| ary.micro.Weak 1.2<br />
| 68.1 -> 58.4<br />
|-<br />
| 11.3<br />
| 9 / 841 (84.41 APS, 1674 PL)<br />
| 1.1%<br />
| pez.micro.Aristocles 0.3.7<br />
| 67.6 -> 74.3<br />
| brainfade.Fallen 0.63<br />
| 70.5 -> 64.8<br />
|-<br />
| 11.4<br />
| 10 / 953 (84.92 APS, 1888 PL)<br />
| 1.1%<br />
| ags.micro.Carpet 1.1<br />
| 80.3 -> 85.1<br />
| abc.Shadow 3.83c<br />
| 54.9 -> 48.4<br />
|-<br />
| 11.5<br />
| 10 / 953 (84.94 APS, 92.52 S, 1890 PL)<br />
| 1.1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.6<br />
| 8 / 953 (85.14 APS, 92.73 S, 1890 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 11.16<br />
| 9 / 971 (85.21 APS, 92.97 S, 1928 PL)<br />
| < 1%<br />
| Unavailable<br />
|<br />
| Unavailable<br />
|<br />
|-<br />
| 12.0.1<br />
| 8-9 / 971 (85.54 APS, 93.38 S, 1934 PL)<br />
| < 1%<br />
| kc.serpent.Hydra 0.21<br />
| 60.4 -> 97.3<br />
| dsx724.VSAB_EP3a 1.0<br />
| 98.2 -> 77.4<br />
|-<br />
| 12.1<br />
| 7 / 972 (86.09 APS, 93.89 S, 1932 PL)<br />
| < 1%<br />
| ph.mini.Archer 0.6.6<br />
| 64.7 -> 98.5<br />
| cx.mini.Nimrod 0.55<br />
| 99.3 -> 69.9<br />
|-<br />
| 12.2*<br />
| 7 / 976 (86.36 APS, 94.00 S, 1942 PL)<br />
| < 1%<br />
| synapse.rsim.GeomancyBS 0.11<br />
| 40.0 -> 69.6<br />
| kc.serpent.Hydra 0.21<br />
| 99.4 -> 82.6<br />
|-<br />
| 12.3*<br />
| 6 / 980 (86.60 APS, 94.10 S, 1948 PL)<br />
| < 1%<br />
| davidalves.Firebird 0.25<br />
| 78.0 -> 97.6<br />
| sm.Devil 7.3<br />
| 79.4 -> 69.0<br />
|-<br />
| 12.4*<br />
| 6 / 980 (86.68 APS, 94.10 S)<br />
| < 1%<br />
| rc.yoda.Yoda 1.0.6c.fix<br />
| 71.0 -> 87.6<br />
| Legend.BoulderZY 1.4.9<br />
| 95.0 -> 69.5<br />
|-<br />
| 12.5**<br />
| 5 / 984 (87.19 APS, 94.72 S)<br />
| < 1%<br />
| simonton.mini.WeeksOnEnd 1.10.4<br />
| 57.8 -> 83.8<br />
| jf.Dodger<br />
| 96.9 -> 70.0<br />
|-<br />
| 12.6*<br />
| 5 / 982 (87.74 APS, 94.8 S)<br />
| < 1%<br />
| mladjo.Grrrrr 0.9<br />
| 68.5 -> 99.2<br />
| kid.Gladiator .7.2<br />
| 86.9 -> 58.8<br />
|}<br />
<br />
(*) Version 12.2+ scores are greatly affected by what clients run them. On some clients, a lot of skipped turns occur in the first round, typically causing the bullet shielding mode to fail. 12.3+ should be slightly better due to some CPU usage improvements, but the problem remains. Despite this, there was little effect on 12.3 - 12.6 due to who all was running clients at the time and possibly also due to the CPU usage improvements.<br />
<br />
(**) Version 12.5 score shown of 87.19 APS was on the Darkcanuck server. However, the rank was only 86.38 APS on the LiteRumble server. This was probably almost entirely due to the skipped turns anomaly of the clients, and gives an idea of how big a difference this anomaly can make.<br />
<br />
== Version CPU Usage ==<br />
<br />
All values are averages in milliseconds with the exception of those listed as '''Peak''' values, which are the maximum time in milliseconds encountered during a typical 35 round battle.<br />
<br />
{| border="1" cellpadding="4"<br />
!Version<br />
!Notes<br />
!Gun Avg/Tick<br />
!Gun Peak<br />
!Drive Avg/Tick<br />
!Drive Peak<br />
|-<br />
|6.5<br />
|Single wave surfing, single guess factor gun.<br />
|1.01<br />
|13.41, 8.77, 8.41, 7.15, 6.94<br />
|0.21<br />
|7.70, 7.61, 6.93, 6.93, 6.49<br />
|-<br />
|9.13<br />
|Multi-wave surfing, single guess factor gun.<br />
|0.301<br />
|6.23, 6.21, 5.82, 5.13, 4.74<br />
|0.775<br />
|22.52, 20.01, 16.26, 16.23, 15.94<br />
|-<br />
|9.14 / 10.0<br />
|Multi-wave surfing, gun array with 3 guess factor guns, Levy's KD Tree.<br />
|0.182<br />
|6.13, 6.07, 5.24, 4.05, 3.93<br />
|0.544<br />
|15.24, 14.55, 14.13, 13.91, 13.78<br />
|-<br />
|11.0<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, unoptimized Precise MEA on guns<br />
|0.978<br />
|140.3, 27.06, 21.98, 20.92, 17.43<br />
|0.558<br />
|21.34, 20.03, 18.62, 17.41, 15.32<br />
|-<br />
|11.3<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Levy's KD Tree, optimized Precise MEA on guns<br />
|0.631<br />
|12.79, 12.65, 9.98, 8.76, 8.68<br />
|0.543<br />
|19.16, 15.21, 14.57, 14.51, 14.40<br />
|-<br />
|11.4<br />
|Multi-wave surfing, gun array with 2 guess factor guns, Rednaxela's 3rd Gen KD Tree (w/ bucket size 64 and MaxHeap copied to List every search; might be better way to do this), optimized Precise MEA on guns<br />
|0.603<br />
|13.40, 9.15, 8.84, 8.76, 8.74<br />
|0.545<br />
|16.99, 15.04, 14.73, 14.39, 14.23<br />
|-<br />
|12.3<br />
|The same as 11.4, but with processing performance improvements. The biggest improvement made to the direct drive predictor. For more details, see version notes for 12.3.<br />
|0.267<br />
|5.23, 4.44, 3.77, 3.28, 2.98<br />
|0.299<br />
|7.34, 6.95, 6.81, 6.71, 6.60<br />
|}<br />
<br />
== Series Notes ==<br />
<br />
'''Series 1.x'''<br />
<br />
This series of robots was released while work on the Xander framework was still ongoing. Targeting and drive strategies were somewhat simple. No surfing or guess-factor targeting.<br />
<br />
'''Series 2.x'''<br />
<br />
This series introduced my earlist concept on guess factor targeting. Drive strategy was still simple.<br />
<br />
'''Series 3.x'''<br />
<br />
This series introduced wave surfing, and improvements to the guess factor gun. Version 3.0 used a modified version of the BasicGTSurfer wave surfing drive as a reference point, with all later versions in the line using a wave surfing drive of my own design. Towards the end of this line, I introduced virtual hit ratios, where all guns would provide aiming information for every shot to determine whether or not their aims would have hit the target or not.<br />
<br />
'''Series 4.x'''<br />
<br />
This series focused largely on drive improvements, including improvements to the wave surfing drive, dive protection, and a new ''Ram Escape'' drive. This series also improved how fire power is selected.<br />
<br />
'''Series 5.x'''<br />
<br />
This series focuses on using a new strategy for calculating factors in guess factor guns and wave surfing drives, surfing multiple waves simultaneously (explored by never implemented), paying more attention to robot width, improving wall avoidance, and improving segmentation selection and processing.<br />
<br />
'''Series 6.x'''<br />
<br />
XanderCat series 6 focuses on taking everything learned so far and evolving it into a new set of components, or at the very least, cleaning up old components or features that did not work out. Series 6 introduces the new ''Evolution Drive'', an updated Wave Surfing drive, and new ways of handling factor arrays. <br />
<br />
'''Series 7.x'''<br />
<br />
XanderCat series 7 uses the first release-ready version of the Xander framework. With the knowledge gained over prior versions of XanderCat, the Xander framework has undergone a final refactoring and cleanup and is now considered ready for public use. The Xander framework can be considered as version 1.0. In addition to using the finished Xander framework, series 7 may see updates to the main drive and gun, as well as a first release into the melee competition.<br />
<br />
'''Series 8.x'''<br />
<br />
This series will use my own take on using a K-nearest-neighbor (KNN) approach for the main drive and gun. It may also finally introduce surfing multiple waves at once. <br />
<br />
My KNN approach to to create a ''KNN Factor Array Processor'' that can be used in both drives and guns. I already have a '''FactorArrayProcessor''' interface built into my guess factor / wave surfing framework that it will utilize. However, instead of saving a large number of factor arrays and combining them, it will instead store a tree of data points, retrieve the closest data points to the current situation, and build a single factor array from those data points. One advantage of this approach is that is should allow for a greater number of segmenters and slices per segmenter.<br />
<br />
'''Series 9.x'''<br />
<br />
This series uses the updated Xander framework version 2.0. There are a variety of changes as a result. This series saw the first introduction of bullet shadows.<br />
<br />
'''Series 10.x'''<br />
<br />
The "Pro" series. This series switched to using a true KD Tree for drive and gun data. However, many of the versions in this series were just parameter adjustments. The only other major feature changes were to fix the buggy bullet shadows implementation introduced in series 9 and to begin (but not fully switch over to) the Xander Painting Framework.<br />
<br />
'''Series 11.x'''<br />
<br />
This series attempts to add some revised functionality in an attempt to break into the top 10, or at least get very close. This series will also see another round of code cleanup to reduce code size and fully utilize the Xander Painting Framework and Xander File Utility (removing any old code that the new frameworks can take over for).<br />
<br />
== Current Series Version Notes ==<br />
<br />
=== Version 12 ===<br />
<br />
In series 12, I was attempting to build some new surfing components, but I generally didn't have much success doing so. Therefore, I instead decided to go back to what I am good at -- multi-mode operation -- and added some new modes that should inflict a new round of pain on my unsuspecting foes.<br />
<br />
<b>New Features:</b><br />
<br />
<i>Xander Framework Updates</i><br />
<br />
* Segmenter interfaces cleaned up and updated to reflect modern usage. All segmenter implementation classes updated to use the new interfaces. This change was validated in 11.10 and did not affect APS (although it did slightly reduce code size and overhead).<br />
* Updated resources and related classes such that separate FactorIndexers can be used for self and opponent instead of a single FactorIndexer for both.<br />
* Fix bug in guess factor targeter class where some aim attempts could be ignored due to the failure to normalize the aim degrees. This caused occasional delays in firing.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Added new bullet shielding mode to the component chain. Feel the pain, boys! (poor Hydra)<br />
* Added new ramming mode to the component chain. This is only used in very limited circumstances -- when the opponent is at very low energy and has stopped firing. This adds insult to injury on opponents who are vulnerable to the new bullet shielding mode. (sorry, I can't help myself!)<br />
* Turned off auto-fire on disabled opponents in the configuration. XanderCat rams them now.<br />
* History size increased from default of 80 to 120 (the default history size was occasionally too small).<br />
* Fixed possible rare NPE bug in a couple of places where obtaining a robot history snapshot did not appropriately handle the rare case where a snapshot doesn't exist (one example where this can happen is a skipped turn resulting in missing a snapshot for self).<br />
* Updating drive data roll parameters, including the use of a new non-linear roll function to replace the previous linear function.<br />
<br />
==== Version 12.0.1 ====<br />
<br />
* Fixed bug in bullet shielding scenario so scenario will disengage if the opponent is not firing any bullets.<br />
<br />
=== Version 12.1 ===<br />
<br />
In this version, the bullet shielding components have been reworked to fix a number of problems. You can tell version 12.0.x is not operating at full potential by comparing it's results to another bullet shielder like BulletCatcher. I believe the new components, while still not perfect, are much improved.<br />
<br />
<i>Xander Framework Updates:</i><br />
* Add new AbstractGun class that implements Gun and handles the actual firing of bullets, leaving aiming up to subclasses. Changed XanderGun to extend AbstractGun. These changes make it easier to build guns when not utilizing XanderGun.<br />
<br />
<i>XanderCat Updates:</i><br />
* Change parameter for BulletShieldingScenario condition 1 so that scenario will activate immediately on start of round, rather than allowing 20 or so ticks for IdealPositionDrive to improve positioning. I'm still not sure which way is better. In my initial testing, it was a wash either way. If shielding right away, you can successfully shield against more opponents, but it takes away a little score from opponents who cannot be shielded against. I need a lot more testing to refine which way is better. For now, because it will be more interesting, I'm going with immediate shielding activation.<br />
* Change BulletShieldingScenario condition 3 to check for ((time - lastOpponentFireTime) < 250) instead of (opponentBulletsFired > 0). This condition is for handling opponents who are not firing bullets, and the change fixes it to work at any time in the battle instead of just checking the beginning of the first round. This fixes the survival anomaly against ad.last.Bottom, and could potentially apply to other opponents under various special conditions.<br />
* Change BulletShieldingScenario condition 7 to use opponent bullet power cutoff of 0.2 instead of 0.3.<br />
* Change BulletShieldingScenario condition 8 to use shielding shot cutoff of 20 shots instead of 10.<br />
* Change bullet shielding drive strategy to standing still when opponent is moving at the time they fire (as in previous version), but shifting position when opponent is standing still at the time they fire. (Why???? Why does it work this way???? Whatever.)<br />
* Fixed a couple of bugs related to using getDistanceRemaining() with bullet shielding control sequence. The only real impact with my current usage is that it prevents the possibility of a brief "runaway robot" when switching from some other scenario to the bullet shielding scenario.<br />
* BulletShieldingScenario now ensures that bullet shielding components are properly reset to initial condition when scenario is deactivated and then reactivated later.<br />
* Created new BulletShieldingGun (that extends the new AbstractGun). It replaces the BulletShieldingTargeter and BulletShieldingPowerSelector used previously. For bullet shielding, the aiming and power selection are too closely intertwined to continue using a separate targeter and power selector approach like I use for other guns.<br />
<br />
Some interesting shielding notes:<br />
* My shielding doesn't work against a few opponents, like Phoenix, but those same opponents can be shielded by other bullet shielders. Why? More research needed.<br />
* For a few opponents, shielding only works if the shielder stands still from the very beginning (note my change to shielding condition 1). Some examples of this include Engineer (definitely) and SniperFrog (I think). XanderCat 12.0.x will move to improve it's position in the first 20 ticks or so before stopping to try to shield. This apparently pollutes the data Engineer is collecting rendering shielding ineffective. More testing is needed to determine if it is better over the entire rumble to improve positioning as in XanderCat 12.0.x or to hold still, risking worse positioning against the greater field for the benefit of a few shielding vulnerable opponents like Engineer.<br />
* The new BulletShieldingGun (that extends AbstractGun) that I created can adjust fire power to try to hit opponent bullets at a time midpoint. However, if the required power adjustment exceeds a set threshold (currently 0.2), it just falls back to using power 0.1. In some initial testing, the power adjustment was only occurring on about 7% of shots. I don't expect this feature to provide a noticeable benefit, so I've opted to leave this function off for XanderCat version 12.1. I may throughly test it out for potential use in a later version however.<br />
<br />
=== Version 12.2 ===<br />
<br />
* Fixed bug where opponent wave too close test in the bullet shielding controller was failing to correctly report when opponent was too close. This bug is the main reason the previous version was losing to GeomancyBS, and was also hurting scores against other close fighting opponents.<br />
* Opponent too close test in the bullet shielding controller now factors in time remaining until gun cool when deciding if an opponent wave is too close to shield against. This allows us to get out of the way sooner of any shot that cannot be shielded against due to waiting on the gun to cool.<br />
* Increased required lead time for an opponent wave from 6 to 7 ticks.<br />
* Add condition to stop trying to bullet shield for the rest of the battle if the opponent is repeatedly not firing first (more than 3 consecutive times in the same round)<br />
* When opponent is under 8 energy remaining, required distance from opponent is increased by a set amount. This is intended to prevent being hit by low power shots that cannot be shielded against and that other scenarios will not have enough time to dodge.<br />
<br />
=== Version 12.3 ===<br />
<br />
This version focuses on enhancing/reducing CPU usage in hopes this will fix skipped turn issues and bullet shielding failures on some clients.<br />
<br />
* Moved some direct drive predictor function calls inline rather than calling methods on utility classes; this reduced function calls and reduced the number of objects created on some methods.<br />
* Updated direct drive predictor to perform fewer drive bounds .contains checks.<br />
* Updated direct drive predictor to cache trig values for last heading rather than recalculate every time a drive state is advanced.<br />
* Removed a few log statements that get ignored anyway. This removes a few unnecessary String creations.<br />
<br />
=== Version 12.4 ===<br />
<br />
* Fix bug where missed shielding shot can go unnoticed. This could potentially happen repeatedly causing loss of round. <br />
* Improve how lead time required for successful shielding is calculated. This improves shielding against close fighting opponents.<br />
* Assume firepower of 0.1 for opponent shots fired when their energy is less than 0.1. This seems to be how Robocode 1.7.3.x works.<br />
* Fix bug in linear intercept calculation where computed double value (one value minus another) is compared to zero. Due to imprecise doubles, the correct behavior it to compare to ''almost'' zero. This bug could result in the occasional firing of a bullet in a bizarre direction.<br />
* Fix bug where bullet shielding gun can get stuck (disabled) on a really low power bullet due to not being able to compute a linear intercept.<br />
<br />
=== Version 12.5 ===<br />
<br />
<i>Framework Updates</i><br />
<br />
* Add new checks of velocity and gun cool time to try to avoid registering an opponent wall hit as firing a bullet. <br />
* Bullet Shielding Gun updated to allow for multiple opponent targeting types.<br />
* Bullet Shielding Drive now moves only a tiny amount when moving to shield against a stationary opponent.<br />
<br />
<i>XanderCat Updates</i><br />
<br />
* Add secondary targeting type to the Bullet Shielding Gun. (same as is used in Spitfire)<br />
* Ideal Position Drive will now hold position instead of driving to center of battlefield when no opponents remain.<br />
* No longer ram disabled opponents when shielding.<br />
<br />
=== Version 12.6 ===<br />
<br />
<i>Rednaxela's KD Tree Update:</i><br />
<br />
* Updated Rednaxela's 3rd gen KD Tree so that the heaps returned from a search have methods to directly access the data and keys by index. This was done to support multiple iterations through the same data of a KD Tree search. Data accessed in this manner is not returned in order (I don't need it to be; I just need to be able to iterate through the data multiple times without having to re-execute the same search; this is handled by my CachingLogReader and is utilized when there are multiple guns or drives using the same KNN parameters).<br />
<br />
<i>Framework Updates:</i><br />
<br />
* Expanded auto fire on disabled opponents functionality such that conditions can be specified for when auto fire is allowed.<br />
* 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:<br />
** 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.<br />
** 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.<br />
* Saving the number of battles for each individual opponent and the total battles for all opponents to the battle statistics file is now a function of the framework. This data is only saved if the robot is saving other information to the battle statistics as well.<br />
* Robots can now have the framework save gun, drive, and radar run times to the battle statistics file using settings in the Configuration.<br />
* Added utility method to the BattleStats class to simplify saving averages to the battle statistics file.<br />
* Updated getActiveGunName() in AbstractXanderRobot to return the disabled robot gun name when the disabled robot gun is in use.<br />
* 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.<br />
<br />
<i>XanderCat Updates:</i><br />
<br />
* Revise generic KNN log reader to return a data iterator instead of a data point list. This should mostly eliminate the massive overhead of creating a List for each read when using Rednaxela's KD Tree in order to match the interface. This will also make data point KD Tree distance available on each point, something previously unavailable that could improve performance if used when filling the factor arrays.<br />
* Use KD Tree distance for each point to adjust the weight of data points in the constructed factor arrays. This is done for the drive only (affect had no statistical significance when tested on the guns).<br />
* Adjust KNN selection parameters on the drive from (1, 30, 0.3) to (10, 40, 0.4) where values are (minK, maxK, K growth rate)<br />
* Start recording drive and gun run time stats in the saved battle statistics file.<br />
* Auto-fire on disabled opponents turned back on, with condition that if the bullet shielding gun is active, there must be no active opponent waves. Ramming will now only be used on low energy opponents who have stopped firing but are not disabled.<br />
* Fix issue where shielding vulnerable opponents repeatedly get too close to shield against. This was fixed by switching to using a disengage distance and a re-engage distance, rather than a single required distance check. This keeps the bullet shielding scenario from bouncing on and off against opponents who keep nudging closer.<br />
* 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).<br />
* 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.<br />
<br />
=== Version 12.7 ===<br />
<br />
Work on this version was stalled for months but is underway again as of mid November, 2013. Probable release in late November.<br />
<br />
This version focuses on managing garbage collection. The amount of garbage collection going on is causing lots of skipped turns on some clients in the first round, which is seriously compromising the effectiveness of my shielding components.<br />
<br />
* Create and utilize new mechanism for managing garbage (particularly in the first round). Current strategy is to use a new "waste basket" to hold onto old objects and delay garbage collection until non-critical times (object pooling was another strategy considered but is not favored at this time). This occurs until round 3.<br />
* Initial objects selected for management include Snapshots and Waves. This was calculated out to be about 2000 objects per round that are thrown away and garbage collected.<br />
* Add new condition for bullet shielding scenario to handle situations where shielding is not sufficiently effective on a round (shielding will shut off for current round only under this condition). This should fix a shielding vulnerability that was occurring against certain mirror bots from suh (the problem turned out not to be with the anti-mirror components, but rather with the bullet shielding components).<br />
<br />
=== Version 12.8 (Planned) ===<br />
<br />
The attempt to fix the garbage collection problem using the "waste basket" approach in version 12.7 was a failure. I can tell this pretty easily by comparing XanderCat against Spitfire. Therefore, version 12.8 will take a new approach to fixing the problem. Possibilities include:<br />
* Going back to an object pooling approach.<br />
* Using a backing array (hidden as much as possible) for frequently constructed and thrown away objects like snapshots (in 1v1, 2 snapshots are created on every tick, and usually 2 are thrown away every tick as well).<br />
<br />
=== Future Version Possibilities ===<br />
<br />
<b>Possible Features</b><br />
<br />
* Update gun data roll procedure.<br />
* New drive system for wave surfing? This was tested and so far has not proved advantageous, so the likelyhood of it making it into the final version is dropping.<br />
* Add 2 new segmenters to the guns.<br />
* Possibly update how danger is modified based on distance.<br />
* Figure out how to pummel PrairieWolf.<br />
* Add tracking of certain types of "errors" to help with improvements (for example, keep and report on a count of how often the robot runs into walls, or fails to reach it's intended location)<br />
* Modify segmenters?<br />
* For logged battle stats against each opponent, instead of keeping a single average for stat values, keep two sets of stat values: one for the best battle against them, one for the worst battle against them.<br />
* Segmenter changes? (possibly a new type of segmenter)<br />
* Try out a "performance-based distancing equation"?<br />
* Implement several speed improvements?<br />
* Maybe tweak some other parameters?<br />
* Improve bullet shielding protection?</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:LiteRumble/Better_Priority_Battles/reply_(7)&diff=32259Thread:Talk:LiteRumble/Better Priority Battles/reply (7)2013-11-18T17:02:31Z<p>Skotty: Reply to Better Priority Battles</p>
<hr />
<div>eem.EvBot v4.4.5, xander.cat.XanderCat 12.7, zezinho.QuerMePegarKKKK 1.0, EH.nano.NightBird M. EvBot was the most recent release. My client was running quite a few battles for EvBot initially (when it only had about 400 pairings) but when it got up to the 900's, suddenly it was just running random pairings of all bots despite the 4 being short roughtly 150 pairings each. It appears as though all 4 of those bots are now getting priority again, as they have each picked up at least 50 pairings since this morning.</div>Skottyhttp://robowiki.net/w/index.php?title=Thread:Talk:LiteRumble/Better_Priority_Battles/reply_(4)&diff=32252Thread:Talk:LiteRumble/Better Priority Battles/reply (4)2013-11-18T13:39:38Z<p>Skotty: Reply to Better Priority Battles</p>
<hr />
<div>I've noticed that there are currently 4 bots in the roborumble which seem sort of stuck at around 950 pairings. I'm running my client, and it appears to just be running random pairings; it's not running pairings for any of those 4 bots. I do have a number of bots that my client won't run due to the "major.minor" version issue, but it's only about 30 bots, and there are will over 100 pairings missing from each of the 4 bots without full pairings, so that doesn't quite explain it. Might be worth looking into.</div>Skotty