Help:Help/Code Shrinking

From RoboWiki
Jump to: navigation, search

Current

Again, I need help... Sorry, I can't seem to make anything smaller, ever... >.<

  • sniff* Elite has grown up so fast... It still sucks.
package awesomeness;

import robocode.*;
import robocode.util.*;
import java.util.Random;
import java.awt.Color;

/**
 * PwnBot - a robot by Awesomeness
 */
public class PwnBot extends AdvancedRobot {
	
	//static StringBuffer pattern = new StringBuffer("" + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)0 + (char)-8 + (char)-7 + (char)-6 + (char)-5 + (char)-4 + (char)-3 + (char)-2 + (char)-1 + (char)1 + (char)2 + (char)3 + (char)4 + (char)5 + (char)6 + (char)7 + (char)8);
	static double previousEnergy = 100d;  //Enemy energy from the last turn
	static double changeInEnergy;  //Enemy bullet detection
	static int movementDirection = 50;  //Positive or negative, determines the direction I (usually) go
	static int alternate;  //Part of my weird moving system
	static Random generator = new Random(); //This makes random numbers
	
	/**
	 * run: PwnBot's default behavior
	 */
	public void run() {
		
		// body = black, gun = white, radar = red
		//setColors(Color.black, Color.gray, Color.orange);
		//setBulletColor(Color.yellow);
		
		setAdjustGunForRobotTurn(true);
		
		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
	public void onScannedRobot(ScannedRobotEvent e) {
		
		
		//The absolute bearing, this is used a lot
		double absoluteBearing = e.getBearingRadians();
		
		///////////////////////////////////////////////////////
		////////////////////Movement Code//////////////////////
		
		//If there's a change in energy, it probably fired

		
		if ((changeInEnergy = previousEnergy - (previousEnergy = e.getEnergy())) > 0d && changeInEnergy<=4) {
			i();
			alternate ++;
			if (alternate > generator.nextInt(5)) {
				i();
				alternate = 0;
			}
		}
		System.out.println(e.getDistance());
		
							
		// Stay at right angles to the opponent	
		//setTurnRight(e.getBearing()+90d);
		setTurnRightRadians(Math.cos(absoluteBearing+(1/e.getDistance())*movementDirection)); // Simonton-ish way. one byte smaller	
	
		
		//setMaxVelocity(8);
		
		setAhead(movementDirection*(Math.random()-0.2)*5);
		 
		previousEnergy = e.getEnergy();
		
		////////////////////Movement Code//////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		///////////////////////Gun Code////////////////////////
		
		//Pretty simple...  Just linear
		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing += getHeadingRadians()) - 
    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    		absoluteBearing) / 13.2)));

		
		///////////////////////////////////////////////////////////
		// Edit:  I'm probably not going to put the SPM in       //
		// If I can't find the space.  I'm not going to even try //
		// customizing it to suit my bot until then, because the //
		// modified version will be inevitably larger... =(      //
		///////////////////////////////////////////////////////////
		
		//Thanks to FunkyChicken for the basis of my new gun code!
		
		//rounding to be more accurate in projection!
		/*pattern.insert(0, (char)(Math.round(Math.sin(e.getHeadingRadians() -
			(absoluteBearing = absoluteBearing + getHeadingRadians()))*e.getVelocity())));

		int index=0, searchlength = 30;
		//lol, if I ever make a haiku pattern-matcher, this will be in it:
		while ((index = pattern.toString().indexOf(pattern.substring(0, searchlength--), 1)) < 0);
		
		//searchlength will now become the index of the StringBuffer that I will project back to (back because my pattern 
		//is stored backward).
		double power;
		double dist = e.getDistance();
		searchlength =  index - (int)((dist)/(20-(power = 2)*3));
		
		//just add the offset to the bearing instead of making a new variable!
		//The fact that this actually reconstructs future movement (like a normal pattern-matcher does) probably makes this
		//just about the most accurate current nano pattern-matcher (except possibly Kakuru's, since it uses doubles instead of
		//characters).  The nice thing about it is that it correctly projects patterns even if I'm at a different distance than
		//when I collected the pattern.
		do
		{
			absoluteBearing += Math.asin(((byte)pattern.charAt(index--))/dist);
		}
		while (index >= Math.max(0, searchlength));
		
		setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));*/
		setFire(2);


		
		///////////////////////Gun Code////////////////////////
		///////////////////////////////////////////////////////
		
		
		
		///////////////////////////////////////////////////////
		/////////////////////Radar Code////////////////////////
			
		setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
		
		
		/////////////////////Radar Code////////////////////////
		///////////////////////////////////////////////////////	
		
	
		
	}

	public void onHitWall(HitWallEvent e) {
		i();
	}
	
	public void i() {
		movementDirection = -movementDirection;
	}
}

