Difference between revisions of "Talk:Kitten"

From Robowiki
Jump to navigation Jump to search
m (Using <syntaxhighlight>.)
 
(16 intermediate revisions by 6 users not shown)
Line 3: Line 3:
  
 
Ah, I'm enlightened. :) First codesize-reducing tip: (I haven't looked at the code yet) Use WeekendObsession's gun instead of Assertive's which is Funkychicken's which is... etc. :D I suggest looking at BlackWidow 1.3's code. It's very tidy and well-commented and it has WeekendObsession's gun. You will gain some bytes and the execution of your bot will be a lot faster. :) StringBuffers are very slow, at least use StringBuilder. --[[User:Robar|HUNRobar]] 08:28, 18 June 2009 (UTC)
 
Ah, I'm enlightened. :) First codesize-reducing tip: (I haven't looked at the code yet) Use WeekendObsession's gun instead of Assertive's which is Funkychicken's which is... etc. :D I suggest looking at BlackWidow 1.3's code. It's very tidy and well-commented and it has WeekendObsession's gun. You will gain some bytes and the execution of your bot will be a lot faster. :) StringBuffers are very slow, at least use StringBuilder. --[[User:Robar|HUNRobar]] 08:28, 18 June 2009 (UTC)
 +
 +
 +
To be more exact, use String instead of StringBuilder/Buffer gain 2 bytes (or 3? IIRC, 2). Sqyeezed code (it have really much to squeeze so I don't wanna list it, doing the code diff if you want):
 +
<syntaxhighlight>
 +
package spinnercat;
 +
 +
import robocode.*;
 +
import robocode.util.Utils;
 +
 +
public class Kitten extends AdvancedRobot {
 +
static String pattern = "00000000000000000000000000000";
 +
 +
public void run(){
 +
// have this out will gain you 5 bytes,
 +
// and gain you more score if your gun isn't tuned up to be very accurate.
 +
// setAdjustGunForRobotTurn(true);
 +
setTurnRadarRight(Double.POSITIVE_INFINITY);
 +
}
 +
 +
public void onScannedRobot(ScannedRobotEvent e){
 +
        double absBearing;
 +
int matchLength = 30; //try out other numbers?
 +
      // Answer: try near 45, at last I didn't found any difference of them...
 +
double dist;
 +
 +
if(setFireBullet(3) != null || getDistanceRemaining() == 0){
 +
setTurnRightRadians(Math.cos(absBearing = e.getBearingRadians())+(2*Math.random()-1)*.5);
 +
setAhead((Math.random()<.5?1:-1)*(Math.random()/2+.5)*(dist/4));
 +
}
 +
 +
setTurnRadarLeftRadians(getRadarTurnRemaining());
 +
 +
pattern = String.valueOf((char)(int)(e.getVelocity()*Math.sin(e.getHeadingRadians() - (absBearing += getHeadingRadians())))).concat(pattern);
 +
 +
int index;
 +
while ((index = pattern.indexOf(pattern.substring(0, matchLength--), 1)) < 0);
 +
 +
matchLength = index - (int)(( dist = e.getDistance()) / 11);
 +
 +
do
 +
absBearing += ((double)(byte)pattern.charAt(index--) / dist);
 +
while (index >= Math.max(0, matchLength));
 +
 +
setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing - getGunHeadingRadians()));
 +
}
 +
}
 +
</syntaxhighlight>
 +
Not test yet, but I think it will be compilable. Anyway, I think WeekendsObsession's is smaller by around 2-3 bytes. And don't mind the move of setFireBullet to be before the gun turn, the turn will not be execute until the next tick so if you turn and fire at the same tick, not matter the order are, it still execute the same. (hope this make sense) 12:23, 18 June 2009 (UTC)
 +
 +
 +
