Robo Home | Changes | Preferences | AllPages

Since robots must expend a certain portion of their energy to fire a bullet, and this portion is always between 0.1 and 3.0, detecting a drop in a robot's energy between 0.1 and 3.0 is a very good indicator they've fired a bullet.

Most bullet impacts cause more damage than 3.0, so this system is fairly reliable; low-power bullets and wall collisions may cause mis-detections, however. This trick is the basis of most (probably all) bullet dodging systems. This trick is (apparently) also used with gun cooling rates in CoolMovement.


To make it more reliable, a bot can calculate the energy drop caused by a bullet hit to the enemy in the "bulletHitEvent?". This way the detection is more acurate, even if it will take some more code (and it is usually not worth if you are coding a Micro or a Nano). -- Albert

NB: The bullet was in fact fired the tick before you detect it, and had moved one tick as soon as it fired, so the position it fired from is where the enemy was the tick before you detected it, and it the time it was fired is 2 ticks before you detected it. And if that sounds complicated, it's because it is. -- Tango

to PEZ:
I remember that u once had mencioned, at wiki pages, something about using opponents gunheat to detect bullet firing. The problem is that i don't remember where... Do u remember where it was? I'm having trouble to get opps gun heat, cant find the appropriated method. I also tried to assume a gunheat for opp. when detected the energyDrop, and then try to calculate using guns coolRate each turn, but i wasn't able to figure out the relations between bullet_power & gunHeat... Do u know anything about these? Thnx.
PS:I f anyone else knows anything about... -- Axe

