[Home]Moebius/Code

Robo Home | Moebius | Changes | Preferences | AllPages

Code for the bot which have been the Champion among NanoBots for a while now.
package mld;
import robocode.*;
import java.awt.Color;

//  Moebius - a robot by Michael Dorgan

// --------------------------------------------------------------------------------------------------------------------------------------------
// Revision 3-09-03 ver 1.0
//
// After very carefully studying the pattern-matching code that Albert provided to the Wiki, I've modified it slightly,
// added a pattern it has trouble hitting to my bot, and here it is - Mobius, my first effective pattern Matching aim bot.
// The parameters can be tweeked later, but for now, I'm just happy it's alive and working.  A strong 1v1 contender in
// NanoBot land.
//
// CodeSize: 248 (No colors yet)
//
// Revision 3-12-03 ver 1.01
//
// Lowered the search depth to 9.  Changed movement to exact triangle pattern as this seems even better than box.
// Freed a bunch of bytes from the pattern code and that allowed me to use a more exact value for the pattern
// match itself - the angular velocity vs the straight velocity.  Really helps when locking onto circle bots.
// Alos made room for colors (style does matter!)  Fixed the spelling of our name (thanks Dave), and a few typos in 
// the comments.  A very, very strong 1v1 Nanobot.
//
// Codesize: 249 with colors!
//
// Revision 3-17-03 ver 1.1
//
// Changed to tan() style locking to gain a few bytes back.  Removed toString() from pattern matcher as it wasn't
// needed.  Had to swtich to dirty triangle movement.  Used saved bytes to implement a fire power control system.
// This allows better survival against certain bots and helps a bit in melee.  Upped movement per leg to 170 to
// help dodge no linear/circular aim shots.  A fairly good improvement.  It survives better against all bots, but
// doesn't win as convincingly against a few it locked onto last revision.  Still, a good improvement.
//
// Codesize: 248 with colors!
//
// Revision 3-25-03 ver 1.2
//
// Radar now uses Infinity style Infinite radar.  I've also re-purposed Albert's wonderful, wonderful pattern
// matching gun for my own use.  I've shrank its codesize somewhat in the process so he can feel free to take 
// it back and have his bot do new things too (like color!)  It's also more accurate than his due to the endBufferCheck.
// I've upped my triange edge a bit to help dodge  as this is the cheapest pattern I could find that caused 
// this new system of aiming to have (just a little) problem hitting.  It's a nice melee pattern as well so I 
// may do decent there too.  I've taken out the power management stuff as it was costing me too many damage points 
// and now I'm hitting even more often so it's not needed.  So far, I've not found a single Nanobot that consistently 
// beats me - though Smog 1.5 gives me problems.  All others fall before my (borrowed and improved) Nano-Scythe 
// of destruction!!! :) 
//
// Codesize: 249 with colors!
//
// Revision 3-26-03 ver 1.3
// I've switched from box movement to orbit movement with random jerkiness thrown in to kill pattern matching.
// This pattern really gives our aim trouble, keeps us equal distance from target which improves aim quality,
// and does decent dodging in all cases.  I've done a few code tricks to optimize codespace and make room for this
// new pattern.  Basically, my death shot code got reduced by 10 shots, my aim cannon at target isn't quite as good, 
// and I still don't get adjustGun() call to help with dead bots.  Still, this bot is really awesome right now.  It 
// annihilates most and only Pinball and Graviton currently stay somewhat close.  An excellent NanoBot 1v1 specialist!
// Many thanks to Albert for this wonderful gun idea and to all other coders who have made me stretch my mind in 
// order to compete.  Thanks!
//
// Codesize: 249 with colors! (And no more room to be had that I can find!)
//
// Revision 4-25-03 ver 1.3.1
// Dieted 4 bytes using a doJob() private method which packs the often-used queries and declares variables in the
// method signature instead of in the body. Diet recepie by PEZ.
//
// Codesize: 245 with colors!
// --------------------------------------------------------------------------------------------------------------------------------------------

public class Moebius extends AdvancedRobot
{
	// Constants
	static final int 	SEARCH_DEPTH = 30;	// Increasing this slows down game execution - beware!
	static final int 	MOVEMENT_LENGTH = 150;	// Larger helps on no-aim and nanoLauLectrik - smaller on linear-lead bots
	static final int	BULLET_SPEED = 11;	// 3 power bullets travel at this speed.
	static final int	MAX_RANGE = 800;  	// Range where we're guarenteed to get a look-ahead lock
							// 1200 would be another good value as this is the max radar distance.
							// Yet too large makes it take longer to hit new movement patterns (Lemon)...
	static final int	SEARCH_END_BUFFER = SEARCH_DEPTH + MAX_RANGE / BULLET_SPEED;	// How much room to leave for leading
										
		// Globals
	static double 		arcLength[] = new double[100000];
	static StringBuffer patternMatcher = new StringBuffer("\0\3\6\1\4\7\2\5\b" + (char)(-1) + (char)(-4) + (char)(-7) + (char)(-2) + 
							  (char)(-5) + (char)(-8) + (char)(-3) + (char)(-6) + "This space filler for end buffer." +
							  "The numbers up top assure a 1 length match every time.  This string must be " +
							  "longer than SEARCH_END_BUFFER. - Mike Dorgan");
	
	//Code
	public void run() 
	{
		// Nice (cheap) Green/Blue color
		setColors(Color.green,null,null);

		turnRadarRightRadians(Double.POSITIVE_INFINITY);
	}

	/**
	 * onScannedRobot: What to do when you see another robot
	 */
    public void onScannedRobot(ScannedRobotEvent e) 
    {
        doMoebius(0, patternMatcher.length(), e, SEARCH_DEPTH, e.getBearingRadians() + getHeadingRadians());
    }

