Difference between revisions of "Yatagan/Source"

From Robowiki
Jump to navigation Jump to search
 
(54 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
== Development Version ==
 
== Development Version ==
 
+
Codesize: 249
<syntaxhighlight>
+
<syntaxhighlight lang="Java">
 
/*
 
/*
Yatagan 1.0.3 by Sheldor & Skilgannon; Release date:  3-21-2013
+
Yatagan 1.2.3 by Sheldor & Skilgannon; Release date:  2013/06/13
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
Codesize:  247 bytes;  Code size class:  NanoBot
+
Codesize:  249 bytes without any colors
 
   
 
   
 
Credits:  
 
Credits:  
Line 11: Line 11:
 
And a general thanks to all open source bot authors and contributors to the RoboWiki.
 
And a general thanks to all open source bot authors and contributors to the RoboWiki.
 
   
 
   
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1
+
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
see license here: http://robowiki.net/wiki/RWPCL
+
See license here: http://robowiki.net/wiki/RWPCL
 
*/
 
*/
 
   
 
   
package sheldor.jk;
+
package jk.sheldor.nano;
 
   
 
   
 
import robocode.*;
 
import robocode.*;
 
import robocode.util.Utils;
 
import robocode.util.Utils;
 
   
 
   
public class Yatagan extends AdvancedRobot
+
public class Yatagan extends AdvancedRobot{
{
 
//Global variables.
 
  static double direction;
 
  static double enemyEnergy;
 
 
   
 
   
   static int deathCount;
+
   public static final double DESIRED_BULLET_POWER = 2.0;
 
 
  public void run()
 
  {
 
      //setAdjustGunForRobotTurn(true);
 
 
 
  //Start spinning radar and initialize direction to infinity.
 
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
  }
 
 
   
 
   
  public void onScannedRobot(ScannedRobotEvent e)
+
   //round to nearest multiple of 0.33333...
  {
+
  public static final int BULLET_POWER = 2;//(int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
   //Local variables.
+
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
      int integer = 30;
 
      double absoluteBearing;
 
      double distance;
 
      int matchPosition;
 
 
 
      //Watch for a drop in the enemy's energy between 0 and 3.  Thanks to Miked0801 for his awesome char trick.
 
      if( (char) ((enemyEnergy - 1.09999  - (enemyEnergy = e.getEnergy()))) <= 1)
 
      {
 
        //One-way/Oscillating/Random movement.
 
        direction *= (chancesOfReversing.charAt(deathCount) - 2*Math.random());
 
      }
 
      setAhead(direction);
 
 
 
  //Stay mostly perpendicular to the enemy, but try to maintain a distance of 220 pixels.
 
      setTurnRightRadians(Math.cos(absoluteBearing = e.getBearingRadians()) + ((220.0 - (distance = e.getDistance())) * (getVelocity() *4e-4)));
 
 
 
  //Pattern Matching.
 
      enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing += getHeadingRadians()))))).concat(enemyHistory);
 
 
 
  // search for a match
 
      while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
 
    
 
      integer = (int)(distance);
 
  // calculate aim offset
 
     
 
      do {
 
        absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  distance;
 
      } while ((integer -= 12) > 0);
 
 
 
  //Aim at the predicted target.
 
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
 
 
 
      //Fire!
 
      //The bullet power must be a multiple of .3333333333333333333333...
 
      setFire(2.666666666666666666666666666666666666666666666666666666);
 
 
 
  //Infinite radar lock.
 
      setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
 
  }
 
 
   
 
   
  public void onDeath(DeathEvent e)
+
//Skilgannon: make this odd otherwise we can get errors in the beginning when a match of length 2 isn't found.
  {
+
  public static final int MAX_MATCH_LENGTH = 40; //Keep this under 128 to save a byte.
      //Move to the next cell in the table every time the bot dies.
 
      deathCount++;
 
  }
 
 
   
 
   
   public void onHitWall(HitWallEvent e)
+
   public static final int ORBIT_DISTANCE = 220;
  {
+
   //public static final double MOVE_AMOUNT = 1e+200;
   //Reverse direction when the bot hits a wall.
+
   public static final double DISTANCE_FACTOR = 3000;
      direction = -direction;
 
   }
 
 
   
 
   
  //The chance that the bot will reverse orbit direction when the enemy fires.
+
  public static final int ANTI_RAMBOT_DISTANCE = 127; //Keep this under 128 to save a byte.
//Since this is an unchanging table, we can save a few bytes by using "final."
 
  private static final String chancesOfReversing = ""
 
  + (char) 2 + (char) 0 + (char) 2 + (char) 0
 
  + (char) 2 + (char) 0 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1;
 
 
   
 
   
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
+
//NB! Generate new RANDOM when changing ORBIT_DISTANCE!
  static String enemyHistory = ""
