Robo Home | Changes | Preferences | AllPages

Bot Name



Bill a.k.a. Geekgymnast



What's special about it?

It's the first robot I have ever made that doesn't fail against all but some weak robots.

Great, I want to try it. Where can I download it?

http://www.robocoderepository.com/BotDetail.jsp?id=3588 Just search for "DreamBot" on the repository to find earlier versions.

http://geeksrobots.googlepages.com/home With developmental versions!

How competitive is it?

It can beat all the sample robots. It really is a decent bot, and can compete with anything that isn't too advanced. It can dodge bullets very effectively, without even checking for enemy fire (iow, it's random to dodge)

How does it move?

Completely new for version 2.0. It turns while oscillating. This is unbelievably effective (in my mind). It makes it surprisingly difficult to hit. No, it still can't regularly dodge SandBoxDT?'s bullets.

How does it fire?

It uses a CircularTargeting system that predicts enemy position iteratively. Then it recurs based on the distance to the new location. It actually works very well. Unless the enemy is acting really weird. It also has a HeadOnTargeting gun, for stuff it's predictor fails with.

It also has a broken SymbolicPatternMatcher. I would really appreciate any help with fixing it.

How does it dodge bullets?

See Movement above. Few targeters regularly hit this. I suppose a PatternMatcher wouldn't have too much trouble, after a while.

How does the melee strategy differ from one-on-one strategy?

The current version absolutely fails in Melee. I hope to improve that.

How does it select a target to attack/avoid in melee?

Whatever it scans last. The current targeting system is messed up with multiple robots due to a notable lack of making sure that I'm scanning my target.

What does it save between rounds and matches?

It saves gun stats. These it uses to choose between its 2 guns. It also saves the PatternMatcher buffer. This, however, doesn't work, so the code that turns the pmc on is commented out.

Where did you get the name?

This will turn into my dream robot...eventually. Also, it originally performed better than my wildest dreams ever predicted.

Can I use your code?

Yes. Just be sure to give credit. Credit for methods in the HelperMethods? class goes to Alisdair Owens and his SnippetBot, although they are in many other places.

Sorry! Unfortunately, the source for v. 1.0 to 1.8 has been lost. All later versions will include source.

What's next for your robot?

I plan to give it more aggressive movement, better dodging movement, and even more guns!

Does it have any WhiteWhales?

Wolverine is the big one right now. DuelistNano is another (slightly more than 1/6 my CodeSize!?!?), although after about 10 minutes I was able to win by 18 points in a 10 round match.

What other robot(s) is it based on?

SnippetBot, to an extent.

Comments, questions, feedback:

Welcome to the wiki. =) No shame in losing to any of the Duelists, all of David's bots are impressive. Good luck with your bots! -- Voidious

Welcome! A next-step-up from fast targeting would probably be PatternMatching. Imagine your iterative circular targeting, but instead of keeping the delta-heading and velocity constant, you change them each iteration with data you recorded from what they did last time they were in a situation similar to the current one. Kuuran put an excellent description on the PatternMatching page on how to store your patterns symbolically in a String, so that you can use Java's String.substring() and String.indexOf() fuctions to search for previous patterns, making the whole thing a lot less painful. Good luck with your Robocoding endeavours! -- Skilgannon

Welcome! The behaviour of your current botversion does have a familiar ring to it ;-) Just keep in mind that when it comes down to it, movement is more important than targeting. Have much fun with improving your bot! -- GrubbmGait

Thanks all. Right now I've managed to convince myself that moving in ovals would annihilate everything that's fairly simple, but it's not working too well. The robot that has the oval code in it DOES move in an oval, but it still gets nailed by DreamBot's targeting system. No, it doesn't revert to HeadOnTargeting. That would make me feel a whole lot better about it. If I can get it to work, I'll put it in DreamBot, with some tweaks to make it deal with PatternMatching guns. Are there any pages appropiate to discuss that? At Skilgannon: why do you think I made my CircularTargeting system work like that? Something else; Robocode doesn't seem to be packaging the source in the .jar file. Does anyone know why (the checkbox is checked)? -- Geekgymnast?

