Difference between revisions of "User talk:Skotty"

From Robowiki
Jump to navigation Jump to search
(Add section on my new Painting Framework)
(→‎Painting Framework: Updated with new screen shot and description)
Line 219: Line 219:
 
*  It allows painters to be turned on and off during the battle.
 
*  It allows painters to be turned on and off during the battle.
  
It's still under development, but I've got the basics working.  Below is a screen shot that has some old painting stuff (which eventually will go into their own windows), as well as a window (labeled "test1") that utilizes the new paint framework.  The "test1" window can be dragged around the screen by it's title bar (if you are curious, the graph it is displaying is CPU usage per tick).  When I'm done, you will also be able to close it, and toggle it on and off through a little menu at the top.  While the window system takes center stage, it does also handle painters that do regular screen painting without windows, and those painters can also be toggled on and off through the menu at the topAnd no, the menu at the top is not shown in the screen shot; I still need to finish that piece.
+
It's still under development, but I've got the basics working.  Below is a screen shot that has some old painting stuff (which eventually will go into their own windows), as well as a visible window (labeled "CPU Utilization") that utilizes the new paint framework.  The CPU Utilization window can be dragged around the screen by it's title bar.  You can toggle it and any other Painters (such as the Active Components Painter, as seen in the menu) on and off through a menu at the top.  In the picture, the menu is dropped down, but it collapses when the mouse is not over it.  While the window system takes center stage, it does also handle painters that do regular screen painting without windows, and those painters can also be toggled on and off through the menu.  The colors are still kind of ugly, but it's a work in progress. :-)
  
[[File:xander-debug-window.png]]
+
[[File:xander-painter-framework.png]]

Revision as of 21:21, 5 November 2011

I Hate Wall Avoidance

I hate it with a passion. I'm still trying to come up with an elegant solution. Since one of my main drive strategies is "orbital", I'm now toying with the idea of moving my orbit target to avoid hitting the wall, rather than trying to adjust orbit path separately. Though I'd prefer a solution that works regardless of drive strategy.

I still have a lot of work to get my drives working well in general. However, I may have to stop playing Robocode again soon. Too many other things I need to get done...

Have you tried Wall_Smoothing ? If you are not wave surfing, you will probably also want to have some explicit Dive_Protection . If you are having trouble implementing those elegantly I would suggest you take a look at the Wave_Surfing_Tutorial) --AW 21:37, 31 May 2011 (UTC)

