Difference between revisions of "Yatagan/Source"
< Yatagan
Jump to navigation
Jump to search
m (→Development Version: Let's try it with only four exploitative rounds.) |
Skilgannon (talk | contribs) (1.0.9 - easier tuning, shoot 3 against rambots, remove setAdjust, oscillate first instead of orbit) |
||
Line 3: | Line 3: | ||
<syntaxhighlight> | <syntaxhighlight> | ||
/* | /* | ||
− | Yatagan 1.0. | + | Yatagan 1.0.9 by Sheldor & Skilgannon; Release date: 2013/05/04 |
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: 249 bytes without any colors | ||
Line 20: | Line 20: | ||
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.3; | ||
+ | |||
+ | //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; | ||
+ | //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 30: | Line 45: | ||
public void run() | public void run() | ||
{ | { | ||
− | + | //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. | ||
Line 38: | Line 54: | ||
public void onScannedRobot(ScannedRobotEvent e) | public void onScannedRobot(ScannedRobotEvent e) | ||
{ | { | ||
− | + | //Local variables. | |
− | int integer = | + | 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. | |
− | if( (char) ( | + | if( |
− | + | (char) ( chancesOfReversing.charAt(deathCount)*Math.random() | |
− | - (enemyEnergy = e.getEnergy()))) <= 1 ) | + | + enemyEnergy - (enemyEnergy = e.getEnergy()) - (1.1 - 1e-8) ) <= 1) |
{ | { | ||
− | + | //Reverse direction. | |
− | + | //Calling the onHitWall event saves two bytes. | |
onHitWall(null); | onHitWall(null); | ||
} | } | ||
setAhead(direction); | 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 220 pixels. | |
− | + | //SHELDOR: Let's try 220 this time. | |
− | + | //Skilgannon: Let's put the distance stuff inside the cos() so that we get better edge decisions. | |
− | + | // Might also allow more aggressive distancing? | |
− | + | setTurnRightRadians(Math.cos(e.getBearingRadians() + ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / 3200)))); | |
− | + | //Skilgannon: add in anti-rambot bullet power - smaller than 128 saves a byte | |
− | + | setFire(BULLET_POWER + (127/integer)); | |
− | |||
do | do | ||
Line 71: | Line 91: | ||
absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) / e.getDistance(); | absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) / e.getDistance(); | ||
} | } | ||
− | while ((integer -= | + | while ((integer -= BULLET_VELOCITY) > 0); |
− | + | //Aim at the predicted target. | |
− | setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians())); | + | setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians())); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | //Infinite radar lock. | |
setTurnRadarLeftRadians(getRadarTurnRemainingRadians()); | setTurnRadarLeftRadians(getRadarTurnRemainingRadians()); | ||
} | } | ||
Line 87: | Line 102: | ||
public void onDeath(DeathEvent e) | public void onDeath(DeathEvent e) | ||
{ | { | ||
− | + | //When the bot dies, move to the next cell in the table. | |
deathCount++; | deathCount++; | ||
} | } | ||
Line 93: | Line 108: | ||
public void onHitWall(HitWallEvent e) | public void onHitWall(HitWallEvent e) | ||
{ | { | ||
− | + | //Reverse direction. | |
direction = -direction; | 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 = "" | private static final String chancesOfReversing = "" | ||
− | + (char)60000 + (char)0 + (char)60000 + (char) 0 | + | //Skilgannon: Make the oscillating movement happen 1st |
− | //100 rounds of deaths | + | + (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. | //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) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + | + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 | |
− | + (char) | + | + (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) | + | + (char) 4 + (char) 3 + (char) 2 + (char) 1 + (char) 0 + (char) 0 |
− | + | ; | |
− | |||
− | + (char) | ||
− | |||
− | |||
− | + (char) | ||
− | |||
− | |||
− | + (char) | ||
− | |||
− | |||
− | + (char) 1 + (char) | ||
− | |||
− | |||
− | + (char) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 248: | Line 181: | ||
<syntaxhighlight> | <syntaxhighlight> | ||
/* | /* | ||
− | Yatagan 1.0. | + | Yatagan 1.0.8 by Sheldor & Skilgannon; Release date: 2013/05/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: 249 bytes without any colors | Codesize: 249 bytes without any colors | ||
Line 345: | Line 278: | ||
//Since this is an unchanging table, we can use 'final' to save a few bytes. | //Since this is an unchanging table, we can use 'final' to save a few bytes. | ||
private static final String chancesOfReversing = "" | private static final String chancesOfReversing = "" | ||
− | + | + (char)60000 + (char)0 + (char)60000 + (char) 0 | |
//100 rounds of deaths, should be enough? | //100 rounds of deaths, should be enough? | ||
// range which will produce 'bullet hit': 3.0999 - 0.0999 = 3 | // range which will produce 'bullet hit': 3.0999 - 0.0999 = 3 |
Revision as of 12:58, 4 May 2013
Development Version
Codesize: 249
/*
Yatagan 1.0.9 by Sheldor & Skilgannon; Release date: 2013/05/04
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 sheldor.jk;
import robocode.*;
import robocode.util.Utils;
public class Yatagan extends AdvancedRobot{
public static final double DESIRED_BULLET_POWER = 2.3;
//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;
//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 220 pixels.
//SHELDOR: Let's try 220 this time.
//Skilgannon: Let's put the distance stuff inside the cos() so that we get better edge decisions.
// Might also allow more aggressive distancing?
setTurnRightRadians(Math.cos(e.getBearingRadians() + ((ORBIT_DISTANCE - (integer = (int)(e.getDistance()))) * (getVelocity() / 3200))));
//Skilgannon: 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.
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 = ""
//Skilgannon: Make the oscillating movement happen 1st
+ (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.0.7)
Codesize: 249
/*
Yatagan 1.0.8 by Sheldor & Skilgannon; Release date: 2013/05/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 sheldor.jk;
import robocode.*;
import robocode.util.Utils;
public class Yatagan extends AdvancedRobot
{
//Global variables.
static double direction;
static double enemyEnergy;
static int deathCount;
public void run()
{
setAdjustGunForRobotTurn(true);
//Start spinning radar and initialize direction to infinity.
setTurnRadarRightRadians(direction = Double.POSITIVE_INFINITY);
}
public void onScannedRobot(ScannedRobotEvent e)
{
//Local variables.
int integer = 30;
double absoluteBearing;
int matchPosition;
//Orbiting/Oscillating/Random movement, all depending on the size of the number you multiply the random with.
if( (char) ((enemyEnergy - 1.09999999999
+ chancesOfReversing.charAt(deathCount)*Math.random()
- (enemyEnergy = e.getEnergy()))) <= 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 220 pixels.
//SHELDOR: Let's try 220 this time.
setTurnRightRadians(Math.cos(e.getBearingRadians()) + ((220.0 - (integer = (int)(e.getDistance()))) * (getVelocity() / 3200)));
do
{
absoluteBearing += ((short) enemyHistory.charAt(--matchPosition)) / e.getDistance();
}
while ((integer -= 13) > 0);
//Aim at the predicted target.
setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
//Fire!
//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());
}
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.
direction = -direction;
}
//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.
private static final String chancesOfReversing = ""
+ (char)60000 + (char)0 + (char)60000 + (char) 0
//100 rounds of deaths, should be enough?
// range which will produce 'bullet hit': 3.0999 - 0.0999 = 3
//required reverse probability, from Toorkild's formula: 0.6*sqrt((20 - 3*2.5)/160) - 0.04 ~= 0.125
//thus 3/x = 0.125 --> x = 3/0.125 = 24
+ (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
+ (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.
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;
}