Help:Help/Code Shrinking

From Robowiki
< Help:Help
Revision as of 17:56, 30 April 2009 by Nat (talk | contribs) (Category talk:NanoBots moved to Help:Help/Code Shrinking: should not be category talk)
Jump to navigation Jump to search

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;
	}
}