Been awhile since I posted this, but I wanted to touch on it again. I am using the typical implementation of wall smoothing, but I don't consider it elegant. The path is a little irregular when cruising around the edges of the battlefield, and it's possible to run into a wall when approaching too quickly and at too steep an angle to turn in time. I still have working on a better solution on my TODO list. I may work on it in the near future. Now that I've built the ability to predict drive paths into my components, it should be easier to achieve a better solution that can get closer to the walls while running into them less. -- Skotty
FYI - I think this one's pretty elegant: Wall Smoothing/Implementations/Fancy Stick. --Voidious 19:23, 27 June 2011 (UTC)
That's actually very close to some pseudocode I already came up with. Mine also takes velocity into account, which I'm not sure if fancy stick was meant to or not (I kind of just skimmed it). I currently call mine dynamic wall arc. Instead of a stick, I use a 180-degree arc, and it's dynamic, because it changes based on robot velocity. Because it takes velocity into account, my the method for my approach returns both a smoothed angle and smoothed speed. I plan to have it finished in the next couple of days when I have some free time. It will be interesting to see if a better wall smoothing algorithm improves overall performance or not. I'm keeping my old wall smoothing code as well, as I think it is a closer approximation to what most robots do, and I want to continue using it for predicting paths of opponents. -- Skotty 23:06, 27 June 2011 (UTC)
I made a code implementation of the fancy stick on the talk page... it's not very neat but it's quick and dirty and it works =) --Skilgannon 19:14, 28 June 2011 (UTC)
I definitely know what you mean by the common form of wallsmoothing seeming inelegant. Interesting approach you're taking. As far as tuning the wallsmoothing goes, note that tighter and more accurate wallsmoothing won't necessarily be a good thing I think. The thing is, tighter and more accurate wallsmoothing means your behavior near walls will be more distinctly different than far from walls. The distinct difference will give adaptive guns aiming for you more accurate/distinct information to "home in on". (Errata: tighter and more accurate wallsmoothing on the other hand, expands the "wall doesn't affect movement" area, so... how it plays with adaptive guns has factors going both ways... The interplay with adaptive guns hard to predict without doing an in-depth analysis or just plain trying it... but either way, keep a close eye on how it affects performance against adaptive targeting)
Personally I'm hoping to avoid explicit wallsmoothing in my next surfer... sort of like how I already avoid explicit dive protection... (Maybe this is something Voidious would call me insane for, unlike about dive protection? Haha) --Rednaxela 13:33, 28 June 2011 (UTC)
I might have, but I think you already explained the details to me and it sounds pretty badass. =) --Voidious 14:28, 28 June 2011 (UTC)
I've finished a functional version of my fancy stick...trying it out in Rowdy. We'll see what happens... -- Skotty 22:30, 29 June 2011 (UTC)
I'm trying out a new variation on fancy stick in my robot Rowdy. This time, not only do I use my own take on the fancy stick, but I've also built in the means to use non-rectangular drive bounds. I can make the bounds any shape I want, and use either regular wall stick or the fancy stick with it. Should be interesting to play around with. For reference, Rowdy 1.1.1 uses regular wall stick with rectangular drive bounds. Rowdy 1.1.2 uses my take on a fancy stick with rectangular drive bounds. Rowdy 1.1.3 uses my take on a fancy stick with a drive bounds that looks kind of like a rounded rectangle that bows in on each side. I wonder if I am the only one to try using a non-rectangular bounds? If anyone wants to see it visually, I left on the options in Rowdy to draw the fancy stick (or wall arc, as I call it) and the drive bounds. It's kind of interesting. Could still be a few glitches in my implementation. And it reverts to wall stick if my robot happens to get out of bounds somehow (like on startup), as my wall arc doesn't take being out of bounds too well. If you look at the painted battlefield, you will see that there are actually 2 drive bounds drawn. The plain rectangular bounds is the one used for the opponent. I did this partially for fun, but I also have a theory as to why the fancy stick seems to result in lower scores. The theory is that it causes the drive path to be too predictable at the edges, as it results in too much driving straight when smoothing. However, with a wavy drive bounds, this will no longer be the case. -- Skotty 19:17, 30 June 2011 (UTC)
That theory is basically what I meant a few days ago, in the paragraph above where I wrote that I don't think tighter wallsmoothing is likely to be good against adaptive targeting :P --Rednaxela 02:31, 1 July 2011 (UTC)
Okay, I've monkeyed with wall smoothing far too long again, and so far it's not performing even equal to my former wall stick method. I hate it, and I once again hate wall avoidance, but it's back to the wall stick for me so I can go back to focusing on things that might actually make my robot score better. lol. -- Skotty 02:50, 1 July 2011 (UTC)

Packaging Source Files

At the moment, my robot XanderCat is not packaged with source. This is fine, since the Xander framework is not entirely complete yet. Though when I am ready to package with source, I'm not sure how I will do it. I use Eclipse for development. I can add the bin directory under the developer options to run my robot while it is under development. But when I go to package it in Robocode, I'm not sure there is any way to tell it where the src folder is. I could also just check to see what all Robocode is putting into the jar files, and write my own Ant built script. Or I might just provide the source as a seperate download from the wiki page. Thoughts?

I'd also like to point out that not packaging your source doesn't necessarily keep people from checking out your code. Class files can be decompiled. Just a thought...

I too use Eclipse for development, and have never had trouble with packaging the source code. I have options -> preferences : development options set to my ...\workspace\robots\ directory which contains my ...\src\ and ...\bin\ directories, then I can package my robots in robot -> package robot for upload; this dialogue contains an "include source" check box (enabled by default). --AW 23:21, 27 May 2011 (UTC)

The preference dialogue on development options, it says that "If you are using Eclipse, you can enter the root dir of robot project inside robot workspace as well (recommend)". Robocode is able to parse Eclipse's project file to get /src and /bin dir (multiple source dir is also supported I think). That way the source code will be packed. --Nat Pavasant 02:43, 28 May 2011 (UTC) PS. I am the one who requested this feature. Before that, I have to either put the source in the jar myself (via WinRAR) or set output directory to /src

Ah...okay. I did not follow that it would automatically check for /src and /bin folders. Skotty 21:32, 31 May 2011 (UTC)

Rant on Lost Form Submissions

Bitten by poor web application design again. After having to pause one of my edits to take care of another matter, I returned a bit later, finished my edit, and submitted it. However, my session had timed out. Much to my surprise, MediaWiki did not preserve my edit. I thought MediaWiki was classier than that.