    private void doMoebius(int matchIndex, int historyIndex, ScannedRobotEvent e, int searchDepth, double targetBearing)
    {
		// Assign ArcMovement here to save a byte with the targetBearing assign.
		double arcMovement = e.getVelocity() * Math.sin(e.getHeadingRadians() - targetBearing);
																										
		// Move in a SHM oscollator pattern with a bit of random thrown in for good measure.
		setAhead(Math.cos(historyIndex>>4) * MOVEMENT_LENGTH * Math.random());
							
		// Try to stay equa-distance to the target -  a slight movement towards
		// target would help with corner death, but no room.
		setTurnRightRadians(e.getBearingRadians() + Math.PI/2);

		// Assume small aim increment so we can always fire.  Too much cost for gun turn check
		// Add simple power management code.  This keeps us alive a bit longer against bots we
		// have trouble locking on to.  Helps in melee as well.  It basically gives us 9 more shots.
		// -2 is better, but costs 1 more byte
		setFire(getEnergy()-1);

		// Cummulative radial velocity relative to us. This is the ArcLength that the enemy traces relative to us.  
		// ArcLength S = Angle (radians) * Radius of circle.
		arcLength[historyIndex+1] = arcLength[historyIndex] + arcMovement;
		
		// Add ArcMovement to lookup buffer.  Typecast to char so it takes 1 entry.
		patternMatcher.append((char)(arcMovement));

		// Do adjustable buffer pattern match.  Use above buffer to save all out of bounds checks... ;)
		do 
		{
			matchIndex = patternMatcher.lastIndexOf(
							patternMatcher.substring(historyIndex - --searchDepth),
							historyIndex-SEARCH_END_BUFFER);
		}
		while (matchIndex < 0); 

		// Update index to end of search		
		matchIndex += searchDepth;
		
		// Aim at target (asin() in front of sin would be better, but no room at 3 byte cost.)
		setTurnGunRightRadians(Math.sin( 
			(arcLength[matchIndex+((int)(e.getDistance()/BULLET_SPEED))]-arcLength[matchIndex])/e.getDistance() +
			targetBearing - getGunHeadingRadians() ));
				
		// Lock Radar Infinite style.  About a 99% lock rate - plus good melee coverage.
		setTurnRadarLeftRadians(getRadarTurnRemaining());
		
		// I'd love to drop a clearAllEvents() here for melee radar locking help, but no space.
	}
}


There's a way to shrink him to 244, but I believe it conflicts with PEZ's shrink to 245 :( Simply take double targetBearing as it was in the original 1.3 and make it static double targetBearing in the globals. Then instead of doing that trick to assign it in the setTurnRight? and then add the rest of it in when arcMovement is determined, simply call e.getBearingRadians?() in the setTurnRight? and assign the entire value in the assignment of arcMovement. Reduces nicely to 244. -- Kuuran

It turns out the codesize can get down to 244 with PEZ's suggestions with a little care. I'll see if your idea can get me anywhere as well. Thanks for the help guys! -- Miked0801

I tried it with PEZ's mod and without, before it shrinks, after it seems to bloat or not change, if you can find a use for it you're obviously more than welcome, though :) Albert now has a shrunken version of NanoLauLectrik 1.0 that's 236 (correction, he's into the 220s now, wow), so be prepared for some stiff competition :) -- Kuuran

YES!, I found a few more bytes here and there and can get Moebius down to 226 w/o color and fire control. With both, he sits at 239 - 10 more bytes of fun and excitement w/o any comprimises. That's more room than I've had in ages. I'll take these same changes to my other Nanos as soon as Moebius kicks some butt again :) I'll post my edits tomorrow as it's past my bedtime here and I want to think it over tonight on what to do next. -- Miked0801

My work was just a quick test, I'm sure it can be tweaked and combined with careful uses of globals and stuff to get more bytes free. The trick is also very useful in micros and minis since there you have much more code that might potentially be extracted to methods. And if it's the right pieces of code, this can increase code readability as well. Not a bad side effect, in'it? I did try to shrink Moebius in other ways as well, but always ended up fattening it instead. I'm very curious as to where you found those 7 bytes Mike! (I'm glad my doJob() fix didn't break Moebius. Since I'm running on Java 1.3.1 I can't test these bots. It's like coding blind folded.) -- PEZ

I've done it good this time, found another 7 bytes again. I can get my bot down to 233 with colors and fire control - or 220 w/o. I'm using the space for new movement, and then I'll post later today. -- Miked0801

A hint? (I have been trying to get it below 244 a while now...). If you post the code on this page, just overwrite the above version. The wiki version control will take care of keeping the old version available. -- PEZ

Ok, here it is. The movement isn't good enough to beat Kakaru? yet (same as before), but I've got a bunch of space to work with now. I'm rather proud of how I modified the aim. Strings turn out to only cost 2 bytes for unlimited length. I'll post the source in the repository when it beats Kakaru 1.2 and NanoLauLectrik 1.0. CodeSize 233! ;) --Miked0801

I see why you say Strings take very little codesize! -- PEZ

Another place you nano-types could possibly lose some size is letting Robocode normalize your angles for you - I've discovered (and I'm using, starting with FloodMini) that I can use robocode.util.Utils.normalRelativeAngle(angle), and it should be smaller than Math.asin(Math.sin(angle)). And to get angles between 0 and 2*pi, you can use robocode.util.Utils.normalAbsoluteAngle?(angle), although by experience, I think you need that a lot less. -- Kawigi


Robo Home | Moebius | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited May 17, 2003 20:01 EST by Kawigi (diff)
Search: