Power -- a poor approximation.

Yakk

Cheftan
Joined
Mar 6, 2006
Messages
1,288
So there is a problem with the power meter -- it doesn't reflect ability to fight wars that well.

After some investigation, it appears that the amount a unit contributes to Power is determined by the iPower stat in the XML file. BetterAI doesn't change XML by policy.

However, this value is pushed through here:
Code:
int CvUnitInfo::getPowerValue() const
{
	return m_iPowerValue;
}

So we can do transformations of the XML power value in-code.

To give an idea how bad it is: (land units)
Warrior: 1
Archer: 2
Spearman: 2
Charoit: 2
Axeman: 3
Horse Archer: 3
Catapult: 3
Longbow: 4
Crossbow: 4
Elephant: 4
Trech: 4
Maceman: 5
Pikeman: 6
Musketman: 6
Knight: 6
Cannon: 8
Rifleman: 10
Gernader: 10
Machine Gun: 10
Cavalry: 12
Infantry: 16
Marine: 18
SAM Infantry: 20
Artillery: 20
Gunship: 20
Tank: 25
Mech. Inf: 30
Modern Armor: 40

This is (basically) linear in unit Combat.

But unit power isn't linear in Combat -- higher Combat both increases damage done and increases chance to do damage.

I've run the numbers before, and the power gain from higher Combat is roughly quadratic --ie, a strength 20 unit is worth about 4 strength 10 units in a knock-down last-unit-standing brawl. In a skirmish, the strength 20 unit is even better.

Given that existing unit power is roughly linear in Combat Strength, if we square the value we'll get a better approximation of actual Power.

The issue remaining is that Power is added to other factors (like technology, buildings, etc) to create a total Power statistic.

We can't just square everything, sadly.

But if we can create a more accurate Power statistic, this will generate better AI performance -- the AI with a swarm of crappy units won't think it is more powerful than the high-tech civilization next to it. And the AI with a tech advantage will quite rightly figure out it can crush the low-tech civilization next to it...
 
Note that the exponent (^2) can be tweaked if we want different behaviour. I'm thinking ^1.5, to reflect the fact that the opponent can upgrade units on you, and the problem with high-end units in that a handful of them can't defend everywhere...

Second pass: Buildings and Technologies.

Reading through the iPower stats of Buildings and Technologies...

Both range from 0 to 12 or so. Neither value the "high end" advances as much as they should, compared to the low-end advances: a factory represents a bigger threat in war than 2 extra warriors. ;)

For technologies, scaling them by era might work.
*2 for ERA_ANCIENT
*4 for ERA_CLASSICAL
*10 for ERA_RENAISSANCE
*30 for ERA_INDUSTRIAL

The above multipliers reflecting a rough average of the unit-strength from each era.

For buildings, non-national/world wonders are all 4 or under Power.

World/national wonders vary from 5 to 10 (great wall).

We could pull off the same trick -- you look up the building's prereq tech era, and scale it by the same above scales. This will undervalue Barracks somewhat -- but by the modern era, everyone will have Barracks, and people won't care.

Barracks: 3->6 power
Forge: 2->8 power
Factory: 2->60 power

Before, a Factory was worth 5% of a Tank. Using the ^1.5 system, it will now be worth 24% of a Tank: a civilization with lots of Factories is a danger in a war, just from it's raw production, and 4 average cities with Factories can pump out a Tank every few turns.

...

Let's look at the list of units under the (^1.5) transformation (round down):
Warrior: 1
Archer: 2
Spearman: 2
Chariot: 2
Axeman: 5
Horse Archer: 5
Catapult: 5
Longbow: 8
Crossbow: 8
Elephant: 8
Trech: 8
Maceman: 11
Pikeman: 14
Musketman: 14
Knight: 14
Cannon: 22
Rifleman: 31
Gernader: 31
Machine Gun: 31
Cavalry: 41
Infantry: 64
Marine: 76
SAM Infantry: 89
Artillery: 89
Gunship: 89
Tank: 125
Mech. Inf: 164
Modern Armor: 253