I'm sure you can get at least 50 bits out of this... It's 234 right now. If it gets small enough, I might be able to fit a modified pattern matcher in. Ugh, I feel like I'm just 'the annoying guy who needs help all the time' on this wiki sometimes... Awesomeness 23:57, 20 January 2010 (UTC)

I'll look into trimming it more in a moment, but right now that compiles as 224 codesize for me, not 234. --Rednaxela 00:46, 21 January 2010 (UTC)

Odd... Are you using Jikes? I use Javac. But I have a Mac, so maybe the compiler on Macs is different. Awesomeness 00:55, 21 January 2010 (UTC)
I've found that JavaC makes much more efficient code than Jikes - and it crashes less often :). I'll take a look at this tonight. I know I can find a few bytes for you. Off the top, I've recently created a more efficient (and accurate) energy drop detector in LittleBlackBook. It goes like this:
// Some incredibly silly and complex code.  We need to only dodge if the change in energy is between 0.1 and 3.0.  
// A basic if is expensive. So we cast to char (which makes negative numbers go huge positive as chars are unsigned) 
// then compare against this wrapped value.  We reverse this so that 0 is ignored in the compare and are forced 
// to use floor to change -(0.1 - 0.9) to -1 (otherwise it changes them to 0 which I find strange.)

    if((char)Math.floor(-enemyEnergy  + (enemyEnergy = e.getEnergy())) >= 65535-3)
    {
        // Do movement/dodge code
    }
Newer version - smaller yet and more accurate.
    if( (char) ((enemyEnergy - 1.09  - (enemyEnergy = e.getEnergy()))) < 2)
Another version - smaller yet and less accurate.
    if( (char) ((enemyEnergy - 1  - (enemyEnergy = e.getEnergy()))) <= 2)


New nano tech here just invented 2 days ago. :)

After that, you have WAY too many local vars. You can use 2 at most efficiently. After that, they get expensive to use, though the Java compiler will sometimes reuse vars for you if it can. Also, you power calculator can be done in a recent robocode.util() class for much cheaper I believe. Also, you are assigning enemyEnergy twice. Use my code there and get rid of both yours for a very large codesize decrease. --Miked0801 01:17, 21 January 2010 (UTC)

I just tried and the smallest I could make that code while maintaining the same funcionality exactly, and got to 194 codesize. With the pattern matcher I could only go as low as 301 codesize. That "alternate" behavior is simply too codesize heavy to fit on alongside a PM gun, plus the random in the setAhead() doesn't exactly help codesize and I suspect has minimal effect in practice. I'll post my attempt at reducing it's codesize if you want me to. --Rednaxela 02:40, 21 January 2010 (UTC)

Smallest I can do with I think the same functionality I believe is 191 codesize (assume Miked's code above is correct). Adding some SPM (Simonton's one which I found is the smallest one) I can get it at 271 codesize. If you don't care about the accuracy of gun (without setAdjust...) and firing detecting (use all energy drop detected), you can get version with SPM at 258 codesize... I know it is really annoying when it just barely above the limit, but here is my code. Perhaps some other can look and squeeze more.

I'm jealous... On my computer the codesize is always bigger for some reason... I guess it's because the Mac javac is different or something? It's 262 for me. I'll try compiling with Jikes and I'll see what happens. Awesomeness 12:43, 21 January 2010 (UTC)
I have been always use Eclipse to compile my robot. It give less codesize than normal javac and sometimes jikes. --Nat Pavasant 13:43, 21 January 2010 (UTC)
package awesomeness;

import robocode.AdvancedRobot;
import robocode.HitWallEvent;
import robocode.ScannedRobotEvent;
import robocode.util.Utils;