It is a newbie web developer mistake to have a web application lose someones edit due to a session timeout. The proper action is to save the edited data, give the user a chance to log back in, and then apply the edit or return them to the edit page without losing the edit. I'm often surprised at how many web applications exhibit this glaring flaw...so many, that I almost consider it my own mistake for not copying the text to notepad before submitting. But it is not my own mistake. It's the web application's mistake. A mistake that I am really growing tired of seeing again and again and again...


Eh? I have never had session timeout with MediaWiki. Are you sure it is really session timeout? I know for the fact that MediaWiki use token cookie for authentication. BTW, I know Chrome preserve form data on 'Back' button. I don't know about other browsers, but I think they do too.

On completely unrelated note, I found that FanFiction.net authentication system more frustrating: if I checked "Remember me for one day", it remember exactly one day i.e. if I start edit on 23.58 and finish on 24.01 hours after my login, my edit will be gone :( --Nat Pavasant 12:51, 27 May 2011 (UTC)

Robocode Bug

I like to print out some stats after each round, but I've been running into a problem. I may be limited to printing to the console. If I win, I get an Win event and a RoundEnded event. But if I lose, it appears as though I get no events. However, it may just be that the console dies before all events are fired/processed. Is that the case? It would be a pain to have to write results to a file every time. I'm running Robocode 1.7.2.2.

In my test, I do a System.out.println in each of the event methods on my main robot class (onWin, onRoundEnded, onDeath), but I only see them when I win. Thoughts? Skotty 21:39, 8 June 2011 (UTC)

I just figured it out. It happens when the main window is minimized. The events are always fired, but they can only print to the console if the main window is not minimized. Annoying, but I can live with it. Skotty 22:01, 8 June 2011 (UTC)
Certainly sounds like a bug - you should always get them, and I'm pretty sure it worked in the past, even when minimized. I have onWin and onDeath both calling a common method (maybe onRoundEnded didn't exist at some point). --Voidious 23:03, 8 June 2011 (UTC)

Painting on the Battlefield

I have been using the painting ability in Robocode to a large degree lately. It's great for debugging, and it's just plain cool. I have quite a few painting features built into XanderCat and the Xander framework now. I left them enabled in XanderCat 3.4, and I have even more cool stuff that can be turned on for XanderCat 3.5 (mostly gun stuff).

Who else out there is using the painting ability of Robocode? Are there any interesting robots to check out? Do you use it for your own bots? Skotty 15:20, 10 June 2011 (UTC)

Off the top of my head: Diamond (gun gfx need an udpate though), Phoenix (one of my favs, and one of the first to make really nice graphics), Shadow, Glacier (other Rednaxela bots?), DrussGT, GresSuffurd. Well, that should get you started. There are lots more though. Maybe Google: graphics site:robowiki.net would yield a more exhaustive list. =) --Voidious 16:24, 10 June 2011 (UTC)

  • Specially Diamond is nice with its feature to turn on/off gun and movement graphics separately during battle (radar graphics does not show anything I think). That's something I definitely want to do too, because enabeling the graphics in the .ini file is just too much trouble. Tigger would be the first tank to have graphics, as stefw was the one who developed the possibility. --GrubbmGait 00:05, 11 June 2011 (UTC)
    • Radar (unless I broke it) shows last known location of each bot. In 1v1 this isn't very visible, but in Melee you can see the squares. And thanks. =) KID's menu system sounds a lot sleeker though! --Voidious 00:21, 11 June 2011 (UTC)

I've built in a lot more painting options into XanderCat and my Xander framework since I first talked about this. Right now, you have to turn painting for different things on and off by setting boolean flags. Sometimes I think it would be nice to turn painting options on and off during battle, but I haven't investigated the possibility. I know ther are interactive robots now, and it might be possible to take advantage of the mouse controls to be able to turn paint options on and off. However, the bigger issue I am working on solving, is that I built the painting ability into individual components, and I now want to seperate that code from the components. What I am doing for the moment is defining interfaces for different kinds of components with getter methods for the information that would be needed to paint. I then create a seperate painter class for that type of component. And for the moment, I register those painter classes with a single PaintManager class. So, for example, if I want to paint the factor arrays for a wave surfing drive, it would look something like this:

// the drive implements the interface

public class SomeWaveSurfDrive implements FactorArrayPaintable {
	...
}

// and in the main robot, where the drive is created...

	SomeWaveSurfDrive drive = new SomeWaveSurfDrive();
	PaintManager.addPainter(new FactorArrayPainter(drive));