That is a closer power ratio: 1 Infantry can take out 2 Riflemen in an even fight and come out alive, on average.

Inf with Combat 2 vs Rifle with Combat 2:
29 vs 16.8
Inf, on average, takes (16.8/29)^2 damage -- 33.5%.

66.5% Inf with Combat 2 vs Rifle with Combat 2:
Inf power reduced to 22.48 (second fight -10%, power reduced by (33.5%)/2).
Inf, on average, takes (16.8/22.48)^2 damage -- 55.8%.

Inf lives with 10.7% HP left, on average. This is an approximation of combat, but it does reflect what actually happens pretty reasonably.

Ie, if 10 Infantry attack 20 Riflemen, the Infantry will probably kill 10 Riflemen in the first wave, and then the 10 remaining Riflemen counterattack still isn't likely to succeed.

Thoughts?
 
Although I can't add anything to the thread, I must say that I find this fascinating. I'm sure that someone with a bit more time on their hands could double-check your system and figures, but at a glance it looks very good.
 
I'm afraid it's much more complicated than that, the old units can be upgraded, that's why they're valuated in a more linear way.

There are many other factors that are part of the decision in war declaration too, the power ratio is only one of them. What I remember is that experience and promotions are looked at too, maybe not in the power score but elsewhere they are. I didn't look at this power score extensively though.

Our best bet is probably to wait for the BtS version to see the algorithms they use. I hope they get rid of some stupid things in the XML files (warmonger respect, attitude needed to attack, and so on...) and improve the power valuation.
 
/shrug -- if the worst thing that happens is that a player can choose to keep their units downgraded, convince enemies to attack, then rocket up in power...

I'm OK with that. That requires mass upgrade of units -- and for players, that's expensive and inefficient. As many good players have pointed out: unit production is cheap, but cash is research.

AIs upgrade units at a discounted rate -- so once they have the new technology, their current power will be reflected in the graph relatively shortly as they upgrade their existing units.

By knowing what the current power balance actually is, the AI can be smarter, and grab those windows of opportunity that a technology edge grants.

I don't think Power is factored into the score directly -- and if it is, we can just leave the score math unchanged.
 
*nod*, that lines up with what I found in the code. And is much easier to read. :)

I'm going to mod my DLL with a better power approximation (at both the graph level, and at the AI-making-decisions-about-attacking-a-stack level) and see if it makes the AI smarter about war, battles and the like. :)
 
Nice work ! It certainly looks like an improvement (I didn't read that part of the code to be certain, though).

If we weren't so close to BtS release, I would have merged that with my own changes on wars, but now I don't feel it's really necessary since Blake made a whole new AI for BtS. This feeling is reinforced by the lack of interest for BetterAI nowadays (everybody waits for BtS, it's normal...). I had virtually no feedback on my own changes, so I really think the best is now to wait and to work all together on Blake's new AI after the release (maybe even after the patch).
 
I've been testing using AD1000 (well, AD1001, epic speed variant).

Between the "fight wars on own continent", the "better power approximation of empires", the "don't be a paranoid git about gimpy units threatening your city" and "don't be a paranoid git about borders", I get a significantly larger amount of territory changing hands at the start of the simulation.

Arabia overruns northern India, Spain takes Cordoba on turn 2, which frees up a tonne of units for Spain, which leads Spain to attack and take Sicily.

I attacked a city and got some bad rolls. The units in the city proceeded to charge out and wipe out my stack -- I think because the stack was no longer considered a significant danger to the city.

Looking at the history, I see that the Japanese managed to take a mainland Chinese city!

The mongol invasion of China wasn't that effective. I can do better as a human without pulling off many tricks -- I suspect the AI's problem is an insufficient tendency to "mass" troops for attacks -- ie, if you have a bunch of attacking units, they should have a tendency to clump up together and attack cities in waves.

The AI is still insufficiently opportunistic -- it should see an undefended or underdefended city, muster an army, and attack it. That by itself would change the game significantly.

But it seems like an improvement. Empires with larger armies are expanding at the expense of empires with smaller armies!
 
Yakk, how do you get that squaring the strength is a good approximation?

I did some calculations on this, and after finding a reasonable way to value wounded units in a stack fight, came up with ^1.3ish.

I used the same model to come up with an easier to calculate heuristic, which is sort of 3/4 linear and 1/4 quadratic, which I've implemented so that CvSelectionGroupAI::AI_compareStacks uses it.

But I suppose we'd better get things right first.

There are many other factors that are part of the decision in war declaration too, the power ratio is only one of them.

I thought you'd decided that the existing algorithm for war declaration is inadequate. Maybe an improved power should be more important in a new or modified one?

As for waiting for BTS, it's quite likely that it hasn't changed this too much. I've renewed my interest in Civ4 precisely because BTS is round the corner. Now is not a bad time.
 
Well looking at those charts, I think the values added by techs should be drastically changed. There are techs in there that should add way more soldiers (potential) and others that could easilly add less. I don't know if this is would work out nicely for the ai, since as a human player I like to use a discovery of a tech as a deciding factor for war, instead of how the ai will build up units and use that for a deciding factor in power estimates.

I'm just throwing it out there for ideas.

For example 3 axeman are worth more than discovering guilds, flight or assembly line.:eek:
 
I think that for a human player, the invention of a technology is very important because we know what we can do with that technology. The AI gets a technology and at that point isn't in a better position. Then another part of the code notices that it can upgrade units and the AI starts to upgrade units. The AI cannot build certain older units and only some newer stronger ones and the real strength of the technology becomes apparent. But the upgrading part and the building newer stronger units is already incorporated in the power score of these newer stronger units.
So when the strength of the units is already incorporated in the power score, why should it also be incorporated in the technology itself?
 
Yakk, how do you get that squaring the strength is a good approximation?

HitRatio * DamageRatio = Strength Ratio

If you have a StrengthRatio of 5:1 in your favour, you will expect to take 20% damage while doing 100% damage to the target.

HitRatio is [(A)/(A+D)] / [(D)/(A+D)] = A/D

So that's linear.

Damage Ratio is more complex. However, if you freeze one side (say, D = 10), and vary A from 10 to 30, the Damage the attacking unit does ends up being about:
sqrt(A/D) * 20
to a first degree of approximation. (I didn't do simulation or analysis, just tossed the values into a spreadsheet, and noted that sqrt was a half-decent fit -- it is better the closer you are to A=D.)

Now, if you take sqrt(A/D) / sqrt(D/A) you get A/D again.

So the StrengthRatio, if A is within a factor of 3 of D, tends to be about (A/D)^2.

Now as a unit gets damaged, it's ability to do damage drops. Hence changing ^2 to ^1.5.

I did some calculations on this, and after finding a reasonable way to value wounded units in a stack fight, came up with ^1.3ish.

I used the same model to come up with an easier to calculate heuristic, which is sort of 3/4 linear and 1/4 quadratic, which I've implemented so that CvSelectionGroupAI::AI_compareStacks uses it.

But I suppose we'd better get things right first.

Neat!

I thought you'd decided that the existing algorithm for war declaration is inadequate. Maybe an improved power should be more important in a new or modified one?

Having an accurate estimation of what the relative power of the nations are seems like a decent first step. :)
 
Interesting to see how you got to that formula. Your first two steps are quite accurate. The to hit ratio indeed results in a A/D strength ratio. Also the damage ratio results in a A/D strength ratio. (I did a mathematical approximation and A/D is a close approximation as long as A/D is between 1/2 and 2). However, I think you seriously underestimate the effect of the weaker strength once units get damaged.

For instance, a strength 2 unit is attacking several strength 1 units. Based on the approximation of the damage and to hit chances, you would expect the strength 2 unit to kill a strength 1 unit and have 75 out of 100 hitpoints left (because it is about 2*2= 4 times as strong when at full hitpoints). However at 75 hitpoints, its damage is reduced, its chance to hit is reduced and it can absorb far fewer hits (which is also very important). So its combat effectiveness is severely reduced.

Below follows a more detailed analysis a strength 2 units facing several strength 1 units. It's an approximation that shows that the unit will not beat a lot more than 2 strength 1 units when it doesn't heal between fights (which is the assumption we take to see how many units it can defeat in a row).

I used a combat calculator and it showed me that after beating a strength 1 unit, the strength 2 unit is expected to have 73 hitpoints left (and the unit wins very likely, 99.1% chance). If it were to lose, it would on average do 70 hitpoints of damage.

Then continuing with 73 hitpoints, it has a chance to win of 81.6% and if it wins it is expected to have 44 hitpoints left. If it were to lose, it would on average do 56 hitpoints of damage.

Continuing with 44 hitpoints, it is expected to lose (win chance 17.8%) and would do 42 hitpoints of damage. If it were to win, it would be expected to have 21 hitpoints left.

Continuing with 21 hitpoints, it is expected to lose (win chance 1%) and would do 17 hitpoints of damage. Lets stop here.

So the total expected damage it inflict on the strength 1 units is:

0.991 *1 + 0.009 * 0.70 + 0.991 * (0.816 * 1 + 0.184 * 0.56) + 0.991 * 0.816 * (0.178 * 1 + 0.822 * 0.42) + 0.991 * 0.816 * 0.178 * (0.010 * 1 + 0.990 * 0.17) =2.357 units of strength 1

Okay, I'm a mathematician, so nobody needs to tell me that you may not use expected values the way I did here. You should continue the calculations with the exact amount of hitpoints and chances and not the expected value and then look at each case and sum everything up. But that is far too much work and this is bound to be a good approximation.

The point is that 2.357 is not a lot more than 2. (2^1.5 = 2.83). Most battles will be between units with a lower variation in strength than 2 to 1. So I really don't think your approximation is better than the standard one from Firaxis (just the unit strengths).

BTW: 2.357 is close to 2^1.25 (log 2.357 / log 2 =1.237), but I don't know if that would be a good approximation in general. In my opinion, just some rough calculations with some unit strength ratio's and the combat calculator mentioned below might get a good formula for the real strength value of units. But I wonder if it will be worth it as the real strength isn't that much higher than the strength value of the units.

Another BTW: repeatedly attacking with a unit until it dies to see how much stronger it is as another unit is probably not the best way to find its true strength value. The problem is that your unit is always going to die by the assumption that you attack until you die. In the game, you wouldn't do that. You would use the unit in a smarter way.
However, once you start attacking a large stack of strength 1 units with a smaller stack of strength 2 units, you do want to know if the counterattack isn't going to kill your stack fo strength 2 units and therefore you want to know the real power ratio between strength 2 and strength 1 units. I think that 2.357 is closer than 2^1.5 in such a case.

This of course does not disqualify the value of improving the way stacks with siege units see their chances of defeating an enemy stack. That work is invaluable and will seriously help the AI to defeat attacking SOD's. I just wanted to add my opinion to see if it might help improve the approximation of the power of units.

You can find the combat calculator that I used here:
http://c4combat.narod.ru/c4c.htm

addendum: I'm pretty tired, so I hope I didn't write something stupid in this post. :crazyeye: :crazyeye:
 
Interesting.

Using the same combat calculator, we get 2.205 average units killed per strength 2 unit. This says that the strength 2 unit is 4.4 times stronger than a strength 1 unit at killing strength 1 units.

In which case, my "^2" is an underestimate, probably thanks to the discontinuities.