/**
 * PwnBot - a robot by Awesomeness
 */
public class PwnBot extends AdvancedRobot {
	
	static double previousEnergy = 100d;  //Enemy energy from the last turn
	static int movementDirection = 50;  //Positive or negative, determines the direction I (usually) go
	static int alternate;  //Part of my weird moving system
	
	/**
	 * run: PwnBot's default behavior
	 */
	public void run() {
		// 5 codesize gun accuracy
//		setAdjustGunForRobotTurn(true);
		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
	public void onScannedRobot(ScannedRobotEvent e) {
		int matchLen = 30;
		//The absolute bearing, this is used a lot
		double absoluteBearing;
		double dist;
		int matchPos;
		
		///////////////////////////////////////////////////////
		////////////////////Movement Code//////////////////////
		
		//If there's a change in energy, it probably fired
		// 8 codesize fire detection
//		if ((char)Math.floor(-previousEnergy  + (previousEnergy = e.getEnergy())) >= 65532 && ++alternate <= (Math.random()*5d)) {
		if (previousEnergy > (previousEnergy = e.getEnergy()) && ++alternate <= (Math.random() * 5)) {
			onHitWall(null);
		}
		
//		setTurnRightRadians(Math.cos((absoluteBearing = e.getBearingRadians())+(1/(e.getDistance()))*movementDirection)); // Simonton-ish way. one byte smaller	
//		Uncomment following line and comment above line for SPM
		setTurnRightRadians(Math.cos((absoluteBearing = e.getBearingRadians())+(1/(dist=e.getDistance()))*movementDirection)); // Simonton-ish way. one byte smaller	
		
		setAhead(movementDirection*(Math.random()-0.2)*5);
		
		////////////////////Movement Code//////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		///////////////////////Gun Code////////////////////////
		
		//Pretty simple...  Just linear
//		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing += getHeadingRadians()) - 
//    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
//    		absoluteBearing) / 13.2)));
		
		// Eric Simonton's Pattern Matching
		int i;
		// String enemyHistory = this.enemyHistory;
		enemyHistory = String.valueOf(
				(char) ((e.getVelocity() * Math.sin(e.getHeadingRadians()
						- (absoluteBearing += getHeadingRadians()))))).concat(enemyHistory);
		while ((matchPos = enemyHistory.indexOf(enemyHistory.substring(0,
				matchLen--), i = (int) (dist / 14D))) < 0)
			;
		do
			absoluteBearing += (short) enemyHistory.charAt(--matchPos) / dist;
		while (--i > 0);
		setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing
				- getGunHeadingRadians()));
		setFire(2);
		
		///////////////////////Gun Code////////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		/////////////////////Radar Code////////////////////////
			
		setTurnRadarLeft(getRadarTurnRemaining());
		
		/////////////////////Radar Code////////////////////////
		///////////////////////////////////////////////////////
	}

	public void onHitWall(HitWallEvent e) {
		movementDirection = -movementDirection;
		alternate = 0;
	}
	
	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) 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) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 2 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 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) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0 + (char) 0
	+ (char) 0 + (char) 0 + (char) 0 + (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) 0 + (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) 0; /* */
}

Why doesn't commenting this and redefining dist the next time it's used work? When I get rid of the back up code, the gun totally screws up. I don't want the back up code anymore because it gets stuck at the wall and corners a lot. Is it screwing with the absolute bearing somehow?

setTurnRightRadians(Math.cos((absoluteBearing = e.getBearingRadians())/*+(1/(dist=e.getDistance()))*movementDirection*/)); // Simonton-ish way. one byte smaller

Awesomeness 22:00, 21 January 2010 (UTC)

If you don't have that you have to change i = (int) (dist / 14D) to i = (int) ((dist=e.getDistance()) / 14D). --Nat Pavasant 09:13, 22 January 2010 (UTC)

Archive

Anyone can help me shrink the code here by 10 bytes? It is currently 759 and I have really no ideas how to shrink it more. » Nat | Talk » 05:12, 21 June 2009 (UTC)

Not mind, I manage to shrink it to 745 bytes now.

Annoying... I've made an Über-Nano bot that gets 99% against N, but I'm stuck at 283 bytes... Awesomeness 01:29, 30 April 2009 (UTC)