+
/*public static void main(String[] args){
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
System.out.println("RANDOM = " + (int)Math.round(3.0/(0.6*Math.sqrt((20 - 3*2.5)/ORBIT_DISTANCE) - 0.04)));
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
}//*/
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 2
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char)-2 + (char)-4 + (char)-6
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-7 + (char)-6 + (char)-5 + (char)-4
 
  + (char)-3 + (char)-2 + (char)-1 + (char)1
 
  + (char) 2 + (char) 4 + (char) 6 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 7 + (char) 6 + (char) 5 + (char) 4
 
  + (char) 3 + (char) 2 + (char) 1 + (char) 1;
 
}
 
 
 
</syntaxhighlight>
 
 
 
== Version 1.0.2 ==
 
 
 
<syntaxhighlight>
 
/*
 
Yatagan 1.0.2 by Sheldor & Skilgannon
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
 
 
   
 
   
Credits:  
+
  //public static final char ONE_WAY_ORBIT = 65535;
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified,
+
  //public static final char REVERSE_ON_ENEMY_FIRE = 0;
and a general thanks to all open source bot authors and contributors to the RoboWiki.
+
  //public static final char RANDOM = 29; //SHELDOR: This is no longer flat, but it works better against PM.
 
   
 
   
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1
+
  public static final char NO_FLIP = 65535;
see license here: http://robowiki.net/wiki/RWPCL
+
  public static final char FLIP = 0;
*/
+
  public static final char RANDOM_FLIP = 10;
 
   
 
   
package sheldor.jk;
+
  //Global Variables
 
import robocode.*;
 
import robocode.util.Utils;
 
 
public class Yatagan extends AdvancedRobot
 
{
 
//Global variables.
 
 
   static double direction;
 
   static double direction;
 
   static double enemyEnergy;
 
   static double enemyEnergy;
 
   
 
   
   static int deathCount;
+
   static int deathCount;
 
   
 
   
//En garde!
 
 
   public void run()
 
   public void run()
 
   {
 
   {
       //setAdjustGunForRobotTurn(true);
+
       //Skilgannon: sacrifice this for anti-rambot code
 +
    //SHELDOR:  Now we have enough room for both!
 +
      setAdjustRadarForGunTurn(true);
 
    
 
    
  //Start spinning radar and initialize direction to infinity.
+
      //start spinning radar and initialize direction
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
   }
 
   }
Line 288: Line 68:
 
   public void onScannedRobot(ScannedRobotEvent e)
 
   public void onScannedRobot(ScannedRobotEvent e)
 
   {
 
   {
  //Local variables.
+
      //Local Variables
       int integer = 30;
+
       int integer = MAX_MATCH_LENGTH;
 
       double absoluteBearing;
 
       double absoluteBearing;
      double distance;
 
 
       int matchPosition;
 
       int matchPosition;
 
    
 
    
   //Oscillating/Random movement.
+
    //SHELDOR:  Debugging Tools
       if( (char) ((enemyEnergy - 1.09999  - (enemyEnergy = e.getEnergy()))) <= 1)
+
  //System.out.println(enemyEnergy - e.getEnergy());
 +
  //System.out.println(deathCount);
 +
  //System.out.println((deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
 +
  //System.out.println((int)chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
 +
  //System.out.println(((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (e.getEnergy())))) * Math.random()) - 1));
 +
    
 +
      //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with
 +
      setAhead(direction *= ((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (enemyEnergy = e.getEnergy())))) * Math.random()) - 1));
 +
       /*if(
 +
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random()
 +
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
 
       {
 
       {
         direction *= (chancesOfReversing.charAt(deathCount) - 2*Math.random());
+
         //Reverse direction.
 +
        //Calling the onHitWall event to reverse direction saves two bytes.  Credit to Simonton.
 +
        onHitWall(null);
 
       }
 
       }
       setAhead(direction);
+
       setAhead(direction);*/ 
 
    
 
    
  //Stay perpendicular to the enemy.
+
      //record the current enemy lateral velocity
       setTurnRightRadians(Math.cos(absoluteBearing = e.getBearingRadians()) + ((160.0 - (distance = e.getDistance())) * (getVelocity() *4e-4)));
+
       enemyHistory = String.valueOf((char) Math.round(e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);  
 
    
 
    
  //Pattern Matching.
+
      //Pattern Matching
       enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing += getHeadingRadians()))))).concat(enemyHistory);
+
       //find the longest match in the enemy history
 +
      do{}while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, (--integer)), 64)) < 0);
 
    
 
    
  // search for a match
+
      //stay mostly perpendicular to the enemy, but try to maintain a distance of ORBIT_DISTANCE pixels
       while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
+
      //If DISTANCE_FACTOR is smaller it tries harder to get to the desired distance, but may 'SpinBot' if it is too small.
 +
       setTurnRightRadians(Math.cos(e.getBearingRadians() +
 +
        ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / DISTANCE_FACTOR/*direction  / DISTANCE_FACTOR*/))
 +
        ));
 
    
 
    
       integer = (int)(distance);
+
       //fire BULLET_POWER power bullets most of the time, but use higher power bullets when the distance is less than ANTI_RAMBOT_DISTANCE
   // calculate aim offset