Graphing strength^2 vs average number of strength 1 units killed, it stays above 0.5 (going up to 0.65) from 1 through to 2.5 -- implying that the square is a decent approximation of power. (by 3.0 it has dropped to 0.4).

The problem with your math is that the average doesn't tell you enough about the distribution of HP remaining. The handful of unlucky outliers cause significant problems with the result.

But the calculator you linked can give you "average number of units beaten".

Divide average number of units beaten by a 2 strength by a 1 strength, and you get the ratio of utility. :)

Graph strength^2 vs average number of strength 1 units beaten, and you get a squiggle that doesn't move all that much from 1.0 to 2.5.
 
Interesting.

Using the same combat calculator, we get 2.205 average units killed per strength 2 unit. This says that the strength 2 unit is 4.4 times stronger than a strength 1 unit at killing strength 1 units.

In which case, my "^2" is an underestimate, probably thanks to the discontinuities.

Graphing strength^2 vs average number of strength 1 units killed, it stays above 0.5 (going up to 0.65) from 1 through to 2.5 -- implying that the square is a decent approximation of power. (by 3.0 it has dropped to 0.4).

The problem with your math is that the average doesn't tell you enough about the distribution of HP remaining. The handful of unlucky outliers cause significant problems with the result.

But the calculator you linked can give you "average number of units beaten".

Divide average number of units beaten by a 2 strength by a 1 strength, and you get the ratio of utility. :)

Graph strength^2 vs average number of strength 1 units beaten, and you get a squiggle that doesn't move all that much from 1.0 to 2.5.

While it can be interesting to compare the average number of strength 1 units killed by strength 2 units to the number killed by strength 1 units, I do not agree that it is a good approximation of their relative strength. When I looked at the calculator, I thought about using that statistic because it is very convenient. But it completely disregards the average amount of damage done by units that lose and while a strength 1 unit loses far more often than a strength 2 unit, it still inflicts a significant amount of damage while doing so. Disregarding that damage underestimates the strength of the strength 1 units. The weaker a unit is, the more important the damage it does and the less important the number of kills.

I didn't do those calculations for fun, but because in that way I don't forget about the damage done by units that lose.

An example where these mathematics go wrong:

A strength 2 unit kills on average 2.2 strength 1 units.
A strength 1 unit kills on average 0.53 strength 1 units.
A strength 0.5 unit kills on average 0.0088 strength 1 units.

According to your logic, a strength 2 unit is 2.2/0.53 = 4.2 times as strong as a strength 1 unit. A strength 1 unit is 0.53/ 0.0088 = 60.2 times as strong as a strength 0.5 unit. The strength ratio is 2 in both cases, but the ratio in number of strength 1 units killed is totally different.

Edit: By the way, it is far easier to criticize a theory of approximating unit strengths than to come up with a decent one. I don't mean to attack you personally here, I just simply disagree with your approximation.
 
I used a combat calculator and it showed me that after beating a strength 1 unit, the strength 2 unit is expected to have 73 hitpoints left (and the unit wins very likely, 99.1% chance). If it were to lose, it would on average do 70 hitpoints of damage.

Then continuing with 73 hitpoints, it has a chance to win of 81.6% and if it wins it is expected to have 44 hitpoints left. If it were to lose, it would on average do 56 hitpoints of damage.

Continuing with 44 hitpoints, it is expected to lose (win chance 17.8%) and would do 42 hitpoints of damage. If it were to win, it would be expected to have 21 hitpoints left.

Continuing with 21 hitpoints, it is expected to lose (win chance 1%) and would do 17 hitpoints of damage. Lets stop here.

So the total expected damage it inflict on the strength 1 units is:

0.991 *1 + 0.009 * 0.70 + 0.991 * (0.816 * 1 + 0.184 * 0.56) + 0.991 * 0.816 * (0.178 * 1 + 0.822 * 0.42) + 0.991 * 0.816 * 0.178 * (0.010 * 1 + 0.990 * 0.17) =2.357 units of strength 1

