Is it possible that two event handlers are running simultaneously? I'm not 100% on how the threading stuff works... In an AdvancedRobot, you tell it the stuff to do, then call execute(), and your thread is blocked, but events still get kicked off right? So those events are running in a different thread than your run() method right? If so, does that mean that they could each be running in their own threads, and might be running at the same time? I'm particularly curious about onScannedRobot() in melee, when multiple robots might be scanned in a single turn, do I need to be careful about updating state? --BenHorner
In melee, onScannedRobot will be called once per robot that you scanned, in order of distance from you. The closest robot will be the first call while the farthest will be the last call. --David Alves
Ok, does the second call wait until the first is complete before it starts? If so, does that count against the amount of processing time your bot is allotted each turn? --BenHorner
Yes and yes. --David Alves
If two robots are moving in the same direction (and both forward), but the one in front is moving more slowly, and the one behind hits it, is that counted as a ram for both of them? --BenHorner
- Yip! Otherwise my bots wouldn't get any ram damage against those pesky rambots! =) -- Skilgannon
- It looks to me like the rammer will take 0.6 damage and the rammed will take 1.8 (0.6 + 1.2 bonus). So the rammer delivers 3x the damage, but still takes damage. If two bots ram each other head on each will take 2.4 damage per tick from the two ram events. -- Martin (I have not tested this .. just inferring from the Rules class above)
This is from the [[Robocode FAQ]]:
Q: What happens when a my robot hits another robot?
A: If your robot was moving towards the other robot when hitting it (i.e. ramming), your robot's move is marked as
complete, and your robot receives 1.2 score points. Both robots takes a constant 0.6 damage.
I don't know why I was considering to be a better source of information than the javadoc comments... Just because I read it before I knew the javadocs existed I guess. =) Now I will have to test it to find out which is right! --BenHorner
- And I think the FAQ is right. A non-moving, non-firing bot and a non-firing rambot go down on energy at the same rate. The only thing is that the rammer gets the scoring bonus and used to win the battle (as source of the ramdamage, until the latest robocode version). No test done though, just digged in my memory how the behaviour of GrubbmThree and opponents was during its development. -- GrubbmGait
Ok, I just did a test, I rammed SittingDuck to death with Interactive before the countdown started... Interactive was disabled at the end (both received 0.6 damage per ram) and it scored 290.
|Total Score ||290 ||
|Bullet Dmg||0 ||
|Bullet Bonus||0 ||
|Ram Dmg * 2 ||200 ||
|Ram Bonus ||30||
I'm thinking the non survival score 230 = 290 - 50 - 10 comes from: 30% bonus for the 100 actual damage done, and then 2 score points for each point of damage. So ram damage is the same for rammer and rammee, and
I think the multiplier for score has changed from 1.2 to 2 since the FAQ was written...
each point of ram damage is worth 2 score points (as opposed to the 1 for 1 ratio on bullet damage), so for a single ram of 0.6 damage, you get 1.2 score points. --BenHorner
Read carefully, per ram you get 0.6 damage and 1.2 scoring 'bonus'. That is a factor 2. Totally you ram 100 damage and thus get a 200 scoring points. -- GrubbmGait
Cool, thanks, a little bad math on my part. In fact, I think I'll edit it out right now so it doesn't confuse anyone else. --BenHorner
Has anyone noticed a "half turn advantage" in 1v1 matches? I was just going to try to do a modified RamFire to get something in the Rumble, because what I want to end up with seems so far away... So I have a "new" bot which is a copy of RamFire, going up against RamFire, I expected them to split pretty much 50-50, strangely though it seems like whoever I enter in the list first ends up winning about 2-1 (very consistently). Is that screen where you pick the bots also defining some kind of initiative (who gets to do their stuff first each turn)? If so, does the Rumble account for that? (I know I could look this up in the source code myself, and if no one knows off the top of their head, I probably will eventually) --BenHorner
- I'm pretty sure that there is "technically" no advantage. The way scan data and such is executed, everything happens simultaneously (i.e., one bot doesn't get to see next turn a turn earlier or anything - both bots get scan data, then both bots move), so nobody should have an advantage in that way. I do remember something a while ago that the bot listed first will skip less turns, but since most bots (and especially sample bots) won't skip turns anyway, that's kinda moot. But if you can reproduce it consistently, obviously there's something up, at least with those bots! -- Voidious
- Well, I was changing very small things, but I always selected my slightly modified bot into the list first... so even when I made a change that hardly meant anything, I noticed that it would give me about a 2-1 advantage. So I backed it of to zero changes, identical code, the only difference being who was listed first, and the 2-1 advantage remained. I ran 30 rounds about 6 times, and the survival differences ranged from about 18-12, to 22-8. I have yet to
see notice a battle where both bots kill each other at the exact same moment... which should be happening now and then with identical simple bots like RamFire. I thought it must be due to one bot's bullet collisions always registering first or something (on the turn when they should be killing each other). --BenHorner
- Yeah, there's a big advantage. This has been supposedly fixed in the latest version. But suppose There are two identical bots that are firing away at each other. Toward the end of the battle, they each have 2 life left, and they each fire a .5 power bullet. Now they each have 1.5 energy and the bullets are in the air. The first bot in the list (A) will have his bullet hit processed first, so he hits the second one (B) for 2 damage, which kills B. He gains back 1.5 energy for the hit, so when the game processes B's bullet, he has 3 energy and does not get killed. Supposedly this is fixed now, but that's how it worked historically. --David Alves
- The difference in the latest version is that the robots are now processed in a random order, meaning that in the situation you describe, bot B is just as likely to kill bot A as the other way around. -- AaronR
For a while, I had myself quite convinced that a bot in a JAR file will win against the same bot compiled from source. Look at this list of 50 randomly generated coin flips, from http://shazam.econ.ubc.ca/flip/index.cgi?50:
T H T H H H H H H H T T H H T H T H T T T T H T H H T H H T H T T T H H H H H T H T T T T T H T T T
Does it seem like there are more heads or tails? Actually, there are exactly the same number of each. As it turns out, most of the oddities in scoring results are simply random fluctuations (i.e. the run of seven heads near the beginning, and the result of exactly 25 heads and 25 tails, are both highly improbable as individual events yet still occur when looking at a large enough sample). It sounds like the placebo effect has struck again.
P.S. It's probably a good idea to write a program that will run battles and score results for you. Whenever I run the battles myself I am convinced that the latest version of my bot is the top performer.
Yeah, I hear you, I try to be scientific about things, not always successful but... I just ran two battles of 1000 rounds each, the first with RamFire selected first, the second with RamFireCopy? selected first. Even if I did mess up in the copying... or if inside or outside a jar mattered, and one bot won more often, shouldn't it at least be the same one? My results were that the first one in the list won 666-334 the first time, and 643-357 the second time.
| battle || selected || order selected || 1sts
| 1 || 1 || RamFireCopy? || 666
| 1 || 2 || RamFire || 334
| 2 || 1 || RamFire || 643
| 2 || 2 || RamFireCopy? || 357
Well, it appears you found a bug - in the ramming code! Check out these results from 500 rounds:
| Robot Name || Total Score || 1sts
| sample.RamFire (1) || 93705 || 315
| sample.RamFire (2) || 82440 || 185
| Robot Name || Total Score || 1sts
| sample.SpinBot (1) || 41077 || 257
| sample.SpinBot (2) || 40444 || 254
So the first RamFire outperforms the second by a huge margin, but the non-ramming SpinBots have an almost even score. I guess I'll file a bug report with Fnl.
Yeah, the SpinBots? would have a lot more chance thrown in, two RamFires? vs each other can't really miss, so every shot counts, so there should be some ties, but aren't. The SpinBot thing is consistent with the selection order also defining bullet evaluation order or something... I'm glad you saw it on your system as well! --BenHorner
This behaviour is already present in the (ancient) version 1.0.6. My experience is that the bot listed first most of the time has a slight advantage (up to 2%). In the rumble this does not matter, as it will even out over the battles fought. The reason I think that it is so obvious to see with rambots, it that they probably die the same tick or maybe one tick apart. The bullet of the first bot is handled first, causing the second bot to die, while in the same time (tick) the bullet of the second (killed) tank destroys the 'winner' tank 1. This is no 'bug' in the ramming code, it is just the way Robocode handles things. It is not very important, but you should keep it in mind when testing things. -- GrubbmGait
This has been fixed. Wow, this is a very alive opensource project! --BenHorner
Yes, Fnl is quite active solving things and extending robocode. On the other hand, you are just stirring things up with all your questions about things we were just taking for granted. ;-) -- GrubbmGait
The bugfix is confirmed (same test, 500 rounds):
| Robot Name || Total Score || 1sts
| sample.RamFire (2) || 88504 || 251
| sample.RamFire (1) || 88059 || 249
I just wanted a little confirmation, from some tests I did with the Interactive and SittingDuck sample bots, it seems that you get credited with a ram whether you are moving backwards or forwards. Are there any differences whatsoever between moving backwards or forwards? (Aside from the method you call to go that direction...) --BenHorner
- Your movement direction does not matter, as long as you move towards the other bot. In robocode there are no differences in moving forward or backward. -- GrubbmGait
- The only difference is that when you are in reverse, your heading is the opposite of the direction that you are moving. That has the potential to complicate calculations. -- Martin
- Ok, thanks guys! --BenHorner
I have just discovered a way to accelerate more than 1 pixel in a single turn... ;) just curious, how common is this knowledge, and is it a bug? --BenHorner
- It's common knowlege that if you are decellerating past 0 you will be accelerating faster than 1 in the opposite direction. -- Martin
- Ok, I don't know how I could think that I found something everyone didn't already know about I guess. So in a situation where it's appropriate to stop, do most people actually coast at a speed that is very close to zero? In order to gain an extra pixel of acceleration when they move? --BenHorner
- Not that I know of. Not on purpose, at least =). PerformanceEnhancingBugs are never nice. -- Skilgannon
- That, I guess, is why I was asking if it was a bug, if it was widely known and used, I thought I would be behind the game if I didn't also use it... but if it's going to be changed, I would be behind the game if I did use it... So I take it that it is a bug? --BenHorner
- No, it's not a bug, but it is an exploitable feature of the GamePhysics. I just don't really see how that 1 pixel will help, most of the time. And a lot of the time you won't be able to exploit it. You definitely won't be behind by not using this =). -- Skilgannon
- It's not really 1 pixel, it is up to 7 pixels, which is about a 3rd of the bot's profile. It's not a bug in the sense of something that will be fixed or that is unethical to take advantage of. It's a part of the reality of Robocode. The physics aren't terribly realistic. -- Martin
- Yeah, that's what I was thinking, within 6 turns it turns into a 7 pixel advantage... I will be sure to keep this in mind. --BenHorner
Is there anything that happens only once per round? I'm interested in initializing some things at the beginning of each round, but I don't see an onRoundStart?() event handler or anything... If there's nothing like that, I'll have to initialize a variable, and then change it in run(), but I'd rather not be checking it every time through the event loop... --BenHorner
- The run() method will be called once at the beginning of every round, before anything happens in the game. -- Simonton
Check me on this... Hitting a bot with a bullet of power bp, where bp <= 1, causes a 7 * bp swing in the energy tug of war, right?
Does that mean that if you can guarantee a hit within six shots, you should take those shots every time? Unless the other bot is doing something that is causing a bigger swing, that you have to make up for... like hitting you with higher power bullets...
- Another thing to consider is that survival is not what matters most, though it does matter (and a lot in melee). You might be able to out-survive someone (the energy tug of war) by never firing, but you may lose the battle because bullet damage counts so much more than survival. (Seems counter-intuitive - at least it did to me - but it's just how the scoring works. =)) -- Voidious
- Whoah... so I could be the one alive at the end, but still lose? Or I could be the one to get killed, but still win? I guess I need to go find the formulas that tell what things are worth what points towards winning the battle. I guess I need to optimize a different function than I thought!
- Correct. Personally, I kinda like Survivalist scoring, which is one reason I suggested it for the TwinDuel. But yes, the scoring formula has factors for bullet damage, ram damage, how many bots you outlive (not just being last one standing), and bonuses for being the one to actually kill an enemy (which is related to how much damage you've done to that enemy). Here's a page that might be helpful to you: CalculatingScore, though there is likely a more readable formula somewhere on this wiki... And just FYI, a whole lot of 1v1 bots use 1.9 or 2.0 as default bullet power. -- Voidious
Is the radar accuracy (likelihood of tripping an onScannedRobot
() event) related to it's "speed", by which I mean, the number of degrees per turn that it is spinning at...? Ok, simply: If I spin the radar faster, am I less likely to see opponents?
- There is no likelihood involved, you should get the event every time. I thought that I was not getting it because I was using firing a bullet to signal me that the event had occurred, there are more rules around firing a bullet though, my gun was hot, so it wasn't firing, I misinterpreted this as not getting the event. A much better way to check things like this is to use System.out.println() and check the robot console (the console that pops up when you click the robot name during a battle). -- BenHorner (thanks to Simonton for this answer!)
I notice that on the Radar
page, many people like to use turnRadarRight?
(Double.POSITIVE_INFINITY), is this better in any way than turnRadarRight?
- It makes it keep spinning forever. If you only tell it to turn 45, it will turn 45 this turn, but nothing next turn. Using the 'infinity lock' is another nice side effect. Once you scan a bot you tell the radar to turn *left* the amount of turn remaining. This makes it turn left infinity, ie right *negative* infinity. So next time you scan a bot, and you call setTurnRadarLeft(getRadarTurnRemaining?()) again, the getRadarTurnRemaining?() gives you negative infinity, so this time you turn 'negative left', which is right. There, try and wrap your mind around that =) -- Skilgannon
If I turn the gun it's maximum of 20 degrees, and the radar it's maximum of 45 degrees, all in the same turn, does this allow me to scan 65 degrees in a single turn?
- Thats quite an intresting question! Generally its true, you can even turn your radar 75 degrees if you turn your bot too! But if you set "setAdjustGunForRobotTurn(true);" and "setAdjustRadarForGunTurn(true);" this trik does not work anymore. But this feature might be quite useful in meele, where you have problems to get enougth enemy information. I talked with Gorded about this theme some time ago, he discovered the trick(Or does anyone use it already?). --Krabb
- Thanks, I just saw today that this info is also on the [[Robocode FAQ]]
- I have some old melee bot lying around that uses that. I made it during the time before I did any sort of robowiki-ing or roborumble-ing. If I ever get into the unlimited CodeSize melee league, it will certainly use that fact when it can. -- Simonton
Turns, how is this actually turn based?
Drawing on the screen for debugging purposes... It looks like in the code of the Interactive robot that it should be drawing a red 'x' and / or oval on the battlefield, but I don't see any such graphic... Do some people actually see these drawn graphics?
- Yes, you have to open the robot console for your bot (by pressing the button with your bot's name on it during a battle), then click the "Paint" button. -- Simonton
- Thank you very much for the tip! Is this something you learned over time, or is there a place I could have found that info? -- BenHorner
- Another useful tip: check out DrawingBot, by David Alves. It's a nice base of code for making debugging graphics in Robocode. Debugging graphics are an extremely useful tool in some parts of Robocode development. -- Voidious
Why are the Consciousness check:
questions so hard? Should I go to bed after I get one wrong 3 times in a row?