+
      //This greatly improves scores against rambots and other extremely aggressive bots.
        
+
      setFire(BULLET_POWER + (ANTI_RAMBOT_DISTANCE / integer));
 +
    
 +
      //assume that the enemy will repeat their movements in the ticks following the recording of the original pattern
 +
       //generate a firing angle based on that assumption
 
       do {  
 
       do {  
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  distance;
+
        //go through the log of enemy movements right after the original pattern was recorded
       } while ((integer -= 12) > 0);
+
        //add the Angular Velocities directly to the absoluteBearing variable
 
+
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
  //Aim at the predicted target.
+
       }
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
+
      while ((integer -= BULLET_VELOCITY) > 0); //keep projecting the enemy's movement forward until our bullet would reach their predicted location
 
    
 
    
  //Fire!
+
      //aim at the predicted target
       setFire(2.6666666666666);
+
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));    
 
    
 
    
  //Infinite radar lock.
+
      //Pseudo-infinite Radar Lock
       setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
+
       setTurnRadarLeftRadians(getRadarTurnRemaining());
 
   }
 
   }
 
   
 
   
 
   public void onDeath(DeathEvent e)
 
   public void onDeath(DeathEvent e)
 
   {
 
   {
       deathCount++;
+
       //when the bot dies, move to the next cell in the table
 +
      deathCount += 127;
 +
      //deathCount++;
 
   }
 
   }
 
   
 
   
 
   public void onHitWall(HitWallEvent e)
 
   public void onHitWall(HitWallEvent e)
 
   {
 
   {
  //Reverse direction when the bot hits a wall.
+
      //reverse movement direction when the bot hits a wall
 
       direction = -direction;
 
       direction = -direction;
 
   }
 
   }
 
   
 
   
  //chance out of 3 for given number of deaths, 'final' saves a few bytes
+
   
  private static final String chancesOfReversing = ""
+
  + (char) 2 + (char) 0 + (char) 2 + (char) 0
+
  + (char) 2 + (char) 0 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1;
 
 
   
 
   
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
 +
//Skilgannon - this didn't need to be quite as long as it was, only max bullet flight time + one of each possible character
 +
//unless we want to try pre-loading some common movement patterns?
 
   static String enemyHistory = ""
 
   static String enemyHistory = ""
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 1  
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char)-1 + (char)-2 + (char)-3 + (char)-4 + (char)-5 + (char)-6
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  ;
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   public static final String ONE_WAY_ORBIT = "" +  
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 2
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +    
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP;
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  //SHELDOR:  Because this will be part of a larger string, we should start from 1 instead of 0.
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   public static final String REVERSE_ON_ENEMY_FIRE = "" +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char)-2 + (char)-4 + (char)-6
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      FLIP   + FLIP    + FLIP    + NO_FLIP + NO_FLIP +
   + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP;
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
   public static final String RANDOM = "" +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-7 + (char)-6 + (char)-5 + (char)-4
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-3 + (char)-2 + (char)-1 + (char)1
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 2 + (char) 4 + (char) 6 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
   + (char) 7 + (char) 6 + (char) 5 + (char) 4
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
   + (char) 3 + (char) 2 + (char) 1 + (char) 1;
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP;
 +
 +
//The chance that Yatagan will reverse direction when the enemy fires.
 +
//values are referenced by number of deaths experienced
 +
//when chancesOfReversing is 0, reverse on enemy fire only
 +
//when chancesOfReversing is very large, almost never reverse (unless Math.random() is very small)
 +
//when chancesOfReversing is > 3, reverse with probability 3/chancesOfReversing
 +
  private static final String chancesOfReversing = ""
 +
  + NO_FLIP
 +
   + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT //SHELDOR:  Let's try oscillating movement first.
 +
  + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE
 +
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  ;
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Version 1.0.1 ==
+
== Latest Released Version (1.2.3) ==
  
 
<syntaxhighlight>
 
<syntaxhighlight>
 
 
/*
 
/*
Yatagan 1.0.1 by Sheldor & Skilgannon
+
Yatagan 1.2.3 by Sheldor & Skilgannon;  Release date:  2013/06/13
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
 +
Codesize:  249 bytes without any colors
 
   
 
   
 
Credits:  
 
Credits:  
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified,
+
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified.
and a general thanks to all open source bot authors and contributors to the RoboWiki.
+
And a general thanks to all open source bot authors and contributors to the RoboWiki.
 
   
 
   
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1
+
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
see license here: http://robowiki.net/wiki/RWPCL
+
See license here: http://robowiki.net/wiki/RWPCL
 
*/
 
*/
 
   
 
   
package sheldor.jk;
+
package jk.sheldor.nano;
 
   
 
   
 
import robocode.*;
 
import robocode.*;
 
import robocode.util.Utils;
 
import robocode.util.Utils;
 
   
 
   
public class Yatagan extends AdvancedRobot
+
public class Yatagan extends AdvancedRobot{
{
 
//Global variables.
 