I'm fairly certain that, as with the number of kills, you'd find that a strength 1 unit deals on average less than 100 damage to healthy strength 1 units when fighting to the death.

The reason for this is that you are overvaluing wounded enemy units compared to the friendly one. when your on 50, you going to inflict less than 50% of the damage that you were going to when you're on 100 but if you take the surviving enemy down to 50 hitpoints, that's only 50% of a kill.

Maybe the obvious thing to do then would be to write a simulation,where a strength 2 unit would fight strength 1 units until it died, then the survivor would be the champion, fighting strength 2 units etc. for ten thousand units and taking the kill ratio. That might not be a good model of any real situation but at least it's symmetrical. But you don't see me rushing to do it.

I got my ^1.3 by taking something like Yakk's KR, which is actually the ratio of expected damage to each unit before there's a chance one of them has been killed and assuming it was the ratio of the damage for the whole battle. Then I looked at how the survivor fared against more units, particularly if it was strong enough to beat the second. Hopefully, that's a sensible average, it's what would happen if the combat per round were infinitesimal and the battle was deterministic.

That shouldn't be that good so if anyone can come up with anything useful, they're welcome.

As well as strength^1.32, I came up with:

effective strength = maxstr * health(out of 1) * sqrt( (1+ health) / 2)

for damaged units. I suppose testing those against a better model would help.
 
That simulation is pretty easy to throw dynamic programming at.

For a given attacker strength A and defender strength D, build an array of [Defender Starting HP][Attacker Starting HP] that contains:

1> Has this value been calculated before?
2> A distribution of results: Attacker win HP and probabilities, Defender win HP and probabilities.

Then use that array to cache the results of battles -- it is only 10,000 or so entries. This means you never have to calculate the results of more than 10,000 battles!

Use that array to run a simulation of killing, say, 1000 strength 10 defenders -- if you neglect the HP of the last defender, this will generate an error of less than 0.1%, and I guarantee our curve will be worse than that! Repeat for strength 10, 11, ..., 28, 29 and 30 attackers.

That will give us a map from (A/D ratio) -> (number of attackers needed to kill 1000 Defenders).

Divide the number of attackers by 1000, and we get a "real" strength ratio based off of the base strength ratio.

It seems computationally feasible. Too bad I don't got time for a while (too much real life) to implement it. Anyone else want to take a swing?
 
I'm fairly certain that, as with the number of kills, you'd find that a strength 1 unit deals on average less than 100 damage to healthy strength 1 units when fighting to the death.

The reason for this is that you are overvaluing wounded enemy units compared to the friendly one. when your on 50, you going to inflict less than 50% of the damage that you were going to when you're on 100 but if you take the surviving enemy down to 50 hitpoints, that's only 50% of a kill.

Maybe the obvious thing to do then would be to write a simulation,where a strength 2 unit would fight strength 1 units until it died, then the survivor would be the champion, fighting strength 2 units etc. for ten thousand units and taking the kill ratio. That might not be a good model of any real situation but at least it's symmetrical. But you don't see me rushing to do it.

I got my ^1.3 by taking something like Yakk's KR, which is actually the ratio of expected damage to each unit before there's a chance one of them has been killed and assuming it was the ratio of the damage for the whole battle. Then I looked at how the survivor fared against more units, particularly if it was strong enough to beat the second. Hopefully, that's a sensible average, it's what would happen if the combat per round were infinitesimal and the battle was deterministic.

That shouldn't be that good so if anyone can come up with anything useful, they're welcome.

As well as strength^1.32, I came up with:

effective strength = maxstr * health(out of 1) * sqrt( (1+ health) / 2)

for damaged units. I suppose testing those against a better model would help.

You are correct that the weakened units are more weakened then I used in the damage calculations and that I should have taken that in account for the effective damage that strength 2 units would inflict on strength 1 units. The value of inflicted damage should thus be higher than what I suggested if you take that into account.