Actually, for repeated appending, StringBuffer is FAR faster than a normal String once the string gets large! This is because a normal String will have to re-allocate a bigger chunk of memory, and re-copy EVERYTHING every time the string goes past container size. The reason that the FunkyChicken gun is slow, is because of <code>enemyLog.toString().indexOf()</code>, because that forces it to re-copy the string every tick no matter what, which is worse than the occasional re-copy that String appending forces. Funny thing is, StringBuffer has it's own indexOf() method, so really, that line in the various FunkyChicken guns should really be <code>enemyLog.indexOf()</code>, which is both slightly lower codesize AND will make the gun have less spikes in time used than WeekendObsession, due to any and all re-copies being totally eliminated. --[[User:Rednaxela|Rednaxela]] 12:46, 18 June 2009 (UTC)
 +
 +
I think that for nano/micro, the [[codesize]] is more important. And String is cheaper than StringBuffer/Builder in term of codesize. For FunkyChicken, IIRC, I think that time StringBuffer/Builder doesn't have indexOf() yet. but using of StringBuffer is not really recommended, consider use of StringBuilder instead. Or it will be around 6 times slower during the synchronization. &raquo; <span style="font-size:0.9em;color:darkgreen;">[[User:Nat|Nat]] | [[User_talk:Nat|Talk]]</span> &raquo; 13:01, 18 June 2009 (UTC)
 +
 +
If you intend to keep your distance at a roughly fixed length, [[Moebius]]'s gun is nice and cheaper than the standard gun.  And I just don't recall on the string/stringbuilder/stringbuffer conversation which was better.  :P  --[[User:Miked0801|Miked0801]] 13:10, 18 June 2009 (UTC)
 +
 +
: Why don't you join it? &raquo; <span style="font-size:0.9em;color:darkgreen;">[[User:Nat|Nat]] | [[User_talk:Nat|Talk]]</span> &raquo; 13:18, 18 June 2009 (UTC)
 +
:: Because robocode isn't allowing me to see the original source for some reason.  It also is failing to read LBB source too.  Weird.  I guess I could uncompile it, but it'd be better if I had original source... --[[User:Miked0801|Miked0801]] 14:35, 18 June 2009 (UTC)
 +
 +
:: BTW, I can say that the original string define needs a larger starting string or you will get outOfIndex() issues in the first round if bots are too far away - like your bots tend to do ;)  Just put another 20 characters in it.  --[[User:Miked0801|Miked0801]] 14:37, 18 June 2009 (UTC)
 +
 +
The String/Builder/Buffer thing. Each person use what he/she likes ;) But I must say, using StringBuffer over StringBuilder seem really silly since the usage is really the same, as did the API =) My point is, use String in nano/micro robot and use StringBuilder in mini/mega, micro if you can fit. &raquo; <span style="font-size:0.9em;color:darkgreen;">[[User:Nat|Nat]] | [[User_talk:Nat|Talk]]</span> &raquo; 13:18, 18 June 2009 (UTC)
 +
 +
Yes, I've only used StringBuilder in my code. I forgot what the difference with StringBuffer is briefly. I revise my recommendation with a FunkyChicken gun, to be change the Buffer to Builder, AND get rid of the unneeded toString(), then you get something between the codesize of a FunkyChicken and a WeekendObsession, and with no spikes in time used (meaning, lowest chance of skipped turns if you use a lot of cpu in the bot) --[[User:Rednaxela|Rednaxela]] 13:24, 18 June 2009 (UTC)
 +
 +
Ok, got your java file with another app.  Reading it now.  Here's some running comments:
 +
* You have too many local variables.  You get 2 java registers, after that, each additional one costs you quite a bit in push/pop byte codes.  Reuse, reuse.
 +
* Always prefer ints over doubles - and ints between -1 and 5 are best.  They take 1 byte to store.
 +
* Static final vars are much easier to play with when tweaking and cost nothing.
 +
* Get a better gun.  This one is bigger than it should be.
 +
 +
Here's my first pass - keeping your (nearly) exact functionality.  Saved 3 bytes.  BTW, this file started out on my local system at 252 bytes - according to my system, this wasn't a nano to begin with.  You must have a better compiler than me :)
 +
<syntaxhighlight>
 +
package spinnercat;
 +
 +
import robocode.AdvancedRobot;
 +
import robocode.ScannedRobotEvent;
 +
import robocode.util.Utils;
 +
 +
