Difference between revisions of "Yatagan/Source"

From Robowiki
Jump to navigation Jump to search
(Bullet power 2 test (also saves a byte))
Line 176: Line 176:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Latest Released Version (1.0.7) ==
+
== Latest Released Version (1.1.1) ==
  
Codesize: 249
 
 
<syntaxhighlight>
 
<syntaxhighlight>
 
/*
 
/*
Yatagan 1.0.8 by Sheldor & Skilgannon;  Release date:  2013/05/03
+
Yatagan 1.1.1 by Skilgannon & Sheldor ;  Release date:  2013/05/05
 
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
+
Codesize:  248 bytes without any colors
 
   
 
   
 
Credits:  
 
Credits:  
Line 193: Line 192:
 
*/
 
*/
 
   
 
   
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{
{
+
 +
  public static final double DESIRED_BULLET_POWER = 2.0;//Skilgannon: Let's test this first
 +
 +
//round to nearest multiple of 0.33333...
 +
  public static final double BULLET_POWER = (int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
 +
  public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
 +
 +
  public static final int MAX_MATCH_LENGTH = 30;
 +
  public static final int ORBIT_DISTANCE = 220;
 +
  public static final int DISTANCE_FACTOR = 3000;
 +
//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 RANDOM = 29;
 +
 
//Global variables.
 
//Global variables.
 
   static double direction;
 
   static double direction;
Line 208: Line 224:
 
   public void run()
 
   public void run()
 
   {
 
   {
      setAdjustGunForRobotTurn(true);
+
  //Skilgannon: sacrifice this for anti-rambot code
 
+
  //setAdjustGunForRobotTurn(true);
 +
 
   //Start spinning radar and initialize direction to infinity.
 
   //Start spinning radar and initialize direction to infinity.
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
Line 216: Line 233:
 
   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;
 
       int matchPosition;
 
       int matchPosition;
    
+
      //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with.
+
   //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with.
       if( (char) ((enemyEnergy - 1.09999999999
+
       if(
      + chancesOfReversing.charAt(deathCount)*Math.random()  
+
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random()  
       - (enemyEnergy = e.getEnergy()))) <= 1 )
+
       + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
 
       {
 
       {
        //Reverse direction.
+
      //Reverse direction.
        //Calling the onHitWall event saves two bytes.
+
      //Calling the onHitWall event saves two bytes.
 
         onHitWall(null);
 
         onHitWall(null);
 
       }
 
       }
 
       setAhead(direction);     
 
       setAhead(direction);     
 
+
 
+
   //Record the current enemy lateral velocity.
    
 
      //Record the current enemy lateral velocity.
 
 
       enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);   
 
       enemyHistory = String.valueOf((char) (e.getVelocity() * (Math.sin(e.getHeadingRadians() - (absoluteBearing = e.getBearingRadians() + getHeadingRadians()))))).concat(enemyHistory);   
    
+
      //Pattern Matching.       
+
   //Pattern Matching.       
      // search for a match
+
  // search for a match
 
       while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
 
       while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, integer--), 64)) < 0);
    
+
      //Stay mostly perpendicular to the enemy, but try to maintain a distance of 220 pixels.
+
   //Stay mostly perpendicular to the enemy, but try to maintain a distance of ORBIT_DISTANCE pixels.  
      //SHELDOR:  Let's try 220 this time.
+
  //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()) + ((220.0 - (integer = (int)(e.getDistance()))) * (getVelocity()  / 3200)));
+
       setTurnRightRadians(Math.cos(e.getBearingRadians() +  
    
+
        ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity()  / DISTANCE_FACTOR))
 +
        ));
 +
 +
   // add in anti-rambot bullet power - smaller than 128 saves a byte
 +
      setFire(BULLET_POWER + (127/integer));
 +
 
       do
 
       do
 
       {  
 
       {  
 
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
 
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
 
       }
 
       }
       while ((integer -= 13) > 0);
+
       while ((integer -= BULLET_VELOCITY) > 0);
    
+
      //Aim at the predicted target.
+
   //Aim at the predicted target.
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
+
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));    
 
+
   
      //Fire!
+
   //Infinite radar lock.
      //Bullet power must be a multiple of 0.33333... or else the gun will be inaccurate.
 
      //SHELDOR: Though lower-power bullets make us easy rambot prey, they will probably result in a larger overall APS score.
 
      setFire(2.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333);
 
    
 
      //Infinite radar lock.
 
 
       setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
 
       setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
 
   }
 
   }
Line 265: Line 280:
 
   public void onDeath(DeathEvent e)
 
   public void onDeath(DeathEvent e)
 
   {
 
   {
      //When the bot dies, move to the next cell in the table.
+
  //When the bot dies, move to the next cell in the table.
 
       deathCount++;
 
       deathCount++;
 
   }
 
   }
Line 271: Line 286:
 
   public void onHitWall(HitWallEvent e)
 
   public void onHitWall(HitWallEvent e)
 
   {
 
   {
      //Reverse direction.
+
  //Reverse direction when the bot hits a wall.
 
       direction = -direction;
 
       direction = -direction;
 
   }
 
   }
 
   
 
   
  //The chance that Yatagan will reverse direction when the enemy fires.
+
//The chance that Yatagan will reverse direction when the enemy fires.
  //Since this is an unchanging table, we can use 'final' to save a few bytes.
+
//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 = ""
 
   private static final String chancesOfReversing = ""
   + (char)60000 + (char)0 + (char)60000 + (char) 0