Post the source. I'm a past master at reducing codesize on bots. Hell, I wrote the original articles over at the repository and codesize tricks that spurred the nanobot explosion. I'd love some new blood in the nano area while I grit my teeth over Infinity/Dustbunny and how to make them just 1% better :) --Miked0801 03:56, 30 April 2009 (UTC)
Okay.
package awesomeness;

import robocode.*;
import robocode.util.*;
import java.util.Random;
import static robocode.util.Utils.normalRelativeAngleDegrees;
//import java.awt.Color;

/**
 * Elite - a robot by Awesomeness
 */
public class Elite extends AdvancedRobot {
	
	int previousEnergy = 100;
	int count;
	int countAdd;// The amount to add to the count
	byte movementDirection = 1;
	byte alternate;
	Random generator = new Random(); //This makes random numbers
	
	/**
	 * run: Elite's default behavior
	 */
	public void run() {
		
		setAdjustRadarForGunTurn(true);
		setAdjustGunForRobotTurn(true);
		
		
		// After trying out your robot, try uncommenting the import at the top,
		// and the next line:
		//setColors(Color.red,Color.blue,Color.green);
		while(true) {
			turnRadarRightRadians(Double.POSITIVE_INFINITY);
		}
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
	public void onScannedRobot(ScannedRobotEvent e) {
		
		//The absolute bearing, this is used a lot
		double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
		
		///////////////////////////////////////////////////////
		////////////////////Movement Code//////////////////////
		
		//If there's a change in energy, it probably fired
		int changeInEnergy = previousEnergy- (int) e.getEnergy();
		
		if (changeInEnergy>0 && changeInEnergy<=4) {
			alternate();
		}
		
							
		// Stay at right angles to the opponent	
		setTurnRight(e.getBearing()+90/*-5*movementDirection*/);	
		
		countAdd += (generator.nextInt(2)*2-1) * 3;
	
		count += countAdd;
		
		setMaxVelocity(8);
		
		
		setAhead(50*movementDirection);
		
		// Track the energy level
		previousEnergy = (int) e.getEnergy();
		
		////////////////////Movement Code//////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		///////////////////////Gun Code////////////////////////
		
		//Pretty simple...
		setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - 
    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    		absoluteBearing) / 13.2)));
		if (getGunHeat() == 0) { // Only try to fire if we can-
			setFire(2.0); // otherwise we do much worse
		}
		
		///////////////////////Gun Code////////////////////////
		///////////////////////////////////////////////////////
		
		
		
		///////////////////////////////////////////////////////
		/////////////////////Radar Code////////////////////////
			
		setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
		
		
		/////////////////////Radar Code////////////////////////
		///////////////////////////////////////////////////////	
		
		
		
	}
	public void onHitWall(HitWallEvent e) {
		i();
	}
	
	public void i() {
		setMaxVelocity(1);
		movementDirection = (byte) -movementDirection;
	}
	public void alternate() {
		i();//Length: 276
		alternate = (byte) -alternate;
		if (alternate == 1) {
			i();
		}
	}
}

Edit: WAIT A SEC! I FORGOT TO DELETE PART OF MY OLD COUNTING CODE! What if I delete it? I hope it'll be enough! Awesomeness 11:33, 30 April 2009 (UTC) Okay, changed the code. 278 bytes.... lol Awesomeness 11:44, 30 April 2009 (UTC)

What's count and countAdd use for? Here is my version that do exactly same as your. except that it 233 bytes (with javac)

package awesomeness;

import robocode.*;
import robocode.util.*;
import java.util.Random;
import static robocode.util.Utils.normalRelativeAngleDegrees;
//import java.awt.Color;

/**
 * Elite - a robot by Awesomeness
 */
public class Elite extends AdvancedRobot {
	
	static double previousEnergy = 100;
	static int count;
	static int countAdd;// The amount to add to the count
	static int movementDirection = 50;
	static int alternate;
	static Random generator = new Random(); //This makes random numbers
	
