# Talk:Selecting Fire Power

## Archived discussion pages

## Smart Fire Power Selection

I've also coded up a 'smart fire power' chooser, based off the description in Dookious. However, what it seems is the problem with using the code is that it optimizes for survival, not score. As such, I'd like to put down a few thoughts/improvements I had.

The first is that, as long as our energy is higher than the enemy's (with a safety margin of course), we don't need to worry about survival, and can optimize purely for bullet damage instead. I did the math, crunched the numbers, and it turns out that the fastest way to inflict damage on an opponent is with a fire power of 2.4999. (For those interested, I took out all the variables that didn't depend on the fire power and ended up with ((4*x+2*Math.max(0,x-1))/((10+Math.floor(2*x))*Math.asin(8/(20-3*x))) ). This does not depend on distance, hitrate, or anything. Basically, if you want to inflict maximum damage in the minimum amount of time, and you *don't* have a 100% hitrate, 2.49999 is the power to shoot at. However, for certain cases against, for example, Rambots, where a 100% hitrate *is* guaranteed, the best power is 2.99999, because you can shoot slightly more often than the rambot shooting with a power of 3 yet the difference in damage is negligible.

Secondly is the case where we have less energy than the enemy. This actually has 2 sub-cases, one where a decision is made that it is possible to get higher energy than the enemy (ie win the round) and the other where it is decided that it is impossible to win this round (I call this one 'Kamikazi'). The decision between these two sub-cases is a simple projection of the enemy's hitrate and our hitrate at our most energy-efficient bullet power, and seeing if it is possible to have a higher energy than the enemy before we get killed. Taken into account should be the loss of score due to possibly reduced bullet damage, and this should be compared to the gain in score of winning the round. If it is desirable to equalize energy before the end of the match, the algorithm for maximizing energy gain should be used for bullet power (this is the one used in Dookious_1.60 and RougeDC_survival). If it is not desirable, a bullet power of 2.9999 should be used to inflict as much damage as possible while at the same time wasting energy so the enemy has less time to get bullet damage.

This entire procedure should be run every tick, including the decision as to whether to go survivalist or kamikaze. Tell me what you think, and if you find any problems with my ideas and/or logic =) --Skilgannon 18:31, 3 June 2009 (UTC)

Nice, I think I'm with you on most of your ideas here. (I remember Martin mentioning 2.49 optimal bullet power once, maybe that was his formula.) Indeed hit-rate does factor out if you ignore survivalism. Here's the survivalist formula I used for measuring the value of a bullet power, just in case anyone's curious.

`(((bulletDamage(bulletPower) + lifeGained(bulletPower)) * probabilityToHit) - bulletPower) / gunHeat(bulletPower)`

I'm not sure I agree with the "Kamikaze or not" subcases, though I like the idea. =) What I'd rather do is, for any bullet power:

- Project X total bullet damage given this round. (Would include actual damage given so far plus projected damage for this bullet power.)
- Project Y total bullet damage taken this round. (Would include actual damage taken so far plus projected damage for their average bullet power, or even tracking / projecting what bullet powers they use at what energy levels, whatever.)
- Estimate probability Z of winning this round using this bullet power.

Then you'd want to optimize something like `(X + Z*oneRoundSurvivalPoints) / (Y + (1-Z)*oneRoundSurvivalPoints)`

. In some cases you would certainly "go Kamikaze". Thoughts?

--Voidious 20:48, 3 June 2009 (UTC)

- To clarify... for projecting X and Y, I'd probably assume damage given at a constant rate until one bot hits zero. For projecting Z, though, you'd take variance into account - so even if your X/Y projections show that you will hit zero first, you still have a non-zero
*chance*of winning that round, it's just below 0.5. --Voidious 21:04, 3 June 2009 (UTC)

Hmm, I like your ideas better than mine =). I would say that `Z=X/(X+Y)`

, and what you would want to maximize would be the total score diff, so maximize `X + Z*survival - Y - (1-Z)*survival`

(which simplifies, after substituting Z, to `(X+Y+survival)*(X-Y)/(X+Y)`

). Also, this makes it very easy to add the bullet bonus into the survival. I'm liking this more and more =) --Skilgannon 22:09, 3 June 2009 (UTC)

Hmm, I'm not sure if `Z=X/(X+Y)`

is a good approximation of your probability of winning the round. For one, you can do less bullet damage than the opponent and win the round -- in fact, I think that happens a lot. And even ignoring that, if one bot is at 5 energy and is taking twice the damage of the other one, he doesn't really have a 33% chance of winning, it's probably much much lower.

I was thinking through the difference vs quotient thing yesterday, and yeah, I do think they will work the same way in Robocode. I just don't think you could find a case where a smaller difference would yield a bigger quotient or vice versa, because the total points gained in one round covers a fairly small range. It's funny you mentioning the bullet bonus... it makes me realize I don't even know all the details of Robocode scoring off the top of my head. =) I need to study up on that.

--Voidious 15:33, 4 June 2009 (UTC)

What I ended up using for Z was the x/(x+y), where x and y are the amount of time until us or the enemy runs out of energy, respectively. It makes much more sense than using damage, but I still think it's not quite perfect. Here's why: if you have a hitrate that actually gives you a positive return on energy, and their hitrate is not enough to negate that, you could theoretically go on to infinity, and then this model breaks down, because there actually still is a very small chance that you could lose the round. However, in practice, it seems to work fine =) --Skilgannon 15:51, 4 June 2009 (UTC)

- [View source↑]
- [History↑]