Continuation/Code
Jump to navigation
Jump to search
/*
Continuation v1.1 by Sheldor. 03/17/2026 Code size: 749 bytes
a microbot with multimode movement and a pattern matching gun
v1.1 -- targeting, energy management
Credits:
Targeting: kc.micro.Needle, kc.micro.WaveShark, jk.micro.Cotillion, nz.jdc.HedgehogGF, pez.mini.Pugilist
Movement : sheldor.micro.Epeeist, nz.jdc.HedgehogGF, jk.micro.Cotillion, jk.micro.Toorkild, kc.micro.Thorn, wiki.nano.RaikoNano
Also, a general thanks to all open source bot authors and contributors to the RoboWiki.
Continuation is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
see license here: https://robowiki.net/wiki/RWPCL
*/
package sheldor.micro;
import robocode.*;
import robocode.util.Utils;
import java.awt.geom.*;
import java.awt.Color;
public class Continuation extends AdvancedRobot {
static final int BINS = 255;//121;
// static final int MIDDLE_FACTOR = (BINS - 1) / 2;
static final int MAX_MATCH_LENGTH = 43;
// static final double MAX_ESCAPE_ANGLE = (0.6082455789 / (MIDDLE_FACTOR / 2));
static final double TAU = (Math.PI * 2.0);
private static final double WALL_TEST = (8.0 / 11) / 8;
static Point2D.Double enemyLocation;
static double direction = 1;
static double enemyBulletSpeed;
static double enemyEnergy;
static double hits;
static boolean ramming;
static int movementMode;
static int enemyVelocity;
static int[][] history = new int[100000][2];
static int historyIndex;
/* public void run() {
setAdjustRadarForGunTurn(true);
setAdjustGunForRobotTurn(true);
do {
turnRadarLeftRadians(1);
} while(true);
}*/
public void onStatus(StatusEvent e){
setAdjustRadarForGunTurn(true);
setAdjustGunForRobotTurn(true);
setTurnRadarRightRadians(1);
}
public void onScannedRobot(ScannedRobotEvent e) {
int antiRam;
double offset;
double theta;
double bulletVelocity;
double enemyDistance;// = e.getDistance();
double absoluteBearing;
// double bestValue = 0;
double bulletPower;
// int matchLen = MAX_MATCH_LENGTH;
int matchPos;
// int predictPos;
int evaluatedPatterns;// = 0;
// int totalPatterns = 0;
//distancing from Thorn
// offset = Math.PI/2 + 1 - ((enemyDistance = e.getDistance()) / 530);
//distancing from HedgehogGF
// choose preferred direction, perpendicular + range control (r4d)
//offset = Math.toRadians(T_M_ANGLE.charAt((int)(enemyDistance = e.getDistance())));
//energy management based on distance, energy, and enemy energy
//retreat very heavily when the enemy is ramming
setFire(bulletPower = (offset = (2 + (antiRam = (100 / (int)(enemyDistance = e.getDistance())))
)) + antiRam - (BULLET_POWER_TABLE
.charAt((((int)getEnergy() >> 3) * 127) + (int)e.getEnergy()) / 100.01)
);
/*offset = 2 + (antiRam = (100 / (int)(enemyDistance = e.getDistance())));
double bulletPower =
Math.min(enemyEnergy / 4, BULLET_POWER_TABLE.charAt(
((int)enemyDistance >> 5) * 127 + (int)getEnergy())
/ 100.01);*/
//energy management based on distance, energy, and enemy energy
//retreat very heavily when the enemy is ramming
/* if(getEnergy() > (bulletPower =
Math.min(enemyEnergy / 4, BULLET_POWER_TABLE.charAt(
((int)enemyDistance >> 5) * 127 + (int)getEnergy())
/ 100.01)) - (double)(antiRam = (100 / (int)enemyDistance))//|| antiRam > 0//(ramming = antiRam > 0)
){
setFire(bulletPower);
} */
/* if (getEnergy() > 0.21)
setFire((bulletPower));*/
//wall smoothing based on HedgehogGF's
do{}while(fieldContains(theta = (absoluteBearing =
(e.getBearingRadians() + getHeadingRadians())) + direction * (offset -= 0.02), 160) > 0);
setTurnRightRadians(Math.tan(theta -= getHeadingRadians()));
//stop and go movement originally based on Thorn's
//move when the enemy fires, or when the robot is moving randomly, or when the enemy is ramming
/* double energyDrop;
if ((energyDrop = (enemyEnergy - (enemyEnergy = e.getEnergy()))) > movementMode - (antiRam))
{
//credit to Cotilion for stop and go length calculator
//credit to HedgehogGF for the copySign trick
setAhead(Math.copySign(((3 + (int)(energyDrop * 1.999999)) << 3), Math.cos(theta)));
}*/
//stop and go movement originally based on Thorn's
//move when the enemy fires, or when the robot is moving randomly, or when the enemy is ramming
double energyDrop;
if ((energyDrop = (enemyEnergy - (enemyEnergy = e.getEnergy()))
- WALL_HIT_TABLE.charAt(127 + (enemyVelocity - (enemyVelocity = (int)e.getVelocity())))
) > movementMode - (antiRam))
{
//credit to Cotilion for stop and go length calculator
//credit to HedgehogGF for the copySign trick
setAhead(Math.copySign(((3 + (int)(energyDrop * 1.999999)) << 3), Math.cos(theta)));
}
//random movement from Toorkild
//don't move randomly if the enemy is ramming, or if the bot is in stop and go mode
//reverse direction if the bot gets too close to a wall
if (Math.random() + antiRam < (-0.6 * Math.sqrt(enemyBulletSpeed / enemyDistance) + 0.04) * movementMode
|| offset < Math.PI/3.5)
{
direction = -direction;
}
int i = 24;//8;
double lv;
int wallScore = 0;
int av;
do{
wallScore += fieldContains(absoluteBearing + //(Math.signum(lv = (e.getVelocity() *
//Math.sin(offset = (e.getHeadingRadians() - absoluteBearing))) ) / 4) * --i
// *
(//4.29 / //(60.0 / (bulletVelocity = Rules.getBulletSpeed(bulletPower)))
WALL_TEST * (short)WALL_TABLE.charAt(--i))
, enemyDistance);
} while(i > 0);
//pattern matching based on kc.micro.WaveShark's
// Update log of enemy movements and pattern match
// enemyHistory = String.valueOf(
int[] currentSituation;
int[][] localHistory;
(currentSituation = (localHistory = history)[++historyIndex])[0] =
// (char)
((int)Math.round( e.getVelocity() *
Math.sin(offset = (e.getHeadingRadians() - absoluteBearing))
)
//+ (Math.random() - 0.5)
<< 10)
+ (wallScore << 3) + ADVEL_TABLE.charAt(8 + (currentSituation[1] = (int)Math.round(e.getVelocity() * Math.cos(offset))))
//Math.cos(e.getHeadingRadians() - absoluteBearing))))
//(fieldContains(absoluteBearing + WALL_FEATURE, enemyDistance) << 1)
// | fieldContains(absoluteBearing - WALL_FEATURE, enemyDistance)
;
//string data from Cotillion
/* (char)(
((4+(Math.round((float)(e.getVelocity()*Math.cos(offset = e.getHeadingRadians()- absoluteBearing))/2f))))
|
((int)Math.round(offset = e.getVelocity()*Math.sin(offset))<<11)
|
0x10*fieldContains(absoluteBearing + (8.0 / (bulletVelocity = Rules.getBulletSpeed(bulletPower))) * Math.signum(offset), enemyDistance))
*/
// ).concat(enemyHistory);
//history[historyIndex][1] = av;
//advelAppendix = String.valueOf((char)(av)).concat(advelAppendix);
// enemyHistory = String.valueOf((char)Math.round(e.getVelocity() * Math.sin(e.getHeadingRadians() - absoluteBearing))).concat(enemyHistory);
//multiple choice originally based on Needle's
int[] angleValue = new int[BINS + 1];
int bestIndex = 0;
// int squares = 0;
i = 0;//127;
int matchLen;
int value;
// double factorAngle = (8.0 / bulletVelocity) / (MIDDLE_FACTOR);
// while(getGunHeat() <= 0.3 &&//matchLen++ < 50 &&
//--matchLen > 1)//matchLen-- > 1)
do
{
matchLen = 0;
matchPos = i;
// evaluatedPatterns = 0;
/* while((//predictPos =
matchPos = enemyHistory.indexOf(
enemyHistory.substring(0, matchLen),
matchPos + 65//Math.max(matchPos + 1, 64)//(int)(enemyDistance / (smoothedHeading - 4))
)) >= 0) */
{
try{
// int test = i;
do{
//matchLen++;
} while(localHistory[i - matchLen][0] == localHistory[historyIndex - matchLen++][0]);
}catch(Exception ex){}
if (matchLen > 1){
//evaluatedPatterns++;
/* if((predictPos = enemyHistory.indexOf(
enemyHistory.substring(0, matchLen), 64)) >= 0)
{*/
double d = 0;// -smoothedHeading;
offset = 0;
do {
// char c;// = enemyHistory.charAt(--matchPos);
offset += (localHistory[++matchPos][0] >> 10)/ //((short)(enemyHistory.charAt(--matchPos))>>8)/
(enemyDistance += localHistory[matchPos][1]);//(short)advelAppendix.charAt(matchPos));//2*((int)(c&0X0F) - 4));
//offset += ((short)enemyHistory.charAt(--matchPos) >> 4) / enemyDistance;
} while (//matchPos > 0 &&
(d += Rules.getBulletSpeed(bulletPower)) < enemyDistance);
// double bestValue = 0;
int bin;
if(fieldContains(absoluteBearing + offset, (enemyDistance )) <= 0 && (angleValue[bin = (int)Math.round(Utils.normalAbsoluteAngle(offset) * (BINS / TAU))] +=
// LENGTH_TABLE.charAt
(i * matchLen * matchLen) )//+= (matchLen) / (1 + Math.abs(bin - MIDDLE_FACTOR + (int)((offset / enemyDistance) / factorAngle))))
> angleValue[bestIndex]) {
//bestValue = angleValue[bin];
bestIndex = bin;
/*setTurnGunRightRadians(Utils.normalRelativeAngle(//(Math.PI / BINS) +
absoluteBearing + offset * Math.signum(enemyEnergy)
+ (Math.random() * 0.007) - getGunHeadingRadians()));*/
}
//angleValue[(int)(Utils.normalAbsoluteAngle(offset) * (BINS / TAU))] += matchLen;//(matchLen * matchLen);
// totalPatterns++;
enemyDistance = e.getDistance();
/* if(evaluatedPatterns > 50){//(MAX_MATCH_LENGTH + 10) - matchLen){//5 + (int)Math.sqrt(enemyHistory.length())) {
break;
}*/
}
}
i += matchLen;
}
while (i < historyIndex - 64// && (squares += value) < 7500 //&& evaluatedPatterns < 50
);
//System.out.println(squares);
//System.out.println(historyIndex);
/* int bin = BINS;
int bestIndex = 0;//MIDDLE_FACTOR;
do {
if((angleValue[bin] )//+= (matchLen) / (1 + Math.abs(bin - MIDDLE_FACTOR + (int)((offset / enemyDistance) / factorAngle))))
> angleValue[bestIndex]) {
//bestValue = angleValue[bin];
bestIndex = bin;
}
} while(bin-- > 0);*/
setTurnGunRightRadians(Utils.normalRelativeAngle(//(Math.PI / BINS) +
absoluteBearing +
(bestIndex * (TAU / BINS) ) * Math.signum(enemyEnergy)
+ (Math.random() * 0.007) - getGunHeadingRadians()));
setTurnRadarRightRadians(2.0 * Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()));
//System.out.println(totalPatterns);
}
//This method returns 1 if a point projected from the bot's location by the
//"heading" and "distance" parameters is outside of the battlefield, and 0 if it is not.
//credit to HedgehogGF
private int fieldContains(double heading, double distance)
{
return Integer.signum(new Rectangle2D.Double(18, 18, 764, 564).outcode(getX() + distance * Math.sin(heading), getY() + distance * Math.cos(heading)));
}
public void onBulletHit(BulletHitEvent e)
{
//adjust the enemy energy variable when the bot hits the enemy
//This makes a big difference against linear targeting.
enemyEnergy -= 10;//Rules.getBulletDamage(e.getBullet().getPower());//10;
}
public void onHitByBullet(HitByBulletEvent e)
{
//adjust the enemy energy variable when the bot gets hit
//store the velocity of the enemy's bullet for the random movement
double damage;
enemyEnergy += (damage = 20 - (enemyBulletSpeed = e.getVelocity()));
//if the bot takes an unacceptable amount of damage relative to the number of rounds
//that have passed while in stop and go mode, switch to random movement
if (//!ramming &&
(hits += damage) > (getRoundNum() * 23) + 40)
{
movementMode = -1;
}
}
public static final String LENGTH_TABLE = ""
+ (char)0 + (char)1 + (char)15 + (char)20 + (char)25
+ (char)30 + (char)40 + (char)50 + (char)60 + (char)70
+ (char)80 + (char)100 + (char)120 + (char)140 + (char)160
+ (char)165 + (char)170 + (char)175 + (char)180 + (char)185
+ (char)190 + (char)195 + (char)200 + (char)205 + (char)210
+ (char)230 + (char)250 + (char)270 + (char)290 + (char)310
+ (char)320 + (char)325 + (char)330 + (char)335 + (char)340
+ (char)345 + (char)350 + (char)355 + (char)360 + (char)365
+ (char)370 + (char)375 + (char)380 + (char)390 + (char)395
+ (char)400 + (char)405 + (char)410 + (char)415 + (char)420
;
static final String NO_HIT = ""
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0;
static final String WALL_HIT_TABLE = ""
+ NO_HIT + NO_HIT + NO_HIT + NO_HIT
+ (char)0 + (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)1 + (char)1 + (char)2
+ (char)2 + (char)3 + (char)3
+ NO_HIT;
public static final String ADVEL_TABLE = ""
/*+ (char)0 + (char)0 + (char)1 + (char)1// + (char)0
+ (char)2 + (char)2 + (char)3 + (char)3
+ (char)3 + (char)3 + (char)3 + (char)4
+ (char)4 + (char)5 + (char)5 + (char)6
+ (char)6;*/
/*+ (char)0 + (char)0 + (char)0 + (char)1// + (char)0
+ (char)1 + (char)1 + (char)2 + (char)2
+ (char)2
+ (char)2 + (char)2 + (char)3 + (char)3
+ (char)3 + (char)4 + (char)4 + (char)4;*/
+ (char)0 + (char)0 + (char)0 + (char)1// + (char)0
+ (char)1 + (char)1 + (char)1 + (char)2
+ (char)2
+ (char)2 + (char)3 + (char)3 + (char)3
+ (char)3 + (char)4 + (char)4 + (char)4;
public static final String WALL_TABLE = ""
/*+ (char)1 + (char)1 + (char)1 + (char)1 + (char)1
+ (char)3 + (char)3 + (char)3 + (char)3 + (char)3
+ (char)7 + (char)7 + (char)7 + (char)7 + (char)7
+ (char)10 + (char)10 + (char)10 + (char)10 + (char)10
+ (char)-1 + (char)-3 + (char)-7 + (char)-10*/
// + (char)2 + (char)2 + (char)2 + (char)2
/*+ (char)3 + (char)3 + (char)3 + (char)3
+ (char)6 + (char)6 + (char)6 + (char)6
//+ (char)12 + (char)12 + (char)12 + (char)12 + (char)12
//+ (char)24 + (char)24 + (char)24 + (char)24 + (char)24
+ (char)-3 + (char)-6// + (char)-12 + (char)-24;*/
+ (char)1 + (char)1 + (char)1 + (char)1 + (char)1
+ (char)2 + (char)2 + (char)2 + (char)2 + (char)2
//+ (char)3 + (char)3 + (char)3 + (char)3 + (char)3
+ (char)4 + (char)4 + (char)4 + (char)4 + (char)4
//+ (char)5 + (char)5 + (char)5 + (char)5// + (char)5
//+ (char)6 + (char)6 + (char)6 + (char)6 + (char)6
//+ (char)7 + (char)7 + (char)7 //+ (char)7 //+ (char)7
//+ (char)12 + (char)12 + (char)12
+ (char)8 + (char)8 + (char)8 + (char)8 + (char)8
//+ (char)10 + (char)10 + (char)10 + (char)10// + (char)10
//+ (char)15 + (char)15 + (char)15 + (char)15 + (char)15
//+ (char)30 + (char)30 + (char)30 + (char)30 + (char)30
//+ (char)24 + (char)24 + (char)24 + (char)24
// + (char)20 + (char)20 + (char)20 + (char)20
//+ (char)15 + (char)15 + (char)15
//+ (char)60 + (char)60 + (char)60 + (char)60 + (char)60
//+ (char)-6 + (char)-10 + (char)-20// + (char)-60
+ (char)-1 + (char)-2 + (char)-4 + (char)-8
;
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;
static String advelAppendix = ""
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0
+ (char) 0 + (char) 0 + (char) 0 + (char) 0;
//tables for energy management
static final String BP0 = ""
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0;
static final String BP50 = ""
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50;
static final String MAIN = ""
+ (char)175 + (char)150 + (char)125 + (char)100
+ (char)83 + (char)66 + (char)50 + (char)33
+ (char)16 + (char)0
+ BP0
+ BP0
+ BP0
+ BP0
+ BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0;
static final String LOW_MID_ENERGY = ""
+ (char)175 + (char)150 + (char)125 + (char)100
+ (char)100 + (char)100 + (char)100 + (char)100
+ (char)100 + (char)100 + (char)100 + (char)100
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ BP50
+ BP0 + BP0 + BP0 + BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0;
static final String MID_ENERGY = ""
+ (char)175 + (char)150 + (char)125 + (char)100
+ (char)100 + (char)100 + (char)100 + (char)100
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ (char)50 + (char)50 + (char)50 + (char)50
+ BP0 + BP0 + BP0 + BP0 + BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0;
static final String BP190 = ""
+ (char)190 + (char)190 + (char)190 + (char)190
+ (char)190 + (char)190 + (char)190 + (char)190
+ (char)190 + (char)190 + (char)190 + (char)190
+ (char)190 + (char)190 + (char)190 + (char)190
+ (char)190 + (char)190 + (char)190 + (char)190;
static final String BULLET_POWER_TABLE = ""
//0 * 127
+ BP190 + BP190
+ BP0 + BP0 + BP0 + BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0
//1 * 127
+ (char)175 + (char)150 + (char)150 + (char)150
+ (char)150 + (char)150 + (char)150 + (char)150
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ BP0 + BP0 + BP0 + BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0
/* + (char)175 + (char)150 + (char)150 + (char)150
+ (char)150 + (char)150 + (char)150 + (char)150
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)170 + (char)170 + (char)170 + (char)170
+ (char)0 + (char)0 + (char)0 + (char)0
+ BP0 + BP0 + BP0
+ (char)0 + (char)0 + (char)0 + (char)0
+ (char)0 + (char)0 + (char)0*/
//2 * 127
+ LOW_MID_ENERGY
//3 * 127
+ LOW_MID_ENERGY
//4 * 127
+ MID_ENERGY
//5 * 127
+ MID_ENERGY
//6 * 127
+ MAIN
//7 * 127
+ MAIN
//8 * 127
+ MAIN
//9 * 127
+ MAIN
//10 * 127
+ MAIN
//11 * 127
+ MAIN
//12 * 127
+ MAIN
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0
+ BP0 + BP0 + BP0 + BP0 + BP0 + BP0 + BP0;
}