Bug Exploits -- What's Fair, What's Not?

Thought I would share my thoughts on bug exploits, and see if anyone else cares to share their thoughts as well.

In my opinion, anything that attempts to exploit bugs or vulnerabilities in the Robocode engine itself is unfair, as it is not in line with the intent of Robocode. However, anything that attempts to exploit vulnerabilties in other robots is fair, and very much in line with the intent of Robocode.

The one case I see as debatable is whether or not it is fair to exploit bugs in other robots. I would categorize this in two flavors -- generic exploits, and targeted exploits. General being an across-the-board attempt to exploit a common bug, and targeted being based on recognizing individual robot names. I think both are fair and acceptable practice, as opponents are always welcome to update their robots to correct them.

Does anyone disagree with this assessment? What are your thoughts?

I agree that exploiting Robocode bugs is unfair and (even if we didn't police it) kinda stupid because they will be fixed eventually. I also agree it's fair to exploit flaws/bugs in other bots. Having bot-specific logic in your bot is definitely allowed in the RoboRumble - even pre-packaged data files. However, many of us (myself included) are not really into doing this ourselves, as we just don't find it as interesting, and doing so could hide the possibility of "real" improvements. (Eg, why improve your gun's learning speed if it can be pre-loaded with data offline?) That said, LittleBlackBook takes bot-specific logic to the extreme, and I find that bot very interesting! =) --Voidious 17:20, 27 June 2011 (UTC)

What brought this up is the x.x5 bug. I agree, it's more interesting not to have bot-specific logic. I like playing with bullet power, but I didn't want to lose ground against other top robots that take advantage of the x.x5 bug. My solution was to specifically target those robots I know to be vulnerable, allowing me to continue playing with bullet power however I want against other opponents. This type of targeted attack is the basis for my Red Eyed Monkey components, as I have been calling them. Generally, I haven't been using them, but this is a case where it made sense. The name coming from Toy Story 3, because it always makes me think of the monkey in the movie that watches the security cameras. -- Skotty 17:32, 27 June 2011 (UTC)
What I did in DrussGT was to do the bullet power choosing first, then round it to the nearest x.x5. --Skilgannon 13:33, 28 June 2011 (UTC)

In last versions of robocode enemy name can be hidden, so in long terms it's not very good idea to have special cases, based on enemy names --Jdev 06:18, 30 June 2011 (UTC)

How are they hidden? Is some unique ID (unique per battle) provided instead? If and when I enter the melee rumble, it is likely I would want to track different opponents, which I currently do by robot name. If no unique ID of any kind is provided, then this means there is no way to differentiate between opponents? That is a pretty big change. -- Skotty 19:11, 30 June 2011 (UTC)
We definitely would not make that change without a lot of discussion, and I doubt we would... It is an available feature in new versions of Robocode, but that doesn't mean we have to use it in the RoboRumble. Anyway, I do think it's a unique identifier though. --Voidious 22:31, 30 June 2011 (UTC)
I think the idea behind that was (I requested it) is to make it so bot specific logic could be turned off without each robot having to have specific code to do so. It would be static along the battle. Basically in a battle, Enemy 1 would always be Enemy 1 (or whatever other unique identifier is used), but between battles this Enemy 1 could become instead Enemy 2, or Enemy 3, or not show up at all. — Chase-san 16:19, 12 July 2011 (UTC)

Speaking of bug exploits, does it amuse anyone else that the robot named NewBGank can be beat by taking advantage of a bug originally introduced in a wave surfing intro/demo bot? -- Skotty 20:46, 18 July 2011 (UTC)

Virtual Guns Equivalent To Virtual Hit Ratios?

I usually push myself to avoid looking at other's tactics, and come up with as much as possible on my own. I've seen "Virtual Guns" here and there around the wiki. I was thinking this is the same thing as my "Virtual Hit Ratios". With my virtual hit ratios, I have every gun provide it's aim for every time I can take a shot. I then record whether or not that aim would have hit the opponent after the wave passes the opponent. From that, I can track the "virtual hit ratios", and select which gun to use from those ratios. Is "Virtual Guns" the same thing?

Yep, "Virtual Guns" fire "virtual bullets" which can virtually hit or miss the opponent. Most hitratio's you see in the debugwindow when fighting an opponent are virtual hit ratio's. I do not even use the real hitratio, although I print it out at the end of each round. Mind though that the ratio's are not sacred, hitting with a real bullet can influence the behaviour of the opponent, hitting with a virtual bullet will not have influence. --GrubbmGait 07:58, 30 June 2011 (UTC)