  static double direction;
 
  static double enemyEnergy;
 
 
   
 
   
   static int deathCount;
+
   public static final double DESIRED_BULLET_POWER = 2.0;
 
   
 
   
//En garde!
+
  //round to nearest multiple of 0.33333...
   public void run()
+
   public static final int BULLET_POWER = 2;//(int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
  {
+
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
      //setAdjustGunForRobotTurn(true);
 
    
 
  //Start spinning radar and initialize direction to infinity.
 
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
  }
 
 
   
 
   
  public void onScannedRobot(ScannedRobotEvent e)
+
  //Skilgannon: make this odd otherwise we can get errors in the beginning when a match of length 2 isn't found.
  {
+
   public static final int MAX_MATCH_LENGTH = 40;  //Keep this under 128 to save a byte.
  //Local variables.
 
      int integer = 30;
 
      double absoluteBearing;
 
      double distance;
 
      int matchPosition;
 
 
 
  //Oscillating/Random movement.
 
      if( (char) ((enemyEnergy - 1 - (enemyEnergy = e.getEnergy()))) <= 1)
 
      {
 
        direction *= (chancesOfReversing.charAt(deathCount) - 2*Math.random());
 
      }
 
      setAhead(direction);
 
 
 
  //Stay perpendicular to the enemy.
 
      setTurnRightRadians(Math.cos(absoluteBearing = e.getBearingRadians()) + ((160.0 - (distance = e.getDistance())) * (getVelocity() *4e-4)));
 
 
 
  //Pattern Matching.
 
      enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing += getHeadingRadians()))))).concat(enemyHistory);
 
 
 
  // search for a match
 
      while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
 
    
 
      integer = (int)(distance);
 
  // calculate aim offset
 
     
 
      do {
 
        absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) / distance;
 
      } while ((integer -= 12) > 0);
 
 
 
  //Aim at the predicted target.
 
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
 
 
 
  //Fire!
 
      setFire(2.6666666666666);
 
 
 
  //Infinite radar lock.
 
      setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
 
  }
 
 
   
 
   
   public void onDeath(DeathEvent e)
+
   public static final int ORBIT_DISTANCE = 220;
  {
+
   //public static final double MOVE_AMOUNT = 1e+200;
      deathCount++;
+
   public static final double DISTANCE_FACTOR = 3000;
  }
 
 
  public void onHitWall(HitWallEvent e)
 
  {
 
  //Reverse direction when the bot hits a wall.
 
      direction = -direction;
 
   }
 
 
//chance out of 3 for given number of deaths, 'final' saves a few bytes
 
  private static final String chancesOfReversing = ""
 
  + (char) 2 + (char) 0 + (char) 2 + (char) 0
 
  + (char) 2 + (char) 0 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1;
 
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
 
   static String enemyHistory = ""
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 2
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char)-2 + (char)-4 + (char)-6
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
 
  + (char)-7 + (char)-6 + (char)-5 + (char)-4
 
  + (char)-3 + (char)-2 + (char)-1 + (char)1
 
  + (char) 2 + (char) 4 + (char) 6 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
 
  + (char) 7 + (char) 6 + (char) 5 + (char) 4
 
  + (char) 3 + (char) 2 + (char) 1 + (char) 1;
 
}
 
 
 
</syntaxhighlight>
 
 
 
== Version 1.0.0 ==
 
 
 
<syntaxhighlight>
 
/*
 
Yatagan 1.0.0 by Sheldor & Skilgannon
 
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
 
 
   
 
   
Credits:
+
  public static final int ANTI_RAMBOT_DISTANCE = 127;  //Keep this under 128 to save a byte.
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified,
 
and a general thanks to all open source bot authors and contributors to the RoboWiki.
 
 
   
 
   
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1
+
//NB! Generate new RANDOM when changing ORBIT_DISTANCE!
see license here: http://robowiki.net/wiki/RWPCL
+
/*public static void main(String[] args){
*/
+
System.out.println("RANDOM = " + (int)Math.round(3.0/(0.6*Math.sqrt((20 - 3*2.5)/ORBIT_DISTANCE) - 0.04)));
 +
}//*/
 
   
 
   
package sheldor.jk;
+
  //public static final char ONE_WAY_ORBIT = 65535;
 +
  //public static final char REVERSE_ON_ENEMY_FIRE = 0;
 +
  //public static final char RANDOM = 29; //SHELDOR: This is no longer flat, but it works better against PM.
 
   
 
   
import robocode.*;
+
  public static final char NO_FLIP = 65535;
import robocode.util.Utils;
+
  public static final char FLIP = 0;
 +
  public static final char RANDOM_FLIP = 10;
 
   
 
   