+
   + (char)0 + (char)60000 + (char)0 + (char)60000 + (char)0 + (char)60000
   //100 rounds of deaths, should be enough?
+
   //100 rounds of deaths should be more than enough
  // range which will produce 'bullet hit': 3.0999 - 0.0999 = 3
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
  //required reverse probability, from Toorkild's formula: 0.6*sqrt((20 - 3*2.5)/160) - 0.04 ~= 0.125
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
  //thus 3/x = 0.125 --> x = 3/0.125 = 24
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
+
  ;
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
   + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29
 
  + (char) 29 + (char) 29 + (char) 29 + (char) 29 + (char) 29;
 
 
   
 
   
 
   
 
   
 
   
 
   
 
//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) 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) 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) 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
 
   + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 1
 
  + (char) 1 + (char) 1 + (char) 1 + (char) 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>
 
</syntaxhighlight>

Revision as of 16:39, 5 May 2013

Development Version

Codesize: 248

/*
Yatagan 1.1.1 by Skilgannon & Sheldor ;  Release date:  2013/05/05
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
Codesize:  248 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;//Skilgannon: Let's test this first
 
 //round to nearest multiple of 0.33333...
   public static final double BULLET_POWER = (int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
 
   public static final int MAX_MATCH_LENGTH = 30;
   public static final int ORBIT_DISTANCE = 220; 
   public static final int DISTANCE_FACTOR = 3000; 
//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 RANDOM = 29;
 
//Global variables.
   static double direction;
   static double enemyEnergy;
 
   static int deathCount;
 
   public void run()
   {
   //Skilgannon: sacrifice this for anti-rambot code
   //setAdjustGunForRobotTurn(true);
   
   //Start spinning radar and initialize direction to infinity.
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
   }
 
   public void onScannedRobot(ScannedRobotEvent e)
   {
   //Local variables.
      int integer = MAX_MATCH_LENGTH;
      double absoluteBearing;
      int matchPosition;
   
   //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with.
      if(
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random() 
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
      {
      //Reverse direction.
      //Calling the onHitWall event saves two bytes.
         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.      
   // 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
      setTurnRightRadians(Math.cos(e.getBearingRadians() + 
         ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity()  / DISTANCE_FACTOR))
         ));
   
   // add in anti-rambot bullet power - smaller than 128 saves a byte
      setFire(BULLET_POWER + (127/integer));
   
      do
      { 
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
      }
      while ((integer -= BULLET_VELOCITY) > 0);
   
   //Aim at the predicted target.
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));      
   
   //Infinite radar lock.
      setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
   }
 
   public void onDeath(DeathEvent e)
   {
   //When the bot dies, move to the next cell in the table.
      deathCount++;
   }
 
   public void onHitWall(HitWallEvent e)
   {
   //Reverse direction when the bot hits a wall.
      direction = -direction;
   }
 
//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 = ""
   + (char)0 + (char)60000 + (char)0 + (char)60000 + (char)0 + (char)60000 
   //100 rounds of deaths should be more than enough
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   ;
 
 
 
//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) 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) 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) 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
   ;
}

Latest Released Version (1.1.1)

/*
Yatagan 1.1.1 by Skilgannon & Sheldor ;  Release date:  2013/05/05
The yatagan is a short sabre which was used extensively in the Ottoman Empire.
Codesize:  248 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;//Skilgannon: Let's test this first
 
 //round to nearest multiple of 0.33333...
   public static final double BULLET_POWER = (int)(DESIRED_BULLET_POWER*3 + 0.5)/3.0;
   public static final int BULLET_VELOCITY = (int)(20 - 3 * BULLET_POWER);
 
   public static final int MAX_MATCH_LENGTH = 30;
   public static final int ORBIT_DISTANCE = 220; 
   public static final int DISTANCE_FACTOR = 3000; 
//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 RANDOM = 29;
 
//Global variables.
   static double direction;
   static double enemyEnergy;
 
   static int deathCount;
 
   public void run()
   {
   //Skilgannon: sacrifice this for anti-rambot code
   //setAdjustGunForRobotTurn(true);
 
   //Start spinning radar and initialize direction to infinity.
      setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
   }
 
   public void onScannedRobot(ScannedRobotEvent e)
   {
   //Local variables.
      int integer = MAX_MATCH_LENGTH;
      double absoluteBearing;
      int matchPosition;
 
   //Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with.
      if(
      (char) ( chancesOfReversing.charAt(deathCount)*Math.random() 
      + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
      {
      //Reverse direction.
      //Calling the onHitWall event saves two bytes.
         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.      
   // 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
      setTurnRightRadians(Math.cos(e.getBearingRadians() + 
         ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity()  / DISTANCE_FACTOR))
         ));
 
   // add in anti-rambot bullet power - smaller than 128 saves a byte
      setFire(BULLET_POWER + (127/integer));
 
      do
      { 
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
      }
      while ((integer -= BULLET_VELOCITY) > 0);
 
   //Aim at the predicted target.
      setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));      
 
   //Infinite radar lock.
      setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
   }
 
   public void onDeath(DeathEvent e)
   {
   //When the bot dies, move to the next cell in the table.
      deathCount++;
   }
 
   public void onHitWall(HitWallEvent e)
   {
   //Reverse direction when the bot hits a wall.
      direction = -direction;
   }
 
//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 = ""
   + (char)0 + (char)60000 + (char)0 + (char)60000 + (char)0 + (char)60000 
   //100 rounds of deaths should be more than enough
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM + RANDOM
   ;
 
 
 
//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) 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) 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) 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
   ;
}