Well, moving in ovals of most sizes, are either going to involve moving close-to-straight most of the time, or moving in circle-like arcs most of the time, depending on just how oblong the oval is. So pretty much any possible oval is going to get hit well-enough by either linear or circular targeting. As far as packaging the source, I think it might require the .java and .class files to be in the same directory but I'm not certain of that. --Rednaxela

I tried to give it a symbolic pattern matcher, but it doesn't work. Also, the radar has been slipping, so I gave it the FACTOR lock...but now nothing else works (!!??). The new version does, however, have a nice new structure without the sloppy looking turnGunToTarget?(EverythingButTheKitchenSink e) {...}. If I really wanted to temporarily remove the pmc, I could with "//" before 1 specific line. Once I get the FACTOR lock working, I'll make that PatternMatcher wish it had worked from the start. -- Geekgymnast?

From what it sounds like, you are calculating how long it would take for your bullet to get to the enemy, iterating that many ticks forward, calculating for the new one, and iterating forward again. This can still leave you slightly inaccurate, especially if they are moving away and towards you a lot. What is better is to iterate forward, but as you are iterating calculate how far the bullet could have traveled at this time. Once the bullet has traveled a further distance than the distance from the firing point to the predicted position you stop iterating. Take a look [here] for an example. -- Skilgannon

It does do that, in v. 0.1.9 (at least, it did until I implemented the FACTOR lock. Why did that mess it up???). The CircularTargeting works perfectly. My SymbolicPatternMatcher and FACTOR RadarLock? are what is giving me grief. The PatternMatcher misses repeatedly, but I cannot figure out why. The new radar lock somehow is stopping everything else. -- Geekgymnast?