CPU Utilization

Have a missed a good conversation on this before? I'm just now getting concerned about how much CPU time I can use without having skipped turns. I now have my framework track peak and average CPU time per turn, but I don't really know what I can generally get away with. How many milliseconds should I try to stay under per turn?

My new factor array system will be more CPU intensive than what I was previously using. One thing I was thinking of doing to avoid possible problems is to split up the workload of factor array processing somewhat evenly for each turn. I can do this with my new drive because it is a Go-To style drive that only makes decisions when the wave situation changes. I could use the in-between turns where decisions are not being made for handling things like rolling averages.

I built a little paint module that can paint a graph of robot CPU utilization on the screen during the battle. Pretty nifty. -- Skotty 20:08, 11 July 2011 (UTC)

Well, if you go to "Options->Recalculate CPU Constant", it will tell you how many nanoseconds that Robocode allocates per turn on your machine. I'd say it would be best to try to keep the peak amounts your robot uses below 80% of that to be safe.

Redistributing CPU intensive code across multiple ticks is something I've considered before, but I haven't because I don't view the mostly empty ticks as "wasted time", I instead view them as a way to: 1) Allow the robot to be tested faster when doing hundreds of seasons of dozens of TC/MC tests in RoboResearch, and 2) Be courteous to others because being inefficient with rumble time is bad karma. --Rednaxela 23:58, 11 July 2011 (UTC)

I'm not looking to maximize my CPU usage, just to flatten the peaks. As a point of interest, I did a recalculate CPU constant, and it gave me a time of about 11.6 ms. On a typical 35 round battle, XanderCat 6.1 had an average turn time of about 1 ms, but could peak close to 9 ms on some turns (although it was more common for it to peak about 5 ms). -- Skotty 02:45, 12 July 2011 (UTC)
On this topic, one of my older guns (Prototype) pretty much required distributing its computation across multiple turns to avoid skipping them. It was also because of this that is could only use actual bullet waves to rate enemy movement. However in my opinion, unless you really need to, it is more painful then useful to do. — Chase-san 03:41, 12 July 2011 (UTC)
I've had some strange results with scores going +-10% for seemingly random bots when I make changes that would affect CPU time in the slightest. I think the turn-skipping characteristics of 1.7.3.0 might need some looking into. Several times I've had a problem with DrussGT being stopped for a 'runaway loop' that I've been wracking my brains to find, it would make a lot of sense if it was in the latest rumbles and not in my bot... I'll do some testing with an older version to see if I can reproduce the problem. --Skilgannon 06:48, 12 July 2011 (UTC)
About DrussGT being stopped for a 'runaway loop', are you referring to 1.7.3.0, or an earlier 1.7.x version? If you're referring to an earlier 1.7.x version, there was a bug in the past where Robocode would kill bots for non-consecutive skipped turns. Perhaps that is what you saw? There was also another skipped turn issue in one version of 1.7.x, but that was fixed well before 1.7.3.0. I haven't seen 1.7.3.0 misbehave at all for skipped turns. --Rednaxela 12:12, 12 July 2011 (UTC)
I hope that's it, I noticed it when threads in RoboResearch started dying on my because they couldn't parse the "DrussGT has been stopped... " stuff. I'll try updating the roboresearch library jar to 1.7.3, see if it helps. On that note, any idea how to set the CPU constant in the new roboresearch? I'd like to manually bump it up a bit so that I can run multiple instances without problems... --Skilgannon 15:38, 12 July 2011 (UTC)

RoboRumble Servers

Are the rest of you running the RoboRumble on pokey slow computers? I started running RoboRumble on my own computer to contribute (was going to do this awhile back, but decided to wait until the 1.7.3 stuff was ready), since a lot of the battles needed are for my various robot versions. What has happened so far has been interesting. It occurred to me after I started that this would also be a great way to get more battle results on my own system (in particular the exception reports). What is interesting is that there are obviously still some problems occurring, but only on battles run by other people. I'm guessing the rest of you have slow secondary computers you run the rumble on (not that my Core 2 Duo is the latest and greatest, it's actually one of the slowest Core 2 Duo's you can get). But I can't say for sure. And I would guess the time available for turns ends up being less, though this is again speculation. Anyway, I guess I'll keep working on my code efficiency for now. -- Skotty 01:15, 13 July 2011 (UTC)

