Robo Home | Changes | Preferences | AllPages

PEZ first entry in the RRGunChallenge (RRGC)

It's the gun from CassiusClay (Bee).

Download: http://www.robocoderepository.com/BotDetail.jsp?id=2310

Like all RRGC bots it uses the Raiko movement stripped of the MusashiTrick.

Here goes:

package wiki.rrgc;
import pez.rumble.pgun.*;
import wiki.rmove.*;
import robocode.*;
import robocode.util.Utils;
import java.awt.Color;
// BeeRRGC - Bee gun by PEZ - Raiko Movement by Jamougha
// For the RoboRumble Gun Challenge - http://robowiki.net/?RRGunChallange
// Released under the RWPCL - RoboWiki Public Code Licence - http://robowiki.net/?RWPCL

public class BeeRRGC extends AdvancedRobot {
    Bee gun;
    RaikoNMT movement;

    public void run() {
	gun = new Bee(this);
	movement = new RaikoNMT(this);
        setColors(Color.magenta, Color.magenta, Color.magenta);
        do {
        } while (true);

    public void onScannedRobot(ScannedRobotEvent e) {
	setTurnRadarRightRadians(Utils.normalRelativeAngle(getHeadingRadians() + e.getBearingRadians() - getRadarHeadingRadians()) * 2);

My only test before release:

1st: wiki.rrgc.BeeRRGC	9245	3400	680	4481	683	0	0	68	32
2nd: ad.Quest 0.10	6029	1600	320	3743	365	0	0	32	68

-- PEZ

Now it's time for a new RRGC test of the Bee gun. Version 2.0 of BeeRRGC does this against Quest:

1st: wiki.rrgc.BeeRRGC 2.0  10520	4150	830	4715	824	0	0	83	17
2nd: ad.Quest 0.10           4952	 850	170	3723	209	0	0	17	83
Let's see how it fares in the RRGunChallenge!

-- PEZ

Looks like the new Bee does considerably better in the RRGC, congrats to that. I'm curious, is this the same gun your using in the current CassiusClay, or did you add some experimental stuff? --Mue

Thanks! It's the same gun. I wanted a measure on the current CC's gun. Now I'll try a BeeRRGC using a reverse wall segmentation. -- PEZ

Now (version 2.0.10) I'm trying with acceleration segmentation again. And reverse wall segmentation tweaked to something that should be pretty similar to that of Ascendant/RRGC. -- PEZ

Gah! 1884... Nothing I do works at the moment. Frustrating to say the least! -- PEZ

OK. Now (v 2.0.11) I'm trying to mimic the config of the best BeeRRGC yet (2.0.2), but with the more readable segmentation configuration in place. The segmentations now look like so:

    static final double[] DISTANCE_SLICES        = { 200, 400, 500, 650 };
    static final double[] DISTANCE_SLICES_FASTER = { 200, 400, 600 };
    static final double[] VELOCITY_SLICES        = { 2, 4, 6 };
    static final double[] LAST_VELOCITY_SLICES   = { 1, 3, 5, 7 };
    static final double[] VELOCITY_SLICES_FASTER = { 3, 6 };
    static final double[] ACCEL_SLICES           = { 0 };
    static final double[] WALL_SLICES            = { 0.25, 0.5, 0.75 };
    static final double[] WALL_SLICES_REVERSE    = { -0.25, -0.5, -0.75 };
    static final double[] WALL_SLICES_FASTER     = { 0.4, 0.8 };
    static final double[] TIMER_SLICES           = { 0.1, 0.25, 0.6, 1.0 };
    static final double[] TIMER_SLICES_FASTER    = { 0.1, 0.3, 1.0 };
TIMER_SLICES(_FASTER) is used for the time-since-velocity-changed segmentation at the moment.

-- PEZ

Hmmm. 1877 now. Must be a bug I guess... -- PEZ

Can't find a bug there. Trying with adjusted segmentations again. -- PEZ

OK. So I found a stupid bug in my accel segmentation. But it didn't help my rating to fix it. Now I have resubmitted version 2.0.2 to get a callibration measure with the current drift. It would be pretty frustrating to find out one of all those versions since 2.0.2 was actually better. =) -- PEZ

Now I have tweaked and tweaked my segmentations ad absurdum. Time for something new! I have mixed Ali/BumbleBee and CassiusClay/Bee. I segment like usual on all dimension but distance. There I use a log of distance => visitIndex pairs and choose the closests ones to the current scan to choose where to fire. I have no log cleaning or anything active so I guess this version can get both slow and memory hungry in long battles. You have been warned. =) -- PEZ

Sounds cool. You wouldn't believe the crazy gun experiments I've been doing lately. :) -- ABC

Nope, but I'd really like to get a hint! -- PEZ

You want a hint from me? Last time I checked your gun (and Mue's) is much better than mine... Anyway, my last experiment is an "inverted" statistical GF gun. Instead of keeping a statistic on GFs for each situation, I keep a statistic on situations for each GF. Then I find the "typical" situation (that's the hard part) for each GF and compare it to the current one. I also did some experiments with dynamic axis wheighting in a log-based GF gun (my gun converted to GFs), using the standard deviation, correlation, you name it... None of them ever performed better than the non-dynamic version. -- ABC

Cool ideas, both of them! My experiment with version 2.5.01 didn't work with the first try. But I have lots of room for tweaking I guess. Maybe I should throw in yet another dimension in the log based part of the gun. Which two would you choose if you were me? -- PEZ

One thing I think you should try is to normalise all dimension to 0..1, I do it in my gun. Don't know about new dimensions, I still use distance traveled in the last 2/4/8/16 ticks, but I don't know if it is better or worse than you time-since-vel-change timers. -- ABC

In this case I would need to normalize only the dimensions that are to be dynamically clustered. I'll do that. What my question was about. In old Bee I segment on:

Now with 2.5.01 I segment on all but the first one. In the leafs of this "shorter" multi-dimensional array structure I now store lists of objets that contain the distance and the GF that would have hit. When choosing where to fire I now select the log lists using array indexing and then I select the log entries based on how similar in distance they are to the current situation. Like so:
    int mostVisited() {
	int mostVisitedIndex = MIDDLE_BIN;
	double[] visits = new double[BINS];
	List[] logs = logs();
	Comparator comp = DistanceEntry.createDistanceComparator(logEntry);
	for (int i = 0; i < logs.length; i++) {
	    List log = logs[i];
	    Collections.sort(log, comp);
	    for (int j = 0, n = log.size(); j < n; j++) {
		DistanceEntry e = (DistanceEntry)log.get(j);
		if (j < 1 || e.distanceFrom(logEntry) < 75) {
		    visits[e.visitIndex] += e.weight / (double)n;
	double most = 0;
	for (int i = 0; i < BINS; i++) {
	    if (visits[i] > most) {
		mostVisitedIndex = i;
		most = visits[i];
	return mostVisitedIndex;
That is; I select the "closest" log entry and then all log entries closer than 75 units. (The code above is a bit blurred by the fact that I still have two stat buffers (faster and slower learning). Hopefully it's not totally opaque what's going on... Now the question. With these segmentations, which would you chose for dynamic clustering and which would you chose for static indexing? I choosed distance for dynamic clustering first because different opponents show quite different distancing behaviour. But it's easy for me to change and select one or two others.

Your question whether yours or mine segmentation is better is interesting. I think yours is better. I'll try that in an old style Bee I think... Maybe I can strengthen my gun against surfers at least (well, all but Shadow then, which surfs your gun segmentations?).

-- PEZ

Shadow currently surfs a small subset of my gun's segmentations: distance, angle to enemy, speed and distance travelled in the last 8 ticks. I never managed to make it surf stuff like distance to wall (very important for targeting) without losing points. The recent ranking improvements came almost exclusively from experimenting with the way I compute the danger of the future position, not from adding/changing segmentations. Most of Shadow's array based surfing versions were based on simple FloodMini-style segmentations, 10 dist segments, 3 vel segments, and 3 accel segments. Every time I tried to add more complex segmentations it decreased my performance. About wich segmentations I would choose for dynamic clustering, all of them :). I believe there is a higher level of gun performance hidden in on-the-fly dynamic clustering, and we must probably forget a lot of what we know about gun segmentations to find it... -- ABC

CC's surfing just oodles of segmentations. Adding wall segmentation to it gained 5 points. I've already tried using all dimensions for dynamic clustering. But it got slow quicker and I had to do tricks to only compute the guess once per bullet. I'm trying to both eat the cake and have it now. =) Though my tests show that the current solution is also very slow above 50 rounds. -- PEZ

When I say it loses me points I mean it degrades my performance against DT :), I never really tested wall distance surfing in the rumble. I'll try adding acceleration and time-since-vel-change segmentation to my gun and see what happens. About computing only one guess per bullet, I recently found out that it isn't that simple afterall, often it takes 2 ticks to turn the gun, Shadow fires 1 tick old predictions more than I thought. It affects any kind of WhenToFire strategy, though. -- ABC

I've come to much the same conclusions. My gun most often makes the same predictions for several ticks in a row. Which makes my strategy at keeping the gun aimed at the current guess all the time the best choice. As long as I can afford it performance-wise, of course. Making Bee compute only once per bullet and keeping the gun aimed at GF0 otherwise degrades its accuracy quite consideraly. -- PEZ

Considerbly? I have to test it some more than, don't think I noticed any difference, though I had a bug in the gun at that time. --Pulsar

Maybe its an option to start aligning the gun to current guess when the gun heat drops below 4*gun cooling rate? I started to do it this way a while ago when i was using a gun with dynamic clustering similar to what PEZ described above (on all dimensions). This reduced the number of skipped turns considerably (especially in longer battles) and i didnt notice any effect on accuracy. --Mue

Yes, that could be an option I guess. Have you tried it on your current gun? Even if it's not needed there, you could check if it keeps its remarkable accuracy. -- PEZ

Actually i've not yet tried the current gun without it. Probably worth a test... --Mue

And now I am trying a fixed-clusters, lateral variant of ABC's distance_since (2/4/8/16) scheme. Mixed with my old velocity/accel/time_since_velocity_changed scheme even. I might make a cleaner implementation later. -- PEZ

Hmmm, distance_traveled_since doesn't seem to work very well for me. My purer implementation gets only 1864 points. -- PEZ

Now I'm trying to "paste" ABC's measurements on top of my old Tityus style ones. -- PEZ

Btw, my measurements are distance since 2/4/8/16/32 projected on the current enemy movement direction, they can be negative. The idea was to somehow include acceleration and heading change into them. If you want to have the exact same measurements you'll have to have a (x,y,heading) enemy log. -- ABC

OK. That is much more like my first implemantation, which worked much better. I have that log already, without heading, but it could be easily added. But 32 ticks... It'll be quite slow learning with fixed indexing and all those segmentations (assuming you have at least distance, velocity and wall proximity too). -- PEZ

Thinking about it, you don't need heading in the log, just x y. I also have distance, velocity, wall proximity (forward/backward) and angleToMe? as axis. You are right, it will probably be slow learning with fixed indexing, and most likely worse than your current segments. I think the fact that makes my gun better against wavesurfers is because it is different, not because it uses better segmentations. It almost never chooses the same firing angle for the same situation percieved by the enemy's surfing statistics. -- ABC

Different and still good I think is the key. =) -- PEZ

That goes without saying :). Another thing I like a lot about my gun is that it will crush pattern moving bots like no GF gun can. I based my initial gun development on optimising the hit rate against a sample bot melee. It's very strange when my current GF gun experiments find it hard to win 100% against Walls or MyFirstRobot without moving... -- ABC

Might be without saying. But I think it's quite an achievement to create a gun that chooses differently from a good gun while still remaining good. I wonder if Bee wins 100% against those when stationary... Your current GF gun experiments, is it doing dynamic clustering still? -- PEZ

I'm currently experimenting with a fixed indexing GF Gun. All my GF experiments were based on a hacked GF implementation I made on top of my PM gun, I'm trying to iron out small possible bugs that may affect its performance. I'll probably revisit dynamic clustering once I'm confident that my GF implementation is 100% bug free. --- ABC

Let's hope your fixed indexing experiments pay off then. That might mean a FastBot? Shadow =). -- PEZ

Not if my results so far are an indication, maybe a new bot. With a traditional GF gun that scores around 91 in the TC, Shadow gets crushed by every single wavesurfer. Where can I find the best (pluggable) Bee version? It would be nice to compare it with my current efforts. -- ABC

Pick the Bee used by the current CC ( It's my best Bee yet. Check CassiusClay.java to see how to plug it in. -- PEZ

I'm curious, what would you say are the major differences between Aristocles and Pugilist/CC? I can't get my GF gun anywhere near Bee's performance... -- ABC

The major differences... Aristocles:

  1. has much lower granulations in the wall segmentation (only 2 indexes)
  2. uses a confused time_since_deccel indexing (I am not sure it works at all)
  3. uses only one stat buffer
  4. fails to update the stat buffer now and then
  5. doesn't wait for gun alignement before fire
Well, I'm not sure about this, but it's something like that anyway.

BTW. It seems my latest Bee (version 2.0.32b) is as strong as the one used in CC Since it is much better factored, you might want to look at that one instead (of the CC one) in trying to figure your GF gun out.

-- PEZ

Other than the possible (and probable) small bugs in my code, the only thing I can see that could explain the difference is the multiple stat buffers. From what I read in your code, you just sum them together (visits1[b]/total1 + visits2[b]/total2)? -- ABC

Exactly. -- PEZ

One more thing. Your GF gun is already consideraly better than Aristocles gun. Remember that Aristocles collects some really cheap points by using a simple MusashiTrick thingy. -- PEZ

To really know that I'd have to make a version with Aristocles movement, either that or an Aristocles/RRGC... -- ABC

An Aristocles/RRGC is probably better. I can do it for you. Might be the start of an effort to reclaim the micro rr@h throne. -- PEZ

It was kinda simple to make an RRGC Aristocles:

public class AristoclesRRGC extends Aristocles {
    RaikoNMT movement;

    public void run() {
	setColors(Color.red, Color.yellow, Color.green);
	movement = new RaikoNMT(this);

    public void onScannedRobot(ScannedRobotEvent e) {
Only problem is that the codesize is 1183. Anyone has an idea on a simple and clean way to grow the bot some 400 bytes?

-- PEZ

Never mind that question. I don't think there's a clean way to do it really. But this one is at least simple:

    void justToGrowTheBotSome() {
	double d1, d2, d3, d4, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = 1;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = d1 / 137;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.pow(d1, 2);
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.sqrt(d1);
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = 1;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = d1 / 137;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.pow(d1, 2);
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.sqrt(d1);
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = 1;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = d1 / 137;
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.pow(d1, 2);
	d1 = d2 = d3 = d4 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = d15 = Math.sqrt(d1);

-- PEZ

Looks like the GF gun I tested was slightly worse than Aristocles, like my tests indicated. -- ABC

Yeah. Much to my surprise actually. It seems like Raiko's movement is conciderably better than Aristocles. I have managed to convince myself that was not the case! I think the micro throne is closer to me than I have figured before. (Thinking positively about it. =) Anyway, Aristocles gun is pretty good. Your first GF gun test coming close to the same performance isn't too bad for a first try. It's probably a bug or three in the way to Pugilist performance and then from there it is about making fancier stuff like Bee does. (Or just making them work in case you have already equipped your gun with it.) -- PEZ

I'll start it from scratch next week. I'm going away for 5 days, maybe I return with some fresh ideas. Looks to me like it's all in the small details, just like in movement. If I change it to your exact segmentations it doesn't help. I must make a GL version to see if I can catch any bug. -- ABC

If you go for OpenSource we can help you chase the bugs. =) -- PEZ

I like the sahring of ideas, but I also like chasing my own bugs... ;) -- ABC

PEZ, what have you been experimenting with in your gun for all this time? And is it working? -- Alcatraz

Small tweaks here and there. Segmentation, weighting of real vs virtual waves, rolling depth, bin smoothing, you name it. Nothing that really works though. The good thing is that I have been able to clean out stuff that didn't matter for performance. The gun is actually quite clean now. Check it out if you like. I'll try to make a mini version of it soon. -- PEZ

Would you mind releasing the current version of BeeRRGC in the rumble so I would have a better idea of where Toad/RRGC stands, because the results in the RRGC page are a bit old. -- Florent

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited November 7, 2005 9:06 EST by Florent (diff)