(attack_val, defense_val): These functions overestimate unit strength,

because they ignore three facts.  Firstly, mil casualties decrease
strength linearly, while unit casualties decrease it quadratically
(unit strength scales with mil * eff).  Secondly, casualties decrease
strength proportional to the combat multiplier, hence twice as much
mil are more powerful than double multiplier.  Thirdly, units break
and retreat.  Change the estimate from mil * mult to mil * sqrt(mult).
Improves things in simulations, hope it works out in practice as well.
Closes #682571.
This commit is contained in:
Markus Armbruster 2006-06-15 19:05:17 +00:00
parent ded3ca41ef
commit 2ecc85b541

View file

@ -60,7 +60,7 @@ double
attack_val(int combat_mode, struct lndstr *lp) attack_val(int combat_mode, struct lndstr *lp)
{ {
int men; int men;
double value; double mult;
struct lchrstr *lcp; struct lchrstr *lcp;
if (lp->lnd_effic < LAND_MINEFF) { if (lp->lnd_effic < LAND_MINEFF) {
@ -77,28 +77,28 @@ attack_val(int combat_mode, struct lndstr *lp)
return 1; return 1;
men = lp->lnd_item[I_MILIT]; men = lp->lnd_item[I_MILIT];
value = men * lp->lnd_att * lp->lnd_effic / 100.0; mult = lp->lnd_att * lp->lnd_effic / 100.0;
switch (combat_mode) { switch (combat_mode) {
case A_ATTACK: case A_ATTACK:
return value; break;
case A_ASSAULT: case A_ASSAULT:
if (!(lcp->l_flags & L_MARINE)) if (!(lcp->l_flags & L_MARINE))
return assault_penalty * value; mult *= assault_penalty;
break; break;
case A_BOARD: case A_BOARD:
if (!(lcp->l_flags & L_MARINE)) if (!(lcp->l_flags & L_MARINE))
return assault_penalty * men; mult = assault_penalty;
} }
return value; return men * sqrt(mult);
} }
double double
defense_val(struct lndstr *lp) defense_val(struct lndstr *lp)
{ {
int men; int men;
double value; double mult;
struct lchrstr *lcp; struct lchrstr *lcp;
if (lp->lnd_effic < LAND_MINEFF) { if (lp->lnd_effic < LAND_MINEFF) {
@ -114,15 +114,15 @@ defense_val(struct lndstr *lp)
!(lcp->l_flags & L_MARINE)) !(lcp->l_flags & L_MARINE))
return men; return men;
value = men * lp->lnd_def * lp->lnd_effic / 100.0; mult = lp->lnd_def * lp->lnd_effic / 100.0;
value *= ((double)land_mob_max + lp->lnd_harden) / land_mob_max; mult *= ((double)land_mob_max + lp->lnd_harden) / land_mob_max;
/* If there are military on the unit, you get at least a 1 /* If there are military on the unit, you get at least a 1
man defensive unit, except for spies */ man defensive unit, except for spies */
if (value < 1.0 && men > 0 && !(lcp->l_flags & L_SPY)) if (men > 0 && !(lcp->l_flags & L_SPY))
return 1; return MAX(1, men * sqrt(mult));
return value; return men * sqrt(mult);
} }
void void