The time per tick is adjusted based on CPU power, so slower computers shouldn't matter. It could well be the opposite - you're running comparably fewer battles than everyone else combined, so you're less likely to hit the rare problem. In my experience, issues on different computers are usually due to different JVMs and their idiosyncracies. --Voidious 01:22, 13 July 2011 (UTC)

Okie dokey, finally got a weird result from my own system - a score of 12% against ChironexFlekeri. But no exception file. So maybe it's not an exception. What else could it be...has to be something that absolutely destroys performance for the rest of the battle...this could be a tough nut to crack. -- Skotty 01:37, 13 July 2011 (UTC)
How about a runaway/infinite loop? But that would only affect a single round, no? Or would the rumble kill the robot for the rest of the battle? -- Skotty 01:48, 13 July 2011 (UTC)
IIRC, Robocode 1.7 did change behavior so runaway/infinite loops result in it disqualifying it for the whole battle instead of just the round. Perhaps that's it?
As a note, I do have one rumble client running on a quaint little Atom netbook, but like Voidious notes, the time per tick is calibrated by an estimate of cpu power the first time robocode starts. --Rednaxela 02:15, 13 July 2011 (UTC)

I have this exception file too (considering I have run so many battles lately)

java.lang.NullPointerException: null
xandercat.drive.SimpleTargetingDrive.onNextBulletWave(SimpleTargetingDrive.java:137)
xandercat.track.BulletHistory.onTurn(BulletHistory.java:123)
xandercat.AbstractXanderBot.run(AbstractXanderBot.java:368)
net.sf.robocode.host.proxies.HostingRobotProxy.run(HostingRobotProxy.java:220)
java.lang.Thread.run(Thread.java:662)

Chase-san 02:23, 13 July 2011 (UTC)

On this topic the latest version was hanging my clients somehow (seems to only happen with xandercat), I can pump out a lot of battles, but it is no help if it stops running due to a single robot. I have excluded it from my clients for the moment. Sorry. I'll get you your exception file later when I get up (its late and I am overdue for sleep). — Chase-san 04:40, 13 July 2011 (UTC)

I'm guessing there is an infinite loop somewhere. For the latest version of XanderCat v6.1.4, I have set up every single while loop throughout the code base with an infinite loop detector (with only a couple of exceptions where it was plainly obvious that the loop cannot fail). For each iteration of the loop, a counter is incremented, and if that counter exceeds a certain threshold, an InfiniteLoopException is thrown. InfiniteLoopException is my own creation which extends RuntimeException (unchecked exception), so that I don't have to catch it everywhere. It should then be caught at the end of my main robot loop where it catches Exception and logs the exception to file. This will hopefully not only find the problem, but it should also prevent further client hangups. I have not done this with the for loops, as a while loop is far more likely the culprit. If this doesn't isolate the problem, I will go back and do this for all for loops as well. -- Skotty 04:56, 13 July 2011 (UTC)
I am re allowing it for the moment, I have a hunch it might have been an issue with my setup, so for the moment disregard my previous comment entirely. — Chase-san 05:00, 13 July 2011 (UTC)
I commented on this elsewhere, but just to bring this discussion line to a close, I will restate what I finally learned about my troubles. There was no infinite loop. I finally discovered that the problem was related to the version of Robocode used. I was using 1.7.2.2, while others were running the latest version 1.7.3.0, and the problem only occurs in version 1.7.3.0. I discovered that in version 1.7.3.0, my hit ratios on the opponent were coming up as 0, which was messing up my gun selection, causing very poor choices in some instances. I traced this back to a bug in Robocode 1.7.3.0 where Bullet objects obtained by setFire(...) were no longer testing as equivalent to what should have been the same Bullet objects returned by onBulletHit. This issue, not originally discovered by me, is documented by Robocode tracker issue #3312402. This has been fixed in the baseline and will be fixed in the next version, but is broken in version 1.7.3.0. The workaround is was to match up my bullets to my bullet waves in the same way enemy bullet waves are matched, rather than relying on matching on the actual Bullet objects. -- Skotty 20:56, 18 July 2011 (UTC)
One final note. I found this by outputting files for rounds with fishy results. One thing I checked was hit ratios. However, since the hit ratios were always coming up 0, every round had fishy results, and every round ended up getting a file written to the data directory. So sorry to everyone out there running the rumble who ended up with a bazilliion little files in XanderCat's data directory; feel free to manually delete them all. If you do not delete them manually, they will eventually be automatically deleted by running newer versions of XanderCat in the rumble. For every opponent battle of newer versions of XanderCat, it first checks for old data files against the opponent, and deletes them if they are found. So they won't all go away until XanderCat has been run against every opponent for which is created data files in the past. But that should happen eventually, so long as you keep running the rumble. -- Skotty 21:01, 18 July 2011 (UTC)