public class Kitten extends AdvancedRobot
 +
{
 +
  static StringBuffer pattern = new StringBuffer("00000000000000000000000000000123456788888888888888886420123456786420123456786420");
 +
  static double energy;
 +
 +
  public void run()
 +
  {
 +
    setTurnRadarRight((1.0D / 0.0D));
 +
    setAdjustGunForRobotTurn(true);
 +
  }
 +
 +
  public void onScannedRobot(ScannedRobotEvent e) {
 +
    int depth = 30;
 +
    double dist = e.getDistance();
 +
    double absBearing = e.getBearingRadians() + getHeadingRadians();
 +
    pattern.insert(0, (char)(int)(e.getVelocity() * Math.sin(e.getHeadingRadians() - absBearing)));
 +
 +
    int index; // Save 2 bytes moving to here
 +
    while ((index = pattern.toString().indexOf(pattern.substring(0, depth--), 1)) < 0);
 +
    depth = index - (int)(dist / 11);
 +
    do
 +
    {
 +
      absBearing += (byte)pattern.charAt(index--) / dist; }
 +
    while (index >= Math.max(0, depth)); // Wasteful - much better guns out there to get rid of Math.max() call here.
 +
 +
    setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing - getGunHeadingRadians()));
 +
    setFire(3); // Saves 1 byte
 +
 +
    if (energy - (Kitten.energy = e.getEnergy()) > 0)
 +
    {
 +
      dist = Math.signum(Math.random() - 0.5D); // Looks alot like LittleBlackBook here :)
 +
      setAhead(100 * (dist)); // Assigning in place saves nothing
 +
      setMaxVelocity(8 * (Math.random() + 0.5D)); // This is really expensive for what it does, use setAhead() variences in distance instead.
 +
      setTurnRightRadians(e.getBearingRadians() + Math.PI/2 - ((Math.random() * dist) / 4)); //Off by 4.5% of your code - change the divide by 4 to 3.82 for exact.
 +
 +
  // Similiar would be (and 1 byte smaller) and you won't spin in place as much
 +
  //  setTurnRightRadians(Math.cos(e.getBearingRadians() - ((Math.random() * dist) / 4)));
 +
    }
 +
 +
    setTurnRadarLeftRadians(getRadarTurnRemaining());
 +
  }
 +
}
 +
</syntaxhighlight> 
 +
--[[User:Miked0801|Miked0801]] 17:42, 18 June 2009 (UTC)
 +
 +
Any I would highly recommend to read and memorize this: [http://testwiki.roborumble.org/w/index.php?title=Code_Size/Cheat_sheet] --[[User:Robar|HUNRobar]] 18:30, 18 June 2009 (UTC)
 +
 +
Good job! I just might have to release a PM bot too...--[[User:CrazyBassoonist|CrazyBassoonist]] 21:47, 18 June 2009 (UTC)
 +
 +
Thanks guys, these look like great tips! I'm still working on movement, the way it gets caught on the walls is really bugging me. [[User:Spinnercat|Spinnercat]] 00:22, 19 June 2009 (UTC)
 +
 +
If you look quick, you are currently 1st with a 98+% APS score... after 1 fight with LuthorTest ;) --[[User:Miked0801|Miked0801]] 23:06, 19 June 2009 (UTC)
 +
 +
hah, well... my haiku bot was first overall after one fight too about a week ago... and that sure didn't last! [[User:Spinnercat|Spinnercat]] 23:38, 19 June 2009 (UTC)

Latest revision as of 09:34, 1 July 2010

Thanks you :) --Miked0801 01:01, 18 June 2009 (UTC)

no problem at all. Spinnercat 01:09, 18 June 2009 (UTC)

Ah, I'm enlightened. :) First codesize-reducing tip: (I haven't looked at the code yet) Use WeekendObsession's gun instead of Assertive's which is Funkychicken's which is... etc. :D I suggest looking at BlackWidow 1.3's code. It's very tidy and well-commented and it has WeekendObsession's gun. You will gain some bytes and the execution of your bot will be a lot faster. :) StringBuffers are very slow, at least use StringBuilder. --HUNRobar 08:28, 18 June 2009 (UTC)


