Simulations would require a fair bit of code. The combat code requires real units so you'd either have to duplicate all of it or cut and paste it into new functions and have the real ones call them to do the same thing they did before. Then have fake units use that code.
First strike and collateral damage aren't too hard. Just add a bit when they apply. The rock paper scissors modifiers are a bit harder. If most of my attack stack isn't spearmen, then even though half the defenders are chariots, it's not worth adding more. If I'm defending with some spearmen then I might want to add extra defence strength but no more than the total strength of attacking mounted units. If a few of them have shock and I have a war elephant, things start getting complex.
I pointed out in your power thread somewhere in this forum that I don't think squared is the right power. I've implemented and tested the formula I came up with. This thread is worthless without code:
Sorry for the spam, copy and paste is just faster than writing pretty formulae. That's a formula just using health and strength.
I don't know how sensible the 4/3 power is but it's definitely better than just adding up the strengths when the city defenders are likely to be individually stronger.
With both those, the AI was much better at taking cities. It did fail sometimes, but the survivors were damaged enough for me to believe that it might have stood a decent chance if not for the RNG gods.
It was much a better judge than I am, anyway. Is there any need to put the data-crunching-challenged player at a disadvantage?
Method 2: Come up with a complicated formula encompassing collateral damage, first strikes, various promotions of the units and match ups of units to estimate the strength of the stack. The advantage of this method is that it is surely possible to enter this formula into the game and a computer could pretty quickly calculate the strength of the stack. The disadvantage is that it's pretty hard to come up with a formula that works well in all the possible match ups between 2 stacks of units. There are lots and lots of variables with all the promotions and bonuses that units can get.
First strike and collateral damage aren't too hard. Just add a bit when they apply. The rock paper scissors modifiers are a bit harder. If most of my attack stack isn't spearmen, then even though half the defenders are chariots, it's not worth adding more. If I'm defending with some spearmen then I might want to add extra defence strength but no more than the total strength of attacking mounted units. If a few of them have shock and I have a war elephant, things start getting complex.
For heuristics, we have:
A first-pass RealPower estimate:
(1/4 of unit-type-specific +% combat bonuses) * (100%+target-square combat bonuses)^2 * (Combat Strength^2, including the combat promotions) * (HP remaining as a percentage) * (50%+HP remaining/2)
only counting units that can attack.
(Mostly, that isn't pulled out of my ass, but rather remembered from the last time I crunched the numbers. The unit-type specific % thing is out of my ass -- we could split power up into unit-type chunks, and use that to weigh our +% combat bonuses?)
I pointed out in your power thread somewhere in this forum that I don't think squared is the right power. I've implemented and tested the formula I came up with. This thread is worthless without code:
Code:
int CvUnit::currEffectiveStr(const CvPlot* pPlot, const CvUnit* pAttacker, CombatDetails* pCombatDetails) const
{
int iStrength = currCombatStr(pPlot, pAttacker, pCombatDetails);
iStrength *= (5 * maxHitPoints() + 3 * currHitPoints());
iStrength /= (7 * maxHitPoints() + currHitPoints());
if (iStrength < 1)
return 0;
int iCube = iStrength;
if (iCube > MAX_INT/10000)
{
FAssert(MAX_INT/40000 > 200);
iCube = MAX_INT/10000;
}
int iGuess = 0;
int iNewGuess = 200;
//cube root
int iPass = 0;
while ((iNewGuess != iGuess) && (iNewGuess != iGuess + 1))
{
iPass++;
FAssert(iPass < 20);
iGuess = iNewGuess;
iNewGuess = iCube * 10000;
iNewGuess /= iGuess;
iNewGuess /= iGuess;
iNewGuess += 2 * iGuess;
iNewGuess /= 3;
}
return (iStrength * iGuess)/100;
}
I don't know how sensible the 4/3 power is but it's definitely better than just adding up the strengths when the city defenders are likely to be individually stronger.
It's still there. The problem, as in Better AI, is that some of the old code can also cause stacks to attack cities. But it's not hard to make those check the stack comparison code as well if a few units are involved on both sides.We added some code which to check stack vs stack strengths when deciding when to attack in BetterAI, I have not looked to see what survived in BtS.
With both those, the AI was much better at taking cities. It did fail sometimes, but the survivors were damaged enough for me to believe that it might have stood a decent chance if not for the RNG gods.
It was much a better judge than I am, anyway. Is there any need to put the data-crunching-challenged player at a disadvantage?