A strength 1 unit at 50 hitpoints has half the hitpoints, a seriously reduced chance to hit and a seriously reduced damage output based on the average of its full health strength and its half strength health. So simply taking the reduced hitpoints as damage is not good enough.

I wonder how your effective strength formula was derived. It looks interesting. The factor health(out of 1) would account for the reduced chance to hit. The last factor looks as if it has to do with the reduction in damage output, but I don't directly see how it was derived, the square root looks weird. This effective strength could be used to see how the battle goes, but then you still have to remember the loss in hitpoints.

I'd expect something like:

Effective strength = maxstrength * (hitpoints/100) * ((hitpoints + 100)/200)
and hitpoints (instead of 100) left to absorb damage.

The effective strength is used to determine the rate at which a wounded unit inflicts damage.

Explanation: If you have lost hitpoints, then you don't hit at a rate based on your maxstrength but based on maxstrength * (hitpoints/100). This means that the rate at which you hit your opponent is also reduced by a factor (hitpoints/100). The damage that you do per hit is based on maxstrength * ((hitpoints + 100)/200). Therefore the damage that you do is also reduced by a factor ((hitpoints + 100)/200). (This is only true as long as the relative strength of the units is not substantially larger than 2.) These two factors are combined in the formula. The effective strength is used to determine the rate at which a wounded unit inflicts damage.

Lets see what I get when I use that formula.

A strength 2 unit hits a strength 1 unit twice as often and does twice as much damage (or close to that). So you'd expect it to beat the strength 1 unit and have 75 hitpoints left.

A strength 2 unit with 75 hitpoints has an effective strength of

2 * 0.75 * 0.875 = 1.3125 (hits at a rate of 75%, damages at a rate of 87,5%)

A strength 1.3125 unit hits a strength 1 unit 1.3125 times as often and does 1.3125 times as much damage per hit. So the strength 1.3125 unit loses hit points at a rate of 1 while the strength 1.3125 unit loses them at a rate of 1.3125^2.

Okay, that means that the strength 1 unit loses 100 hitpoints while the strength 1.3125 unit loses 100/1.3125^2= 58 hitpoints.

That means that the strength 2 unit has 75-58=17 hitpoints left.

A strength 2 unit with 17 hitpoints has an effective strength of

2 * 0.17 * 0.585 = 0.1989

The damage ratio formula is not really good once the difference in strength is greater than 2 (which is the case here with 0.1989 and 1). So the effective strength formula is not that useful here to determine the rate at which the wounded unit of strength 2 damages the strength 1 unit. So I just use the combat calculator to see how much damage a strength 2 unit with 17 hitpoints can still inflict on a strength 1 unit on average: that would be 7 hitpoints of damage.

That would reduce the effective strength of the strength 1 unit to

1 * 0.93 * 0.965 = 0.89745. So the wounded strength 1 unit would do damage as a strength 0.89745 unit would do at full health but only has 93 hitpoints. So its 'damage' is
1- 0.93 * 0.89745= 0.165

So the strength 2 unit defeated 2.165 strength 1 units. 2.165 is about 2^1.114

That simulation is pretty easy to throw dynamic programming at.

For a given attacker strength A and defender strength D, build an array of [Defender Starting HP][Attacker Starting HP] that contains:

1> Has this value been calculated before?
2> A distribution of results: Attacker win HP and probabilities, Defender win HP and probabilities.

Then use that array to cache the results of battles -- it is only 10,000 or so entries. This means you never have to calculate the results of more than 10,000 battles!

Use that array to run a simulation of killing, say, 1000 strength 10 defenders -- if you neglect the HP of the last defender, this will generate an error of less than 0.1%, and I guarantee our curve will be worse than that! Repeat for strength 10, 11, ..., 28, 29 and 30 attackers.

That will give us a map from (A/D ratio) -> (number of attackers needed to kill 1000 Defenders).