My "KNN" + Tree Approach

Thought I would take a moment to explain what I am doing with my new "KNN Factor Array Processor". Once again, it is something loosely based on existing concepts, but ultimately my own invention. So far it has not proven to be any better (in terms of robot performance in the Rumble) than my older bazillion factor ararys approach, but I still have a few changes in mind for it that may help.

Two things I know are different between what others are doing and what I am doing (though I am not fully up to speed on what others are doing, but I think I have the idea).

  1. How to compute what the nearest neighbor is.
  2. How the data tree works.

I'm thinking of changing how I compute nearest neighbors, and the result will probably be the same as what others are doing. So item 1 on the list may go away. At the moment, the computation I am doing differs in that it prefers data points where every segmentation is close to what I am looking for, whereas I believe the distance calculation most others use would allow any single segmentation to be fairly far off so long as the others are very close.

Example:

Lets say we are looking for a situation with segment slices [4, 6, 2, 2, 5], where max values are [6, 6, 10, 10, 8]. Now lets consider a neighbor that has segment slices of [4, 0, 2, 2, 5]. I could be wrong about this, but the distance formulas most people are using might consider that to be reasonably nearby, and use the point. However, my implementation would likely dismiss it because the second value (6) is on the completely opposite end from the neighbor value (0). I suspect this may be inferior and hurting overall performance, so I will be trying a more Robocode traditional approach for the distance calculation.