	/**
	 * run: Elite's default behavior
	 */
	public void run() {
		setAdjustGunForRobotTurn(true);
		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
	public void onScannedRobot(ScannedRobotEvent e) {
		
		//The absolute bearing, this is used a lot
		double absoluteBearing = e.getBearingRadians();
		
		///////////////////////////////////////////////////////
		////////////////////Movement Code//////////////////////
		
		//If there's a change in energy, it probably fired
		double changeInEnergy = previousEnergy - e.getEnergy();
		
		if (changeInEnergy>0d && changeInEnergy<=4d) {
			i();
			alternate = -alternate;
			if (alternate == 1) {
				i();
			}
		}
		
							
		// Stay at right angles to the opponent	
		//setTurnRight(e.getBearing()+90d);
		setTurnRightRadians(Math.cos(absoluteBearing)); // Simonton-ish way. one byte smaller	
	
		count += (countAdd += (generator.nextInt(2)*2-1) * 3);
		
		setMaxVelocity(8);
		
		setAhead(movementDirection);
		
		// Track the energy level
		previousEnergy = e.getEnergy();
		
		////////////////////Movement Code//////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		///////////////////////Gun Code////////////////////////
		
		//Pretty simple...
		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing += getHeadingRadians()) - 
    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    		absoluteBearing) / 13.2)));
		if (getGunHeat() == 0d) { // Only try to fire if we can-
			setFire(2d); // otherwise we do much worse
		}
		
		///////////////////////Gun Code////////////////////////
		///////////////////////////////////////////////////////
		
		
		
		///////////////////////////////////////////////////////
		/////////////////////Radar Code////////////////////////
			
		setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
		
		
		/////////////////////Radar Code////////////////////////
		///////////////////////////////////////////////////////	
		
		
		
	}
	public void onHitWall(HitWallEvent e) {
		i();
	}
	
	public void i() {
		setMaxVelocity(1);
		movementDirection = -movementDirection;
	}
}

» Nat | Talk » 16:54, 30 April 2009 (UTC)

I took a quick stab at this. Note that static variables take up less room than instance variables, for whatever reason. But Nat, he wants previousEnergy set to 100 at start of each round, and count and countAdd set to 0, so switching those to static would require setting the value in run() -- not sure which is smaller. I think movementDirection and alternate keeping their values from previous round should not be a performance hit, and will save codesize.

package awesomeness;

import robocode.*;
import robocode.util.*;
import java.util.Random;
import static robocode.util.Utils.normalRelativeAngleDegrees;
//import java.awt.Color;

/**
 * Elite - a robot by Awesomeness
 */
public class Elite extends AdvancedRobot {

    int previousEnergy = 100;
    static byte movementDirection = 1;
    static byte alternate;
    static Random generator = new Random(); //This makes random numbers

    /**
     * run: Elite's default behavior
     */
    public void run() {

        setAdjustRadarForGunTurn(true);
        setAdjustGunForRobotTurn(true);


        // After trying out your robot, try uncommenting the import at the top,
        // and the next line:
        //setColors(Color.red,Color.blue,Color.green);
        while(true) {
            turnRadarRightRadians(Double.POSITIVE_INFINITY);
        }
    }

    /**
     * onScannedRobot: What to do when you see another robot
     */
    public void onScannedRobot(ScannedRobotEvent e) {

        //The absolute bearing, this is used a lot
        double absoluteBearing;

        ///////////////////////////////////////////////////////
        ////////////////////Movement Code//////////////////////

        //If there's a change in energy, it probably fired
        int changeInEnergy;

        // Voidious: ugly as it is, I *think* this will execute in right order
        if ((changeInEnergy = previousEnergy - (previousEnergy = (int) e.getEnergy()))>0 &&
            changeInEnergy<=4) {
            i();//Length: 276
            alternate = (byte) -alternate;
            if (alternate == 1) {
                i();
            }
        }


        // Stay at right angles to the opponent
        setTurnRight(e.getBearing()+90/*-5*movementDirection*/);

        setMaxVelocity(8);

        setAhead(50*movementDirection);

        ////////////////////Movement Code//////////////////////
        ///////////////////////////////////////////////////////

        ///////////////////////////////////////////////////////
        ///////////////////////Gun Code////////////////////////

        //Pretty simple...
        setTurnGunRightRadians(Utils.normalRelativeAngle(
            (absoluteBearing = getHeadingRadians() + e.getBearingRadians()) -
            getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() -
            absoluteBearing) / 13.2)));