Divide the number of attackers by 1000, and we get a "real" strength ratio based off of the base strength ratio.

It seems computationally feasible. Too bad I don't got time for a while (too much real life) to implement it. Anyone else want to take a swing?

A simulation would probably be very exact if it was written correctly, and it should clearly be possible to calculate it in a very reasonable time. I'm not a programmer, so I can't help you with that.

Edit: my sincerest apologies to people who dislike mathematics and happen to come across this post. :p
 
Don't worry, you're in good company: I think Blake made the same mistake in Better AI's valuation of wounded units in comparing stacks.

Your multiplier is right. It's just not clear what your applying it to. It applies to the ratio of expected damage per round. Yakk has already explained the maths for healthy units a couple of times. That is just his (misnamed) KR:

A "simpler" damage equation, for our purposes, is:
Dam(A) = 20 * (3*A/B + 1) / (3 + A/B)
DR(A) = DamRatio(A) = (3*A/B + 1)^2 / (3 + A/B)^2 = Dam(A)^2/400
And
Hit(A) = A/(A+B)
HR(A) = HitRatio(A) = A/B

So DR(A) = (3*HR(A) + 1)^2 / (3 + HR(A))^2

KR(A) = KillRatio(A) = HitRatio(A) * DamRatio(A)

Damage Ratio is more complex. However, if you freeze one side (say, D = 10), and vary A from 10 to 30, the Damage the attacking unit does ends up being about:
sqrt(A/D) * 20
to a first degree of approximation. (I didn't do simulation or analysis, just tossed the values into a spreadsheet, and noted that sqrt was a half-decent fit -- it is better the closer you are to A=D.)

Now, if you take sqrt(A/D) / sqrt(D/A) you get A/D again.

So for unwounded units, both the HitRatio and DamRatio are proportional to strength (i.e. A. I now realise that Yakk's explanation is this thread confusingly calls KR Strength ratio.)

The factor (hitpoints / 100) applies to the strength used in HitRatio and the factor ((hitpoints + 100) / 200) applies to the strength used in DamRatio.

That should make it more obvious where the square root comes from. But it raises the question of why the first factor isn't square rooted as well.

For a battle between wounded units to be 50-50, it's not enough for the ratio of expected damage per round to be 1. If the two units take damage at an equal rate, the healthier one would win. If the health of both units is high compared to the damage per round, then the battle will be about even when:

HealthRatio * Ratio of Expected Damage per round = 1

We want a fully healed unit of effective strength and our unit to have even odds. That is:

(HitPoints / 100) * (strength^2 * (Hitpoints / 100) * ((Hitpoints + 100) /200) / effective strength^2) = 1

That rearranges to give my expression for effective strength, right?

Anyone paying attention might question whether the square root is actually necessary as DamRatio is already a square:

DR(A) = DamRatio(A) = (3*A/B + 1)^2 / (3 + A/B)^2 = Dam(A)^2/400

So instead of the square root factor we would have:

(3 * ((HitPoints + 100) / 200) + 1) / (3 + ((HitPoints + 100) / 200))

Giving:

Effective Strength = Strength * (Hitpoints / 100) * ((500 + 3 * HitPoints) / (700 + Hitponits))

This is what I've implemented where Blake was using your expression in Better AI.

As we've already used the square root approximation for strength, this isn't necessarily any better. In the most interesting case, where a high strength wounded unit is fighting lower strength undamaged units, the expression with the square root is better as it reduces the error in Yakk's original approximation. When a higher strength unit fights a very wounded lower strength unit, it doesn't take much damage anyway.

That's why I'll stand by my first expression. For the lost:

effective strength = maxstr * (Hitpoints / 100) * sqrt((Hitpoints + 100) /200)

Edit: my sincerest apologies to people who dislike mathematics and happen to come across this post. :p

You don't think we lost them long ago?
 
Back
Top Bottom