Fixed the FACTOR lock! Turns out the setTurnRadarRight call in the onScannedRobot event was overriding the turnRadarRightRadians?(2*pi) that was supposed to scan, but it still tried to complete it! Now I just have to figure out why the pattern matcher is missing Sample.SittingDuck. It doesn't just spin in circles and spray everywhere; it misses by only a few degrees of gun heading. I'm certain it's a problem with the SymbolicPatternMatcher, but I just can't identify it.

	public Point nextPMC(Point p, double heading, int patternPlace) {
		double velocity = (int) pattern.charAt(patternPlace); 
		double nextX = Math.min(Math.max(17.9, p.getX() + (Math.sin(heading) * velocity)), width - 17.9);
		double nextY = Math.min(Math.max(17.9, p.getY() + (Math.cos(heading) * velocity)), height - 17.9);
		Point r = new Point();
		r.setLocation(nextX, nextY);
		return r;
	public double nextHeadingPMC(int patternPlace, double heading) {
		return heading + Math.toRadians((double) pattern.charAt(patternPlace));
	public int indexOfPatternMatch() {
		return pattern.indexOf(getRecentPattern()) + 7;
	public void updateData(ScannedRobotEvent e, double heading, Point bot) {
		double absBearingRadians = (heading + e.getBearingRadians()) % (2 * Math.PI);
		double x = bot.getX() + Math.sin(absBearingRadians) * e.getDistance();
		double y = bot.getY() + Math.cos(absBearingRadians) * e.getDistance();
		p.setLocation(x, y);
		distance = e.getDistance();
		velocity = e.getVelocity();
		previousHeading = this.heading;
		this.heading = e.getHeadingRadians();
		energy = e.getEnergy();
		lastUpdate = e.getTime();
		name = e.getName();
		pattern.append((char) Math.toDegrees(this.heading - previousHeading)).append((char) velocity);
		if (gunType == 2) {
			try {
			reTurn.setLocation(pmc(t, 2, p));
			return h.absbearing(p.getX(), p.getY(), reTurn.getX(), reTurn.getY());
			} catch (Exception e) {}
	private Point pmc(TargetBot t, double firePower, Point p) {
		double heading = t.getHeading();
		int location = t.indexOfPatternMatch();
		Point pr = new Point(t.p);
		int time = 0;
		do {
			heading = t.nextHeadingPMC(location, heading);
			pr.setLocation(t.nextPMC(pr, heading, location));
			time ++;
		} while (bulletTravelTime(firePower, p, pr) / 2 > time);
		return pr;
	private int bulletTravelTime(double firePower, Point p, Point q) {
		return (int) (p.distance(q)/ (20 - 3 *firePower));
        //this line turns the gun to the predicted point.
        setTurnGunLeftRadians(h.NormaliseBearing(gunheading - gun.turnGunToTarget(gunSelector.gunMode, curTarget, p)));

The code between the stars is the part that returns the absolute bearing to the target. All functions not included work perfectly for circular targeting. Can anyone help? -- Geekgymnast?

Okay, this is very funny. About that "ovalmovement" suggestion I had made: it is incredibly effective against DuelistNano. I'm not kidding. I was laughing when I saw the NanoBot disabling itself against a robot with ovalmovement implemented. -- Geekgymnast?

I think you need to cast your char to a byte before you cast it to a double, so that you keep the negative info. The same is true for the other way around, cast to an int before you cast to a char when storing the data. I'm not sure if that's the only problem, but it's what I saw at first glance. Have you tried doing graphical debugging, to see where the pattern matcher is predicting the movement is going? It can make it easier to identify where the problem is. Also, it looks like you don't have any protection against accidentally using the angle data for velocity and vice versa. However, none of these look like they would help with hitting SittingDuck, so you have a bug somewhere else as well. -- Skilgannon

Oh, and I don't think you want to be dividing bulletTravelTime? by 2... -- Skilgannon

I implemented your suggestions, Skilgannon. It nails SittingDuck now. It still misses Spinbot, so I'll give graphical debugging a shot. As to the new movement...In all modesty, it works quite well.

Note that this is with PatternMatching disabled. It isn't a complete one-off, either (I've managed to repeat it). JollyNinja isn't the best shooter in the Rumble, but it's decent. -- Geekgymnast?

I used some graphical debugging and also built a droid that takes the last 2 entries on the pattern and mimics the foe. That helped me discover an error in the way velocity is stored; I hadn't realized that a byte is 8 bits including the sign! I reduced the multipliers, and now it annihilates SpinBot. However...it still misses Walls, MyFirstLeader?, MyFirstRobot, and PatternBot. I doubt that it's the lack of protection for switching the 2 data up. That wouldn't explain the 3 samples. They don't turn very much, but they have very regular velocity changes (that could be entirely picked out with the 10 turns of data that I give it). Whoa, typing that sentence made me realize why the original failed so bad; 7 is not an even number, but every 2 numbers represent a turn! Unfortunately, the number is now 20, so that is no longer applicable. Are there any other possible errors? I'll upload the code to my site, but I'm pretty sure that nothing I did introduced errors. -- Geekgymnast?

Hang on, you're storing your velocity and delta-heading in different characters, so you don't need to use a byte, you can use a 'short'. It's 16 bits, so you can use a higher multiplier. Be careful though, because using too high a multiplier means you never find a pattern exactly like this one. Another idea: search for a really long pattern, and if you don't find one, search for one half it's length, and keep halving the length of the pattern you're looking for, until you find a pattern that matches. About your fights against PatternBot etc, the above may fix it, but only if the problem is in your pattern-search. I'd like to see the code from inside your getRecentPattern?() method, it's the only thing I haven't been able to go over. Also, if there is a problem in your movement rebuilding, such as playing the data backwards, you obviously still won't be able to hit them =) -- Skilgannon

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited April 20, 2009 14:37 EST by Skilgannon (diff)