public class Yatagan extends AdvancedRobot
+
  //Global Variables
{
 
//Global variables.
 
 
   static double direction;
 
   static double direction;
 
   static double enemyEnergy;
 
   static double enemyEnergy;
 
   
 
   
   static int deathCount;
+
   static int deathCount;
 
   
 
   
//En garde!
 
 
   public void run()
 
   public void run()
 
   {
 
   {
     // setAdjustGunForRobotTurn(true);
+
      //Skilgannon: sacrifice this for anti-rambot code
 
+
     //SHELDOR:  Now we have enough room for both!
  //Start spinning radar and initialize direction to infinity.
+
      setAdjustRadarForGunTurn(true);
 +
 +
      //start spinning radar and initialize direction
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
   }
 
   }
Line 781: Line 361:
 
   public void onScannedRobot(ScannedRobotEvent e)
 
   public void onScannedRobot(ScannedRobotEvent e)
 
   {
 
   {
  //Local variables.
+
      //Local Variables
       int integer = 30;
+
       int integer = MAX_MATCH_LENGTH;
 
       double absoluteBearing;
 
       double absoluteBearing;
      double distance;
 
 
       int matchPosition;
 
       int matchPosition;
    
+
   //Oscillating/Random movement.
+
    //SHELDOR:  Debugging Tools
       if( (char) ((enemyEnergy - 1.0999  - (enemyEnergy = e.getEnergy()))) < 2)
+
   //System.out.println(enemyEnergy - e.getEnergy());
 +
   //System.out.println(deathCount);
 +
  //System.out.println((deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
 +
  //System.out.println((int)chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
 +
  //System.out.println(((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (e.getEnergy())))) * Math.random()) - 1));
 +
 +
      //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with
 +
      setAhead(direction *= ((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (enemyEnergy = e.getEnergy())))) * Math.random()) - 1));
 +
       /*if(
 +
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random()
 +
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
 
       {
 
       {
         direction *= (chancesOfReversing.charAt(deathCount) - 3*Math.random());
+
         //Reverse direction.
 +
        //Calling the onHitWall event to reverse direction saves two bytes.  Credit to Simonton.
 +
        onHitWall(null);
 
       }
 
       }
       setAhead(direction);
+
       setAhead(direction);*/ 
 
+
  //Stay perpendicular to the enemy.
+
      //record the current enemy lateral velocity
      setTurnRightRadians(Math.cos(absoluteBearing = e.getBearingRadians()) + ((160.0 - (distance = e.getDistance())) * (getVelocity() *4e-4)));
+
       enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);  
 
+
  //Pattern Matching.
+
      //Pattern Matching
       enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing += getHeadingRadians()))))).concat(enemyHistory);
+
      //find the longest match in the enemy history
 
+
       while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, (--integer)), 64)) < 0);
  // search for a match
+
       while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
+
       //stay mostly perpendicular to the enemy, but try to maintain a distance of ORBIT_DISTANCE pixels
 
+
      //If DISTANCE_FACTOR is smaller it tries harder to get to the desired distance, but may 'SpinBot' if it is too small.
       integer = (int)(distance);
+
      setTurnRightRadians(Math.cos(e.getBearingRadians() +
  // calculate aim offset
+
        ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / DISTANCE_FACTOR/*direction  / DISTANCE_FACTOR*/))
        
+
        ));
 +
 +
      //fire BULLET_POWER power bullets most of the time, but use higher power bullets when the distance is less than ANTI_RAMBOT_DISTANCE
 +
      //This greatly improves scores against rambots and other extremely aggressive bots.
 +
      setFire(BULLET_POWER + (ANTI_RAMBOT_DISTANCE / integer));
 +
 +
      //assume that the enemy will repeat their movements in the ticks following the recording of the original pattern
 +
       //generate a firing angle based on that assumption
 
       do {  
 
       do {  
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  distance;
+
        //go through the log of enemy movements right after the original pattern was recorded
       } while ((integer -= 12) > 0);
+
        //add the Angular Velocities directly to the absoluteBearing variable
 
+
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
  //Aim at the predicted target.
+
       }
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
+
      while ((integer -= BULLET_VELOCITY) > 0); //keep projecting the enemy's movement forward until our bullet would reach their predicted location
 
+
  //Fire!
+
      //aim at the predicted target
       setFire(2.6666666666666666666666666666);
+
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));    
 
+
  //Infinite radar lock.
+
       //Pseudo-infinite Radar Lock
       setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
+
       setTurnRadarLeftRadians(getRadarTurnRemaining());
 
   }
 
   }
 
   
 
   
 
   public void onDeath(DeathEvent e)
 
   public void onDeath(DeathEvent e)
 
   {
 
   {
       deathCount++;
+
       //when the bot dies, move to the next cell in the table
 +
      deathCount += 127;
 +
      //deathCount++;
 
   }
 
   }
 
   
 
   
 
   public void onHitWall(HitWallEvent e)
 
   public void onHitWall(HitWallEvent e)
 
   {
 
   {
  //Reverse direction when the bot hits a wall.
+
      //reverse movement direction when the bot hits a wall
 
       direction = -direction;
 
       direction = -direction;
 
   }
 
   }
 
   
 
   
  //chance out of 3 for given number of deaths, 'final' saves a few bytes