My nanobot Freddie dodges opponents when their gunheat is less than .02. I worked out a formula for it in the bot:

       if ((heat -= 0.1) <= 0.2) {		
			heat = 1;
		if ((last_energy -= e.getEnergy()) <= 3 && last_energy > 0) {
			heat = 0.2 * (last_energy - 0.1) + 0.92;
The code gives Freddie the coolest graph in Robocode and the highest specialization index. --Alcatraz

I'm not sure that i have understood the reason for the:

if ((heat -= 0.1) <= 0.2) {		
    heat = 1;
My pupose with it is to improve the bullet detection ensuring that an energy drop while heat>0, won't generate a bullet detection. Something like:
if (((heat-=0.1) <= 0) &&  (last_energy -= e.getEnergy()) <= 3 && last_energy > 0) {
   //enemy fired bullet!!
   heat = 0.2 * (last_energy - 0.1) + 0.92;
Assuming that the formula for gunHeat is (0.2 * (last_energy - 0.1) + 0.92)... Is that correct? -- Axe

Yeah, that formula is all you need. The first part was just for dodging purposes. -- Alcatraz

Thnx, Alcatraz! -- Axe

The formula is firepower/5 + 1, the - 0.1 (or purely - getGunCoolingRate?()) is required because it's already cooled one tick after you detect energydrop, I'm not sure where you get 0.92 though. -- Kuuran

I don't know either. But it worked. -- Alcatraz

I'll try Kuuran's formula, unfortunately Alcatraz formula isn't working for me. Tell u later... -- Axe

Kuuran's formula is correct, but maybe the variable last_energy in Alcatraz formula indicates the powerdrop and just is reused to decrease codesize. But then i still don't understand the -0.1 in this place: it seems already accounted for in the +0.92 (whis is 1-0.1 + a fudge factor?). I am currently also working on a nano that uses the Gun cooling rate to dodge. It works pretty well against some top nano's and hopelessly looses from others. Problem is there is not enough room left for a decent gun. I will release him soon anyway, just to see if this is a direction to go with movement. --Loki

Dummy is brilliant, just look to his TimmyTheCheerfulMonkey as proof. Inspired by that, and for all those AM systems that need something like this, here is a virtually foolproof set of OneOnOne filter to find the bullet power fired (if any) of every EnergyDrop:

First you will need to track enemy velocity, HitRobotEvent?s, and BulletHitEvent?s.

If EnergyDrop of any amount is detected:

Whatever remains is the power of the bullet fired.

If you want to be hyper-accurate you should include one last check to see if the inactivity time has hit. If it has the bots will lose (I believe) a constant 0.1 per tick. If you are losing this, subtract that amount from your opponent's EnergyDrop as well. Modification for Melee is possible, but you can never be foolproof there, as opponent bullets hitting other opponents are an unknown. Comments? -- Kuuran

No other comments than a big THANKS for splitting this up. It might seem like small details, but when WaveSurfing you can't be too accurate. I'll see if I can fit this into CassiusClay and will get back with questions should I stumble. -- PEZ

If you want to be even more than hyper-accurate, you may want to check onHitByBullet?() and adjust enemy EnergyDrop accordingly, as the enemy can fire a bullet, while his previous bullet hits you (so he gains and loses energy in the same tick). I'm not sure wether checking for RobotHits? is useful, though; ever seen a bot dodge at point blank range? :-p --Dummy, still lurking around, still needs to learn to use the 'Preview' feature while editing stuff ;)

Heh, I knew I forgot something, yeah, energy gain. The robot hits is more to know the enemy fired than to really worry about the bullet, it can be important for collecting stats or to reset gun heat. -- Kuuran

I've been debugging my EnergyDrop detection (thanks for reminding me of energy gain ;)), and came to the conclusion that the energy drop resulting from a wall hit can never be precisely detected. You only know the enemy's velocity from the last tick before the wall hit, so, if he was accelerating/decelerating, your damage calculation will be off by +/-.5. -- ABC

Out of curiousity ABC, how much code do you have to maintain the state of an enemies energy? I am currently only looking at energy at scan time and I am sure I can gain some added benefit there but I am wondering if it is worth the effort now or if it is something for later. -- jim

I'm not sure I understand your question. I have something very close to what Kuuran described up there, as close as I could get to a 100% acurate enemy bullet fire detection. Coupled with a more precise hit point calculation (both real and simulated) and some other small tweaks, It looks like it was worth around 5 ranking points for Shadow... -- ABC

On a different tact, is all of this is predicated on the fact that you use the default Robocode Event priorities? What happens if you set the EventPriority? of your scan event to 99? If I read things correctly, would that not mean that your scan event would trigger before any of the other events triggered and thus you would be able to ignore the other worries about everything but wall strikes. I have to be wrong as I do this and my surfing is far from perfect but thats the assumption I am under right now :) -- jim

Event priorities are just the execution order of the code you put in the handlers, they don't influence the main Robocode loop. Your code (event handlers and run method) will always be executed after every action that can influence the bot's energy has been executed for that tick. So, no matter how you set the priorities, you'll always see the opponent with the same energy in every event. There is no way to execute the scan event before the bulletHits/wallHits/bulletFire happen. -- ABC

Sure. If the enemy only fires a 3.0 bullet it's simple, you'll see him with 47 energy anywhere on your code. But if, in this same tick, he get's hit by a bullet, he'll be at 47-energyLoss. What I'm saying is that Robocode will execute all the actions like the bots/bullets movement and collisions (and consequent energy losses/gains), and only after everything happens will it generate the events that are executed by your code. You will see the enemy with 47-energyLoss in every event handler, the execution order (priority) doesn't matter. It's like everything (movement/collisions/etc) happens _exactly_ at the same time, and in the scan you always see the end result. Changing the priorities does not influence the order of the events, just the order of execution of your code in the handlers. -- ABC

Does inactivity kick in for all bots at the same time? Does it occur (default) 450 ticks after the last bullet landed, or damage was taken (e.g. wall / robot collision)? I'm pretty sure firing bullets does not reset the inactivity timer. -- Martin

I think that bullets with less than 1.0 power do not count, so if both bots fire 0.1 power bullets, inactivity will kick in after 450 ticks. The energy of all bots is drained simultaniously until one dies, then the inactivity timer will be reset. If you win by inactivity timeout, you do not get a bonus. -- GrubbmGait

Not having looked at the code, this is my guess based on my experience:

My guess is that the timer is never "reset" but reversed something like this: onEnergyLoss?: Timer -= energyLost * C, where C is a constant. Someone who knows more might want to confirm it though. -- Kinsen

After some test runs i have discovered a bit more about the inactivity timer, at the begining of each round a number from 1 to 10 is chosen this is the amount of energy loss that must take place in order for the timer to be reset

I hope this clears some things up, and if you want a to test to see how good you energydrop detection try it out on

give these a shot, doesn't mean your perfect but pretty close - Gorded

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited January 7, 2007 1:56 EST by bas2-toronto47-1242398936.dsl.bell.ca (diff)