Continuation/Code

From Robowiki
< Continuation
Revision as of 22:20, 17 March 2026 by Sheldor2 (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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;
}