+
   
  private static final String chancesOfReversing = ""
+
  + (char) 3 + (char) 0 + (char) 3 + (char) 0
+
  + (char) 3 + (char) 0 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1;
 
 
   
 
   
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
 +
//Skilgannon - this didn't need to be quite as long as it was, only max bullet flight time + one of each possible character
 +
//unless we want to try pre-loading some common movement patterns?
 
   static String enemyHistory = ""
 
   static String enemyHistory = ""
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 1  
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char)-1 + (char)-2 + (char)-3 + (char)-4 + (char)-5 + (char)-6
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  ;
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   public static final String ONE_WAY_ORBIT = "" +  
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 2
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +    
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP;
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
  //SHELDOR:  Because this will be part of a larger string, we should start from 1 instead of 0.
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
   public static final String REVERSE_ON_ENEMY_FIRE = "" +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char) 1 + (char)-2 + (char)-4 + (char)-6
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      FLIP   + FLIP    + FLIP    + NO_FLIP + NO_FLIP +
   + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      NO_FLIP + NO_FLIP;
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
   public static final String RANDOM = "" +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-8 + (char)-8 + (char)-8 + (char)-8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-7 + (char)-6 + (char)-5 + (char)-4
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char)-3 + (char)-2 + (char)-1 + (char)1
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 2 + (char) 4 + (char) 6 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
  + (char) 8 + (char) 8 + (char) 8 + (char) 8
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
   + (char) 7 + (char) 6 + (char) 5 + (char) 4
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
   + (char) 3 + (char) 2 + (char) 1 + (char) 1;
+
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
 +
      RANDOM_FLIP + RANDOM_FLIP;
 +
 +
//The chance that Yatagan will reverse direction when the enemy fires.
 +
//values are referenced by number of deaths experienced
 +
//when chancesOfReversing is 0, reverse on enemy fire only
 +
//when chancesOfReversing is very large, almost never reverse (unless Math.random() is very small)
 +
//when chancesOfReversing is > 3, reverse with probability 3/chancesOfReversing
 +
  private static final String chancesOfReversing = ""
 +
  + NO_FLIP
 +
   + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT //SHELDOR:  Let's try oscillating movement first.
 +
  + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE
 +
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
 +
  ;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 23:18, 2 October 2024

Development Version

Codesize: 249

/*
Yatagan 1.2.3 by Sheldor & Skilgannon;  Release date:  2013/06/13
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
Codesize:  249 bytes without any colors
 
Credits: 
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified.
And a general thanks to all open source bot authors and contributors to the RoboWiki.
 
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
See license here: http://robowiki.net/wiki/RWPCL
*/
 
package jk.sheldor.nano;
 
import robocode.*;
import robocode.util.Utils;
 
public class Yatagan extends AdvancedRobot{
 
   public static final double DESIRED_BULLET_POWER = 2.0;
 
   //round to nearest multiple of 0.33333...
   public static final int BULLET_POWER = 2;//(int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
 
 //Skilgannon: make this odd otherwise we can get errors in the beginning when a match of length 2 isn't found.
   public static final int MAX_MATCH_LENGTH = 40;  //Keep this under 128 to save a byte.
 
   public static final int ORBIT_DISTANCE = 220;
   //public static final double MOVE_AMOUNT = 1e+200;
   public static final double DISTANCE_FACTOR = 3000;
 
   public static final int ANTI_RAMBOT_DISTANCE = 127;  //Keep this under 128 to save a byte.
 
//NB! Generate new RANDOM when changing ORBIT_DISTANCE! 
/*public static void main(String[] args){
System.out.println("RANDOM = " + (int)Math.round(3.0/(0.6*Math.sqrt((20 - 3*2.5)/ORBIT_DISTANCE) - 0.04)));
}//*/
 
   //public static final char ONE_WAY_ORBIT = 65535;
   //public static final char REVERSE_ON_ENEMY_FIRE = 0;
   //public static final char RANDOM = 29; //SHELDOR: This is no longer flat, but it works better against PM.
 
   public static final char NO_FLIP = 65535;
   public static final char FLIP = 0;
   public static final char RANDOM_FLIP = 10;
 
   //Global Variables
   static double direction;
   static double enemyEnergy;
 
   static int deathCount;
 
   public void run()
   {
      //Skilgannon: sacrifice this for anti-rambot code
     //SHELDOR:  Now we have enough room for both!
      setAdjustRadarForGunTurn(true);
   
      //start spinning radar and initialize direction
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
   }
 
