Robo Home | Changes | Preferences | AllPages

You store some information in your fired bullet. Later you retrieve some information from it. I have dreamed about a "tag" member variable or so in my fired bullets.

This involves some encoding/decoding schemes.


//fires at random
double bearingOffset = Math.signum(e.getVelocity()) * (Math.random() * 10 - 2) / 11.0 * Math.sin(e.getHeadingRadians() - enemyAbsoluteBearing);
setTurnGunRightRadians(Utils.normalRelativeAngle(enemyAbsoluteBearing - getGunHeadingRadians() + bearingOffset));
setFire(2 + bearingOffset);


	public void onBulletHit(BulletHitEvent e) {
		double visitedBearingOffset = e.getBullet().getPower() - 2;
		out.println("hit: " + visitedBearingOffset);

I once encoded bearingOffset like this:
setFire(bearingOffset * 100);
But it varied BulletTravelTime. You can encode informations whatever you want like this way. e.g. using truncation, fraction digit range x-y is velocity, x2-y2 is heading, etc. Tricky!! Hahaha! But after some test, this method is proved unuseful by me at the moment. This is sort of ActualBullets? (contrary to VirtualBullets) and slow learing.

You can minimize side effects by reducing magnitude of the data. For example, instead of

setFire(2 + bearingOffset);
setFire(2 + bearingOffset / 100);
And when retrieving,
visitedBearingOffset = (e.getBullet().getPower() - 2) * 100;

-- Stelokim

That would limit you to about 30 or so angles, as bullet power is stored as a number with a single decimal place between 0.1 and 3. --Chase-san

Not really. Bullet power has not only a single decimal place. Its minimum is 0.1 but it has type double's precision. Also check out MaxEscapeAngle. And use divisor 1000, 10000, or 100000, etc. No hard limit!! -- Stelokim

Then why don't you start with an integer and use binary to store all the data you need into it, and then cast it toa double and set it as below the decil line. such that if it was 65535, you do (double)65535/1000000d = 0.065535, then you can still have your power management. Look in FoldedPatternMatcher for implimentation (it turns it into a symbol). You can look [here] for more information on bitwise operators. --Chase-san

Thank you for good information. -- Stelokim

Just gotta figure out a way to store the origin, time fired and direction. You could just chop and place it, isntead of using complex binary operations(though, they might be more exact.

Lets see a double can store a value of this many values X.XXXXXXXXXXXXXXX, thus that leaves you with 0.0XXXXXXXXXXXXXX, or 14 places to deal with, I would mully that down to 12 to try and make up for java rounding errors.

Thus 0.0XXXXXXXXXXXX00, so you take your data and cut it maybe like so.

  X    Y   fired  direction

for the x and y is just a integer of the x and y position, fired is the time the bullet was fired, and the direction is the direction of movement+1 (0 meaning counterclockwise and 2 meaning clockwise). Then you can calculate the maxEcape angle and so on.


Here is some code to do this:

public double encodeBulletPower(double power, double x, double y,
		long time, double direction) {
	power = getPure(power);
	power += Math.round(x)/1e4 + Math.round(y)/1e7;
	power += Math.round(time)/1e12;
	power += (direction > 0) ? 1e-13 : 0; 
	return power;
public double getPure(double p) {
	return Math.round(p*10.0)/10.0;
public String getEncodedString(double p) {
	return String.valueOf((p-getPure(p))*1e13);
public double getSourceX(Bullet b) {
	String power = getEncodedString(b.getPower());
	return (int)(Double.valueOf(power.substring(0,4))*100.0);
public double getSourceY(Bullet b) {
	String power = getEncodedString(b.getPower());
	return Double.valueOf(power.substring(4,7)).intValue();
public long getShotTime(Bullet b) {
	String power = getEncodedString(b.getPower());
	return Double.valueOf(power.substring(7,12)).longValue();
public int getDirection(Bullet b) {
	String power = getEncodedString(b.getPower());
	return (Double.valueOf(power.substring(12,13))==0?-1:1);
public double getEscapeAngle(Bullet b) {
	return Math.asin(8/b.getVelocity())*getDirection(b);
public double getDistanceTraveled(Bullet b) {
	return Point2D.distance(b.getX(), b.getY(), getSourceX(b), getSourceY(b));
public double getDistanceTravelTime(Bullet b, long time) {
	return b.getVelocity()*(time-getShotTime(b));
I think those work, tell me if I got something wrong (and please test it first, just don't eyeball it)) --Chase-san

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited February 2, 2007 3:54 EST by Chase-san (diff)