To be more exact, use String instead of StringBuilder/Buffer gain 2 bytes (or 3? IIRC, 2). Sqyeezed code (it have really much to squeeze so I don't wanna list it, doing the code diff if you want):

package spinnercat;

import robocode.*;
import robocode.util.Utils;

public class Kitten extends AdvancedRobot {
	static String pattern = "00000000000000000000000000000";

	public void run(){
		// have this out will gain you 5 bytes,
		// and gain you more score if your gun isn't tuned up to be very accurate.
		// setAdjustGunForRobotTurn(true);
		setTurnRadarRight(Double.POSITIVE_INFINITY);
	}
	
	public void onScannedRobot(ScannedRobotEvent e){
        	double absBearing;
		int matchLength = 30; //try out other numbers?
				      // Answer: try near 45, at last I didn't found any difference of them...
		double dist;
		
		if(setFireBullet(3) != null || getDistanceRemaining() == 0){
			setTurnRightRadians(Math.cos(absBearing = e.getBearingRadians())+(2*Math.random()-1)*.5);
			setAhead((Math.random()<.5?1:-1)*(Math.random()/2+.5)*(dist/4));
		}

		setTurnRadarLeftRadians(getRadarTurnRemaining());

 		pattern = String.valueOf((char)(int)(e.getVelocity()*Math.sin(e.getHeadingRadians() - (absBearing += getHeadingRadians())))).concat(pattern);

		int index;
		while ((index = pattern.indexOf(pattern.substring(0, matchLength--), 1)) < 0);

		matchLength = index - (int)(( dist = e.getDistance()) / 11);

		do
			absBearing += ((double)(byte)pattern.charAt(index--) / dist);
		while (index >= Math.max(0, matchLength));

		setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing - getGunHeadingRadians()));
	}
}

Not test yet, but I think it will be compilable. Anyway, I think WeekendsObsession's is smaller by around 2-3 bytes. And don't mind the move of setFireBullet to be before the gun turn, the turn will not be execute until the next tick so if you turn and fire at the same tick, not matter the order are, it still execute the same. (hope this make sense) 12:23, 18 June 2009 (UTC)


Actually, for repeated appending, StringBuffer is FAR faster than a normal String once the string gets large! This is because a normal String will have to re-allocate a bigger chunk of memory, and re-copy EVERYTHING every time the string goes past container size. The reason that the FunkyChicken gun is slow, is because of enemyLog.toString().indexOf(), because that forces it to re-copy the string every tick no matter what, which is worse than the occasional re-copy that String appending forces. Funny thing is, StringBuffer has it's own indexOf() method, so really, that line in the various FunkyChicken guns should really be enemyLog.indexOf(), which is both slightly lower codesize AND will make the gun have less spikes in time used than WeekendObsession, due to any and all re-copies being totally eliminated. --Rednaxela 12:46, 18 June 2009 (UTC)

I think that for nano/micro, the codesize is more important. And String is cheaper than StringBuffer/Builder in term of codesize. For FunkyChicken, IIRC, I think that time StringBuffer/Builder doesn't have indexOf() yet. but using of StringBuffer is not really recommended, consider use of StringBuilder instead. Or it will be around 6 times slower during the synchronization. » Nat | Talk » 13:01, 18 June 2009 (UTC)

If you intend to keep your distance at a roughly fixed length, Moebius's gun is nice and cheaper than the standard gun. And I just don't recall on the string/stringbuilder/stringbuffer conversation which was better. :P --Miked0801 13:10, 18 June 2009 (UTC)

Why don't you join it? » Nat | Talk » 13:18, 18 June 2009 (UTC)
Because robocode isn't allowing me to see the original source for some reason. It also is failing to read LBB source too. Weird. I guess I could uncompile it, but it'd be better if I had original source... --Miked0801 14:35, 18 June 2009 (UTC)
BTW, I can say that the original string define needs a larger starting string or you will get outOfIndex() issues in the first round if bots are too far away - like your bots tend to do ;) Just put another 20 characters in it. --Miked0801 14:37, 18 June 2009 (UTC)