//        if (getGunHeat() == 0) { // Only try to fire if we can-
            setFire(2.0); // otherwise we do much worse
                          // Voidious: what side effect to setFire if you can't?
                          //           I didn't think there was any.
//        }

        ///////////////////////Gun Code////////////////////////
        ///////////////////////////////////////////////////////



        ///////////////////////////////////////////////////////
        /////////////////////Radar Code////////////////////////

        setTurnRadarLeftRadians(getRadarTurnRemainingRadians());


        /////////////////////Radar Code////////////////////////
        ///////////////////////////////////////////////////////



    }
    public void onHitWall(HitWallEvent e) {
        i();
    }

    public void i() {
        setMaxVelocity(1);
        movementDirection = (byte) -movementDirection;
    }

    // Voidious is "*= -1" smaller than "var = (byte)-var"? seems like it
    // would be (both in i() and alternate(), which was moved)
}

I haven't compiled that, but I think everything there is basic and will work. There's surely more that can be done, but I hit most of the obvious stuff. Good luck. =) --Voidious 16:22, 30 April 2009 (UTC)

Er, yeah, sorry, that count stuff is definitely not doing anything, and should save you more than 5 bytes. (Updated my code there.) You can also compile with Jikes if you use an older version of robocode.jar, that might save some bytes too. --Voidious 16:31, 30 April 2009 (UTC)

No, the var = -var is the smallest. I see no point to use byte when the memory isn't in issue. The integer should take smaller codesize since it need not to be promoted to each operation. And by assign the 50 to movementDirection instead of multiply by 50 should saves around 1 or 2 bytes (or 3? I not sure) And what is alternate necessary? It always be zero... Anyway, Here my new code. Got rid off the count thing and using the energy system Voidious posted, this version cost 202 bytes with javac and 205 with Jikes (!!): » Nat | Talk » 16:54, 30 April 2009 (UTC)

package awesomeness;

import robocode.*;
import robocode.util.*;
import java.util.Random;
//import static robocode.util.Utils.normalRelativeAngleDegrees;
//import java.awt.Color;

/**
 * Elite - a robot by Awesomeness
 */
public class Elite extends AdvancedRobot {
	
	double previousEnergy = 100d;
	//int count;
	//int countAdd;// The amount to add to the count
	static int movementDirection = 50;
	static int alternate;
	//static Random generator = new Random(); //This makes random numbers
	
	/**
	 * run: Elite's default behavior
	 */
	public void run() {
		setAdjustGunForRobotTurn(true);
		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
	public void onScannedRobot(ScannedRobotEvent e) {
		
		//The absolute bearing, this is used a lot
		double absoluteBearing = e.getBearingRadians();
		
		///////////////////////////////////////////////////////
		////////////////////Movement Code//////////////////////
		
		//If there's a change in energy, it probably fired
		double changeInEnergy;
		
		if ((changeInEnergy = previousEnergy - (previousEnergy = e.getEnergy())) > 0d && changeInEnergy<=4) {
			i();
			alternate = -alternate;
			if (alternate == 1) {
				i();
			}
		}
		
							
		// Stay at right angles to the opponent	
		//setTurnRight(e.getBearing()+90d);
		setTurnRightRadians(Math.cos(absoluteBearing)); // Simonton-ish way. one byte smaller	
	
		//count += (countAdd += (generator.nextInt(2)*2-1) * 3);
		
		//setMaxVelocity(8);
		
		setAhead(movementDirection);
		
		// Track the energy level
		previousEnergy = e.getEnergy();
		
		////////////////////Movement Code//////////////////////
		///////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////
		///////////////////////Gun Code////////////////////////
		
		//Pretty simple...
		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing += getHeadingRadians()) - 
    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    		absoluteBearing) / 13.2)));
		if (getGunHeat() == 0d) { // Only try to fire if we can-
			setFire(2d); // otherwise we do much worse
		}
		
		///////////////////////Gun Code////////////////////////
		///////////////////////////////////////////////////////
		
		
		
		///////////////////////////////////////////////////////
		/////////////////////Radar Code////////////////////////
			
		setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
		
		
		/////////////////////Radar Code////////////////////////
		///////////////////////////////////////////////////////	
		
		
		
	}
	public void onHitWall(HitWallEvent e) {
		i();
	}
	
	public void i() {
		//setMaxVelocity(1);
		movementDirection = -movementDirection;
	}
}
Just found out that setMaxVelocity isn't need since it will get override, so now 190 bytes (javac) » Nat | Talk » 16:58, 30 April 2009 (UTC)