   public void onScannedRobot(ScannedRobotEvent e)
   {
      //Local Variables
      int integer = MAX_MATCH_LENGTH;
      double absoluteBearing;
      int matchPosition;
   
    //SHELDOR:  Debugging Tools
   //System.out.println(enemyEnergy - e.getEnergy());
   //System.out.println(deathCount);
   //System.out.println((deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
   //System.out.println((int)chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
   //System.out.println(((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (e.getEnergy())))) * Math.random()) - 1));
   
      //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with
      setAhead(direction *= ((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (enemyEnergy = e.getEnergy())))) * Math.random()) - 1));
      /*if(
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random() 
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
      {
         //Reverse direction.
         //Calling the onHitWall event to reverse direction saves two bytes.  Credit to Simonton.
         onHitWall(null);
      }		
      setAhead(direction);*/   
   
      //record the current enemy lateral velocity
      enemyHistory = String.valueOf((char) Math.round(e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);   
   
      //Pattern Matching
      //find the longest match in the enemy history
      do{}while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, (--integer)), 64)) < 0);
   
      //stay mostly perpendicular to the enemy, but try to maintain a distance of ORBIT_DISTANCE pixels
      //If DISTANCE_FACTOR is smaller it tries harder to get to the desired distance, but may 'SpinBot' if it is too small.
      setTurnRightRadians(Math.cos(e.getBearingRadians() + 
         ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / DISTANCE_FACTOR/*direction  / DISTANCE_FACTOR*/))
         ));
   
      //fire BULLET_POWER power bullets most of the time, but use higher power bullets when the distance is less than ANTI_RAMBOT_DISTANCE
      //This greatly improves scores against rambots and other extremely aggressive bots.
      setFire(BULLET_POWER + (ANTI_RAMBOT_DISTANCE / integer));
   
      //assume that the enemy will repeat their movements in the ticks following the recording of the original pattern
      //generate a firing angle based on that assumption 
      do { 
         //go through the log of enemy movements right after the original pattern was recorded
         //add the Angular Velocities directly to the absoluteBearing variable
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
      }
      while ((integer -= BULLET_VELOCITY) > 0); //keep projecting the enemy's movement forward until our bullet would reach their predicted location
   
      //aim at the predicted target
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));      
   
      //Pseudo-infinite Radar Lock
      setTurnRadarLeftRadians(getRadarTurnRemaining());
   }
 
   public void onDeath(DeathEvent e)
   {
      //when the bot dies, move to the next cell in the table
      deathCount += 127;
      //deathCount++;
   }
 
   public void onHitWall(HitWallEvent e)
   {
      //reverse movement direction when the bot hits a wall
      direction = -direction;
   }
 
 
 
 
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
//Skilgannon - this didn't need to be quite as long as it was, only max bullet flight time + one of each possible character
//unless we want to try pre-loading some common movement patterns?
   static String enemyHistory = ""
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 1 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 1 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char)-1 + (char)-2 + (char)-3 + (char)-4 + (char)-5 + (char)-6 
   + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5 
   + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0
   ;
 
 
 
   public static final String ONE_WAY_ORBIT = "" + 
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +	   	   
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP;
 
   //SHELDOR:  Because this will be part of a larger string, we should start from 1 instead of 0.
   public static final String REVERSE_ON_ENEMY_FIRE = "" + 
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       FLIP    + FLIP    + FLIP    + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP;
 
   public static final String RANDOM = "" +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP;
 
//The chance that Yatagan will reverse direction when the enemy fires.
//values are referenced by number of deaths experienced
//when chancesOfReversing is 0, reverse on enemy fire only
//when chancesOfReversing is very large, almost never reverse (unless Math.random() is very small)
//when chancesOfReversing is > 3, reverse with probability 3/chancesOfReversing
   private static final String chancesOfReversing = ""
   + NO_FLIP
   + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT //SHELDOR:  Let's try oscillating movement first.
   + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   ;
}

Latest Released Version (1.2.3)

/*
Yatagan 1.2.3 by Sheldor & Skilgannon;  Release date:  2013/06/13
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
Codesize:  249 bytes without any colors
 
Credits: 
Pattern Matching code from simonton.WeekendObsession_S and mld.Moebius, heavily modified.
And a general thanks to all open source bot authors and contributors to the RoboWiki.
 
Yatagan is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
See license here: http://robowiki.net/wiki/RWPCL
*/
 
package jk.sheldor.nano;
 
import robocode.*;
import robocode.util.Utils;
 
public class Yatagan extends AdvancedRobot{
 
   public static final double DESIRED_BULLET_POWER = 2.0;
 
   //round to nearest multiple of 0.33333...
   public static final int BULLET_POWER = 2;//(int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
 
 //Skilgannon: make this odd otherwise we can get errors in the beginning when a match of length 2 isn't found.
   public static final int MAX_MATCH_LENGTH = 40;  //Keep this under 128 to save a byte.
 
   public static final int ORBIT_DISTANCE = 220;
   //public static final double MOVE_AMOUNT = 1e+200;
   public static final double DISTANCE_FACTOR = 3000;
 
   public static final int ANTI_RAMBOT_DISTANCE = 127;  //Keep this under 128 to save a byte.
 
//NB! Generate new RANDOM when changing ORBIT_DISTANCE! 
/*public static void main(String[] args){
System.out.println("RANDOM = " + (int)Math.round(3.0/(0.6*Math.sqrt((20 - 3*2.5)/ORBIT_DISTANCE) - 0.04)));
}//*/
 