The String/Builder/Buffer thing. Each person use what he/she likes ;) But I must say, using StringBuffer over StringBuilder seem really silly since the usage is really the same, as did the API =) My point is, use String in nano/micro robot and use StringBuilder in mini/mega, micro if you can fit. » Nat | Talk » 13:18, 18 June 2009 (UTC)

Yes, I've only used StringBuilder in my code. I forgot what the difference with StringBuffer is briefly. I revise my recommendation with a FunkyChicken gun, to be change the Buffer to Builder, AND get rid of the unneeded toString(), then you get something between the codesize of a FunkyChicken and a WeekendObsession, and with no spikes in time used (meaning, lowest chance of skipped turns if you use a lot of cpu in the bot) --Rednaxela 13:24, 18 June 2009 (UTC)

Ok, got your java file with another app. Reading it now. Here's some running comments:

  • You have too many local variables. You get 2 java registers, after that, each additional one costs you quite a bit in push/pop byte codes. Reuse, reuse.
  • Always prefer ints over doubles - and ints between -1 and 5 are best. They take 1 byte to store.
  • Static final vars are much easier to play with when tweaking and cost nothing.
  • Get a better gun. This one is bigger than it should be.

Here's my first pass - keeping your (nearly) exact functionality. Saved 3 bytes. BTW, this file started out on my local system at 252 bytes - according to my system, this wasn't a nano to begin with. You must have a better compiler than me :)

package spinnercat;

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

public class Kitten extends AdvancedRobot
{
  static StringBuffer pattern = new StringBuffer("00000000000000000000000000000123456788888888888888886420123456786420123456786420");
  static double energy;

  public void run()
  {
    setTurnRadarRight((1.0D / 0.0D));
    setAdjustGunForRobotTurn(true);
  }

  public void onScannedRobot(ScannedRobotEvent e) {
    int depth = 30;
    double dist = e.getDistance();
    double absBearing = e.getBearingRadians() + getHeadingRadians();
    pattern.insert(0, (char)(int)(e.getVelocity() * Math.sin(e.getHeadingRadians() - absBearing)));

    int index; // Save 2 bytes moving to here
    while ((index = pattern.toString().indexOf(pattern.substring(0, depth--), 1)) < 0);
    depth = index - (int)(dist / 11);
    do
    {
      absBearing += (byte)pattern.charAt(index--) / dist; }
    while (index >= Math.max(0, depth)); // Wasteful - much better guns out there to get rid of Math.max() call here.

    setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing - getGunHeadingRadians()));
    setFire(3); // Saves 1 byte

    if (energy - (Kitten.energy = e.getEnergy()) > 0)
    {
      dist = Math.signum(Math.random() - 0.5D); // Looks alot like LittleBlackBook here :)
      setAhead(100 * (dist)); // Assigning in place saves nothing
      setMaxVelocity(8 * (Math.random() + 0.5D)); // This is really expensive for what it does, use setAhead() variences in distance instead.
      setTurnRightRadians(e.getBearingRadians() + Math.PI/2 - ((Math.random() * dist) / 4)); //Off by 4.5% of your code - change the divide by 4 to 3.82 for exact.

	  // Similiar would be (and 1 byte smaller) and you won't spin in place as much
	  //  setTurnRightRadians(Math.cos(e.getBearingRadians() - ((Math.random() * dist) / 4)));
    }

    setTurnRadarLeftRadians(getRadarTurnRemaining());
  }
}

--Miked0801 17:42, 18 June 2009 (UTC)

Any I would highly recommend to read and memorize this: [1] --HUNRobar 18:30, 18 June 2009 (UTC)

Good job! I just might have to release a PM bot too...--CrazyBassoonist 21:47, 18 June 2009 (UTC)

Thanks guys, these look like great tips! I'm still working on movement, the way it gets caught on the walls is really bugging me. Spinnercat 00:22, 19 June 2009 (UTC)

If you look quick, you are currently 1st with a 98+% APS score... after 1 fight with LuthorTest ;) --Miked0801 23:06, 19 June 2009 (UTC)

hah, well... my haiku bot was first overall after one fight too about a week ago... and that sure didn't last! Spinnercat 23:38, 19 June 2009 (UTC)