Perhaps a more significant difference is in how my data tree works. It does not store any "factor arrays". It only stores information about "points". Once all the nearby neighbor points to a particular situation are collected, the are used to build a factor array, which is then used by the drive or gun. This part might not be too different from what others are doing (or maybe it is, I don't know). Perhaps of more interest and/or significance is in how the tree branches.

Most people are using kd trees. I briefly looked at a wiki page on the concept, and it appears they work by adding new braches to the tree whenever they start to fill up with a lot of data. I'm not sure how this works in concert with segmentation, but I would guess this allows the number of "slices" to grow as the amount of data grows. But I don't quite follow how this is typically implemented when segmenting on multiple parameters (or when having multiple "segmenters", in my own lingo).

With my tree, the basic structure of the tree is defined from the start, though branches do not exist until they have at least one data point. The number of levels (or depth) of the tree is fixed. Each level represents a segmenter (so if there are 6 segmenters, the depth of the tree will always be 6). And each level can have a number of branches up to the number of slices the segmenter provides. To search the tree, I created an Iterator to be used when processing the children of a branch that iterates from the closest matching slice outward, the general idea being to grab the closest matches first and skip branches where the "distance" is already too far away.

As for how many points I use per situation (how many neighbors to use), right now I just start with a percentage of the total number of points, then restrict that within a set minimum and maximum. So if there are 1000 points in the tree, and the percentage is set to 8%, it will try to get 80 nearest neighbor points from the tree, but limited to a given set minimum and maximum (so if the max was set to 50, it would only use 50). On top of that, I also have a min percent match that can restrict it further. So if the min percent match is set at 60%, and only 42 of the 50 points are considered at least a 60% match, then only 42 points would be used.

Initial results are sort-of ho hum. I've tuned the parameters for using this approach in my main gun, but the rumble result is about 0.3 APS lower than with my older array of factor arrays approach. The drive using this approach performed slightly worse as well, though I have not yet attempted to tune the drive parameters. I still have a few changes to try before I throw it all out the window. -- Skotty 20:26, 19 August 2011 (UTC)

Here's a few observations on the differences and similarities from usual knn+kd-tree:

  • It's different that your tree structure is predefined instead of adaptive, and splits numerous ways per level instead of two. Not that those two factors change the result at all. The only thing it could affect would be speed.
    • The fun part: kd-trees don't have to be adaptive, so while this makes the predefined tree unusual in the Robocode context, the only reason it's not technically kd-tree is because it's not a binary tree. A kd-tree is basically just any multidimensional space partitioning binary tree where splits are defined by orthogonal hyperplanes.
  • The way you describe your iterator is the same as how a conventional knn search of a kd-tree is done (I say conventional, as variations can be done).
  • Your (initial?) choice of distance function sounds a little unusual. I'm curious to hear more detail about what you're doing for distance function actually.

--Rednaxela 21:13, 19 August 2011 (UTC)

Cool to see you exploring existing concepts with your own approaches. A few things I thought worth noting:

  • As for distance formula, I actually think most of us do use formulas that highly penalize a single attribute being further away - Euclidean distance squares the difference in value for each attribute, so attribute differences of 1/1/1 would be a lot closer than 0/0/3. Though it's worth noting that DrussGT (last I heard) uses Manhattan distance (just summing the distances). Seems to be working out for him. =)
  • It sounds like you are still implementing some form of segmentation and slices of your attributes? Most KNN bots don't and I consider it a key differentiator of the two methods. They just work on raw attribute values - there is no segmenting or partitioning of the data set.
  • While I was quickly convinced of the elegance and potential of KNN based ("DC") methods, it was a long time before I was able to get one to the level of my previous segmentation / VCS systems. I think the latter can be easier to tune and just has a longer history behind it.

Good luck! --Voidious 16:45, 20 August 2011 (UTC)

Just a quick note, from what I understand, his "segmentation and slices" are just used to subdivide the data tree. It's no different than how a kd-tree you use in a KNN bot segments/slices at each branch. It may not be predefined in their case, but kd-trees segment/slice just as much as this does. Since the kNN algorithm searches the full tree's area in both cases, there is no difference in end result. Since it doesn't affect end result, I'd consider it no more of a "key differentiation" than how some versions of Shadow used no tree at all for their kNN. --Rednaxela 17:27, 20 August 2011 (UTC)

Taking Another Break Again...Maybe...

I'm thinking of taking a break again, though I never really took one the first time. I've just got too much else going on in my life to devote time to Robocode. But at the same time, I am slightly addicted, more out of determination than out of having fun at this point. I hate that I haven't been able to make it into the top 40, or solidly into the "2000 club" territory (I think XanderCat version 6.8 managed a score of 2000 just barely, but it seemed like a fluke). On one hand, Robocode is just a hobby, and maybe I should set it aside. But on the other hand, software is my career and I have devoted most of my life to it, and I feel almost obligated to have a better performing robot. I tell you, if there were steroids for the brain, I would be a performance-enhancing drug user. -- Skotty 21:07, 19 August 2011 (UTC)

It's definitely easy to burn out. =) Robocode can be super addictive. Breaks are really healthy for sure, and I usually come back with a rejuvenated brain and lots of fun ideas. =) --Voidious 16:49, 20 August 2011 (UTC)

Curious Cases: Robots that raise your eyebrow

Here is a list of robots that have really peaked my curiosity due to unique specializations or unexpected competition results:

  • NDH.GuessFactor -- extremely low ranked robot, but scores way above where would be expected against some of the high ranked robots. What's going on here? This robot really raises an eyebrow.
  • nat.Samekh 0.4 and nat.BlackHole 2.0gamma -- Scores against these two always fluctuate wildly from release to release of my robots. I can only guess these robots are storing data between battles, but not checking robot versions.
  • ncj.MoxieBot 1.0 -- A bullet shielding robot that shields on the move. This takes greater advantage of bullet shadow size, and makes this little bugger really hard to hit. Still easy to beat, since it wastes all of it's shots on shielding, but a very interesting robot nontheless.


NDH.GuessFactor had 1.7.3-only methods, so got 0 on all of the old clients. On the new clients it is getting much better scores =) --Skilgannon 09:10, 16 September 2011 (UTC)

Painting Framework

I'm making progress on my painting framework. It will integrate with my Xander robot framework, but will also be able to stand on it's own for anyone to use. It's main features are:

  • It can be easily disabled in a manner where most of it will not be packaged with the robot. This allows developers to have extensive painting capabilities during development and debugging that can be easily be removed from released versions to keep the code size smaller.
  • It allows informational displays to be created that can be moved around the screen using a simple windowing system.
  • It allows painters to be turned on and off during the battle.

It's still under development, but I've got the basics working. Below is a screen shot that has some old painting stuff (which eventually will go into their own windows), as well as a visible window (labeled "CPU Utilization") that utilizes the new paint framework. The CPU Utilization window can be dragged around the screen by it's title bar. You can toggle it and any other Painters (such as the Active Components Painter, as seen in the menu) on and off through a menu at the top. In the picture, the menu is dropped down, but it collapses when the mouse is not over it. While the window system takes center stage, it does also handle painters that do regular screen painting without windows, and those painters can also be toggled on and off through the menu. The colors are still kind of ugly, but it's a work in progress. :-)

Xander-painter-framework.png