Difference between revisions of "Yatagan/Source"

From Robowiki
Jump to navigation Jump to search
Line 1: Line 1:
 
== Development Version ==
 
== Development Version ==
Codesize: 246
+
Codesize: 249
 
<syntaxhighlight>
 
<syntaxhighlight>
 
/*
 
/*
Yatagan 1.1.7 by Skilgannon & Sheldor;  Release date:  2013/05/27
+
Yatagan 1.2.0 by Sheldor & Skilgannon;  Release date:  2013/06/03
 
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:  246 bytes without any colors
+
Codesize:  249 bytes without any colors
 
   
 
   
 
Credits:  
 
Credits:  
Line 31: Line 31:
 
   public static final int MAX_MATCH_LENGTH = 40;  //Keep this under 128 to save a byte.
 
   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 int ORBIT_DISTANCE = 220;
   public static final double DISTANCE_FACTOR = 20000;  
+
  //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.
 
   public static final int ANTI_RAMBOT_DISTANCE = 127;  //Keep this under 128 to save a byte.
Line 41: Line 42:
 
}//*/
 
}//*/
 
   
 
   
   public static final char ONE_WAY_ORBIT = 65535;
+
   //public static final char ONE_WAY_ORBIT = 65535;
   public static final char REVERSE_ON_ENEMY_FIRE = 0;
+
   //public static final char REVERSE_ON_ENEMY_FIRE = 0;
   public static final char RANDOM = 29;
+
   //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.
 
   //Global variables.
 
   static double direction;
 
   static double direction;
Line 54: Line 59:
 
   {
 
   {
 
       //Skilgannon: sacrifice this for anti-rambot code
 
       //Skilgannon: sacrifice this for anti-rambot code
      //setAdjustGunForRobotTurn(true);
+
  //SHELDOR:  Now we have enough room for both!
 
+
      setAdjustGunForRobotTurn(true);
       //Start spinning radar and initialize direction to infinity.
+
       setTurnRadarRightRadians(direction = 48);
+
       //Start spinning radar and initialize direction.
 +
       setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
 
   }
 
   }
 
   
 
   
Line 66: Line 72:
 
       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.
      //Use the unsigned feature of chars to make the enemy fire detection more accurate, Credit to Miked0801.
+
  setAhead(direction *= ((chancesOfReversing.charAt(deathCount + (100 + (int)(enemyEnergy - (enemyEnergy = e.getEnergy())))) * Math.random()) - 1));
       if(
+
       /*if(
 
       (char) ( chancesOfReversing.charAt(deathCount)*Math.random()  
 
       (char) ( chancesOfReversing.charAt(deathCount)*Math.random()  
 
       + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
 
       + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1)
Line 77: Line 83:
 
         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.
       //Find the longest match in the enemy history.
+
       //Find the longest match in the enemy history.  
 
       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 ORBIT_DISTANCE pixels.  
 
       //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.
 
       //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() +  
 
       setTurnRightRadians(Math.cos(e.getBearingRadians() +  
         ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (direction  / DISTANCE_FACTOR))
+
         ((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.
 
       //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.
 
       //This greatly improves scores against rambots and other extremely aggressive bots.
 
       setFire(BULLET_POWER + (ANTI_RAMBOT_DISTANCE / integer));
 
       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.
 
       //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.
+
       //Generate a firing angle based on that assumption.  
 
       do {  
 
       do {  
 
         //Go through the log of enemy movements right after the original pattern was recorded.
 
         //Go through the log of enemy movements right after the original pattern was recorded.
      //Add the Angular Velocities directly to the absoluteBearing variable.
+
        //Add the Angular Velocities directly to the absoluteBearing variable.
 
         absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) /  e.getDistance();
 
         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.
 
       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.
 
       //Aim at the predicted target.
 
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));       
 
       setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));       
 
+
       //Infinite radar lock.
+
       //Pseudo-infinite radar lock
 
       setTurnRadarLeftRadians(getRadarTurnRemaining());
 
       setTurnRadarLeftRadians(getRadarTurnRemaining());
 
   }
 
   }
Line 115: Line 121:
 
   {
 
   {
 
       //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 += 127;
 +
       //deathCount++;
 
   }
 
   }
 
   
 
   
Line 124: Line 131:
 
   }
 
   }
 
   
 
   
//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)ONE_WAY_ORBIT + (char)REVERSE_ON_ENEMY_FIRE + (char)ONE_WAY_ORBIT
 
  + (char)REVERSE_ON_ENEMY_FIRE + (char)ONE_WAY_ORBIT + (char)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
 
  ;
 
 
   
 
   
 
   
 
   
Line 156: Line 143:
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 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) 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  
Line 167: Line 156:
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 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  
Line 172: Line 162:
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0  
 
   + (char) 0 + (char) 0 + (char) 0 + (char) 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  
Line 183: Line 170:
 
   + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5  
 
   + (char)-7 + (char)-8 + (char) 8 + (char) 7 + (char) 6 + (char) 5  
 
   + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0
 
   + (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;
 +
 +
  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 + 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;
 +
 
 +
  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 = ""
 +
  + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT
 +
  + 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
 
   ;
 
   ;
 
}
 
}

Revision as of 21:59, 3 June 2013

Development Version

Codesize: 249

/*
Yatagan 1.2.0 by Sheldor & Skilgannon;  Release date:  2013/06/03
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!
      setAdjustGunForRobotTurn(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;
 
      //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;

   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 + 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;
	   
   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 = ""
   + ONE_WAY_ORBIT + REVERSE_ON_ENEMY_FIRE + ONE_WAY_ORBIT
   + 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.1.5)

/*
Yatagan 1.1.5 by Skilgannon & Sheldor;  Release date:  2013/05/19
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;
 
   //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);

 //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 = 81;  //Keep this under 128 to save a byte.

   public static final int ORBIT_DISTANCE = 220; 
   public static final int 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;
 
   //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.
      //Use the unsigned feature of chars to make the enemy fire detection more accurate.  Credit to Miked0801.
      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 allowable in the enemy history.
      //Credit to Nz.jdc for the idea to reduce match length by two instead of one.
      while((matchPosition = enemyHistory.indexOf(enemyHistory.substring(0, (integer -= 2)), 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))
         ));
   
      //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()));      
   
      //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 movement 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)ONE_WAY_ORBIT + (char)REVERSE_ON_ENEMY_FIRE + (char)ONE_WAY_ORBIT
   + (char)REVERSE_ON_ENEMY_FIRE + (char)ONE_WAY_ORBIT + (char)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
   ;
 
 
 
//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
   ;
}