   //public static final char ONE_WAY_ORBIT = 65535;
   //public static final char REVERSE_ON_ENEMY_FIRE = 0;
   //public static final char RANDOM = 29; //SHELDOR: This is no longer flat, but it works better against PM.
 
   public static final char NO_FLIP = 65535;
   public static final char FLIP = 0;
   public static final char RANDOM_FLIP = 10;
 
   //Global Variables
   static double direction;
   static double enemyEnergy;
 
   static int deathCount;
 
   public void run()
   {
      //Skilgannon: sacrifice this for anti-rambot code
     //SHELDOR:  Now we have enough room for both!
      setAdjustRadarForGunTurn(true);
 
      //start spinning radar and initialize direction
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
   }
 
   public void onScannedRobot(ScannedRobotEvent e)
   {
      //Local Variables
      int integer = MAX_MATCH_LENGTH;
      double absoluteBearing;
      int matchPosition;
 
    //SHELDOR:  Debugging Tools
   //System.out.println(enemyEnergy - e.getEnergy());
   //System.out.println(deathCount);
   //System.out.println((deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
   //System.out.println((int)chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - e.getEnergy()))));
   //System.out.println(((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (e.getEnergy())))) * Math.random()) - 1));
 
      //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with
      setAhead(direction *= ((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (enemyEnergy = e.getEnergy())))) * Math.random()) - 1));
      /*if(
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random() 
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
      {
         //Reverse direction.
         //Calling the onHitWall event to reverse direction saves two bytes.  Credit to Simonton.
         onHitWall(null);
      }		
      setAhead(direction);*/   
 
      //record the current enemy lateral velocity
      enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);   
 
      //Pattern Matching
      //find the longest match in the enemy history
      while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, (--integer)), 64)) < 0);
 
      //stay mostly perpendicular to the enemy, but try to maintain a distance of ORBIT_DISTANCE pixels
      //If DISTANCE_FACTOR is smaller it tries harder to get to the desired distance, but may 'SpinBot' if it is too small.
      setTurnRightRadians(Math.cos(e.getBearingRadians() + 
         ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / DISTANCE_FACTOR/*direction  / DISTANCE_FACTOR*/))
         ));
 
      //fire BULLET_POWER power bullets most of the time, but use higher power bullets when the distance is less than ANTI_RAMBOT_DISTANCE
      //This greatly improves scores against rambots and other extremely aggressive bots.
      setFire(BULLET_POWER + (ANTI_RAMBOT_DISTANCE / integer));
 
      //assume that the enemy will repeat their movements in the ticks following the recording of the original pattern
      //generate a firing angle based on that assumption 
      do { 
         //go through the log of enemy movements right after the original pattern was recorded
         //add the Angular Velocities directly to the absoluteBearing variable
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
      }
      while ((integer -= BULLET_VELOCITY) > 0); //keep projecting the enemy's movement forward until our bullet would reach their predicted location
 
      //aim at the predicted target
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));      
 
      //Pseudo-infinite Radar Lock
      setTurnRadarLeftRadians(getRadarTurnRemaining());
   }
 
   public void onDeath(DeathEvent e)
   {
      //when the bot dies, move to the next cell in the table
      deathCount += 127;
      //deathCount++;
   }
 
   public void onHitWall(HitWallEvent e)
   {
      //reverse movement direction when the bot hits a wall
      direction = -direction;
   }
 
 
 
 
 
//Preloaded log of enemy movements for pattern matcher so it doesn't need error checking
//Skilgannon - this didn't need to be quite as long as it was, only max bullet flight time + one of each possible character
//unless we want to try pre-loading some common movement patterns?
   static String enemyHistory = ""
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 1 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 1 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 1 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 
   + (char)-1 + (char)-2 + (char)-3 + (char)-4 + (char)-5 + (char)-6 
   + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5 
   + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0
   ;
 
 
 
   public static final String ONE_WAY_ORBIT = "" + 
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +	   	   
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP;
 
   //SHELDOR:  Because this will be part of a larger string, we should start from 1 instead of 0.
   public static final String REVERSE_ON_ENEMY_FIRE = "" + 
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       FLIP    + FLIP    + FLIP    + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP + NO_FLIP +
       NO_FLIP + NO_FLIP;
 
   public static final String RANDOM = "" +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
      RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP + RANDOM_FLIP +
       RANDOM_FLIP + RANDOM_FLIP;
 
//The chance that Yatagan will reverse direction when the enemy fires.
//values are referenced by number of deaths experienced
//when chancesOfReversing is 0, reverse on enemy fire only
//when chancesOfReversing is very large, almost never reverse (unless Math.random() is very small)
//when chancesOfReversing is > 3, reverse with probability 3/chancesOfReversing
   private static final String chancesOfReversing = ""
   + NO_FLIP
   + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT //SHELDOR:  Let's try oscillating movement first.
   + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   ;
}