Some improvements, codesize down to 173 (comments removed):

package awesomeness;
import robocode.*;
import robocode.util.*;

public class Elite extends AdvancedRobot {
	
	double previousEnergy = 100d;
	static int movementDirection;
	static int alternate;

	public void run() {
		movementDirection = 50;
		setAdjustGunForRobotTurn(true);
		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	public void onScannedRobot(ScannedRobotEvent e) {
		
		double absoluteBearing = e.getBearingRadians();
		
		double changeInEnergy;
		
		if ((changeInEnergy = previousEnergy - (previousEnergy = e.getEnergy())) > 0d && changeInEnergy<=4) {			
			if ((alternate = -alternate) != 1) {
				movementDirection = -movementDirection;
			}
		}
		
		setTurnRightRadians(Math.cos(absoluteBearing)); // Simonton-ish way. one byte smaller	
		
		setAhead(movementDirection);
		
		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing += getHeadingRadians()) - 
    		getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    		absoluteBearing) / 13.2)));
		if (getGunHeat() == 0d) {
			setFire(2d);
		}
		setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
	}
	public void onHitWall(HitWallEvent e) {
		movementDirection = -movementDirection;
	}
}

Basically:

  • it takes 1 less byte to initialize static variables in run() than when it is declared.
  • if enemy fired, i() is possibly twice, so removed 1 possible call by changing the if to if ((alternate = -alternate) != 1) and removing the call above it
  • previousEnergy = e.getEnergy() was done twice...
  • finally, after all this it's less expensive to just inline i()

But 1 question: since alternate is never initialized, won't it always be zero? --Starrynte 00:37, 5 May 2009 (UTC)



What's the best targeting system equal or less than 83 bytes long? Awesomeness 21:59, 30 April 2009 (UTC)

What kind of bot are you building? For very short range to around 200 and very long range (600+), an Infinity type gun works great. If that's too big, just standard linear aim is fine for short range. But, it all depends on what type of bots you are going up against. A bullet dodger would crush Infinity and a good stop and go would also confuse it. Heck head on firing works fine in melee beyond around 200. It even will occasionally hit dodgers and the like.

For the more advanced bots, random linear is probably your best bet. --Miked0801 22:37, 30 April 2009 (UTC)

I'm not sure but I think circular targeting can fit in. But random is better, PM is the best for nanobot. » Nat | Talk » 08:11, 1 May 2009 (UTC)

PM will not fit in my Nano, I'm sure of it. I don't know how to implement random linear. You're right, circular targeting might fit in, but I'm sure it'd be a stretch. PS: I've tweaked my code, and now its movement fools PMers and linear targeting! =) PPS: All of the different small versions of elite are making the page huge. Should we take them down?

A random, linear aim gun - assumes firepower 3 shots always. Change the /11 to fix that. Will not fire behind the targeted bot, change the random() to 1 - 1.5*random() to fix that. Yanked from Infinity w/o the decrease lead with distance code.

setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians() + 
				Math.random() * 
				Math.asin(e.getVelocity() / 11) * Math.sin(e.getHeadingRadians() - absoluteBearing) ));

--Miked0801 15:52, 1 May 2009 (UTC)

Actually, there is no need for asin. The disorted between them isn't really matter. And, no, you should not take them down. If you finsih asking help, letting me know and this page will be archived instead. » Nat | Talk » 16:39, 1 May 2009 (UTC)

Yes, FunkyChicken's PM gun on my bot easily beats many minis and ties with even a few megas, but it's 370 bytes. Awesomeness 23:34, 1 May 2009 (UTC)

I don't get it... Most guns I borrow from sample code always aim 90 degrees away from where I want it to aim. About half of the time I can fix it, (I had to fix it for myself in FunkyChicken's gun) but the other half I can't. The random linear code is in the second group.

  • Remember that zero degrees is up (North) in robocode and the direction is clockwise, not as math at school. --GrubbmGait 01:47, 2 May 2009 (UTC)
Personal tools