= \$toHit) { \$hits++; } } return \$hits; } function calculateDamageDone(\$army, \$toHit) { \$combatStrength = min(5, \$army[0] + \$army[1]); \$hits = calculateHits(\$combatStrength, \$toHit); \$leaderReroll = min(\$army[2], \$combatStrength - \$hits); \$hits += calculateHits(\$leaderReroll, \$toHit); return \$hits; } function takeDamage(\$army, \$damage, \$defender, \$presses) { global \$pressesAvailableToReduceElite; // while we have damage to process and units left in army while (\$damage > 0 && \$army[0] + \$army[1] > 0) { // if we have more than 5 units, lose a regular if (\$army[0] + \$army[1] > 5) { // confirm we have a regular to lose if (\$army[0] > 0) { \$army[0]--; } // reduce an elite because no regulars to lose else { \$army[1]--; \$army[0]++; } } // if it's the defender, always reduce elites if possible elseif (\$defender) { if (\$army[1] > 0) { \$army[1]--; \$army[0]++; } // must kill a regular because no elites left else { \$army[0]--; } } // we need to lose a regular below 5 or reduce an elite else { // if we have enough presses, it's OK to reduce an elite if (\$army[1] + \$presses >= \$pressesAvailableToReduceElite) { // reduce an elite if (\$army[1] > 0) { \$army[1]--; \$army[0]++; } // must kill a regular because no elites left else { \$army[0]--; } } // we don't have enough presses, so lose a regular if possible else { // confirm we have a regular to lose if (\$army[0] > 0) { \$army[0]--; } // reduce an elite because no regulars to lose else { \$army[1]--; \$army[0]++; } } } // take the damage \$damage--; } return \$army; } function printGames (\$start, \$results) { global \$tempSum; // rough error checking if (\$start < 0 || \$start > count(\$results)) { return; } echo " \n"; echo " ".(\$start)."\n"; echo " ".\$results[\$start]."\n"; \$tempSum += \$results[\$start]; echo " ".\$tempSum."\n"; echo " \n"; } \$aMaxHP = \$aArmy[0]+ 2*\$aArmy[1]; \$dMaxHP = \$dArmy[0]+ 2*\$dArmy[1]; \$aResults = array(); \$dResults = array(); \$rResults = array(); \$aVictory = array(); \$dVictory = array(); \$draw = array(); // do each choice of onslaught for (\$onslaught = 0; \$onslaught <= min(4, \$aArmy[0] + 2*\$aArmy[1]); \$onslaught++) { \$aResults[\$onslaught] = array_fill(0, \$aMaxHP + 1, 0); \$dResults[\$onslaught] = array_fill(0, \$dMaxHP + 1, 0); \$rResults[\$onslaught] = array_fill(0, \$freePresses + \$aArmy[1] + 1, 0); \$aVictory[\$onslaught] = 0; \$dVictory[\$onslaught] = 0; \$draw[\$onslaught] = 0; for (\$g = 0; \$g < \$GAMES; \$g++) { // process the battle \$aCurrent = \$aArmy; \$dCurrent = \$dArmy; \$pressesCurrent = \$freePresses; \$press = false; \$rounds = 0; // do onslaught stuff here \$aCurrent = takeDamage(\$aCurrent, \$onslaught, false, \$pressesCurrent); \$dCurrent = takeDamage(\$dCurrent, calculateHits(\$onslaught, 4), true, \$pressesCurrent); // can we press to next round? if (\$pressesCurrent > 0) { \$pressesCurrent--; \$press = true; } elseif (\$aCurrent[1] > 0) { // reduce an elite \$aCurrent[1]--; \$aCurrent[0]++; \$press = true; } // while we have armies left while (\$dCurrent[0] + \$dCurrent[1] > 0 && \$aCurrent[0] + \$aCurrent[1] > 0 && \$press) { \$rounds++; if (\$debug && \$g < 1) { echo "Round ".\$rounds."
"; echo "a=".\$aCurrent[0]."/".\$aCurrent[1]."/".\$aCurrent[2].". "; echo "d=".\$dCurrent[0]."/".\$dCurrent[1]."/".\$dCurrent[2]."
"; } // hack for round 2 deadly strife if (\$rounds == 2) { \$dDamageTaken = calculateDamageDone(\$aCurrent, 4); \$aDamageTaken = calculateDamageDone(\$dCurrent, 3); } else { \$dDamageTaken = calculateDamageDone(\$aCurrent, 6); \$aDamageTaken = calculateDamageDone(\$dCurrent, 5); } if (\$debug && \$g < 1) { echo "dDamageTaken= ".\$dDamageTaken.". aDamTaken= ".\$aDamageTaken."
"; } \$aCurrent = takeDamage(\$aCurrent, \$aDamageTaken, false, \$pressesCurrent); \$dCurrent = takeDamage(\$dCurrent, \$dDamageTaken, true, \$pressesCurrent); if (\$debug && \$g < 1) { echo "a=".\$aCurrent[0]."/".\$aCurrent[1]."/".\$aCurrent[2].". "; echo "d=".\$dCurrent[0]."/".\$dCurrent[1]."/".\$dCurrent[2]."
"; } // Do we need to press to the next round? if (\$dCurrent[0] + \$dCurrent[1] > 0) { // can we press to next round? if (\$pressesCurrent > 0) { \$pressesCurrent--; } elseif (\$aCurrent[1] > 0) { // reduce an elite \$aCurrent[1]--; \$aCurrent[0]++; } // can't press any more else { \$press = false; } } } // track the results. \$aHP = \$aCurrent[0] + 2*\$aCurrent[1]; \$dHP = \$dCurrent[0] + 2*\$dCurrent[1]; if (\$debug && \$g < 1) { echo "ons=".\$onslaught.". aHP=".\$aHP."
"; } \$aResults[\$onslaught][\$aHP]++; \$dResults[\$onslaught][\$dHP]++; \$rResults[\$onslaught][\$rounds]++; if (\$aHP > 0 && \$dHP == 0) { \$aVictory[\$onslaught]++; } elseif (\$dHP > 0) { \$dVictory[\$onslaught]++; } elseif (\$aHP == 0 && \$dHP == 0) { \$draw[\$onslaught]++; \$dVictory[\$onslaught]++; } else { echo "LOGIC ERROR
"; } } // for each game } // for each onslaught choice ?>

# A WotR Onslaught Battle Simulation with trials

Onslaught
The attackers won times. The defenders kept the stronghold times,
including mutual destructions. The battles took an average of rounds.
"; } for (\$b = 0; \$b <= \$aMaxHP; \$b++) { printGames(\$b, \$aResults[\$o]); } ?>
Attacker HP
Remaining
Frequency Sum
Defender HP
Remaining
Frequency Sum

 Reg Elite Leader Attacker: Defender: Free Presses: Presses left beforereducing an Elite: Trials:

You have just finished a round of combat, and need to decide how many units to spend on onslaught. This simulation helps with that decision. The forces listed are what you have before spending for onslaught.

Free Presses shows how many presses you have left (from Grond or additional attack dice). For example, if you have 0 free presses and 0 elites, the battle will end immediately after onslaught.

Press left before reducing an Elite controls how you take casualties. For example, if you have 2 regulars and 3 elites and need to take a casualty, should you reduce an elite or lose a regular? If you lose a regular, you're only rolling 4 dice, but you could potentially have an extra press.

Say you have 2 free presses and 2 elites in your army, so you have 4 presses left. If "Presses left before reducing an elite" is set to 4 or lower, you'll reduce an elite when you need to take a casualty (and then you'll have only 3 presses left). If the value is set to 5 or higher, you'll lose a regular (reducing your combat strength below 5).

Of course, if you have more than 5 combat strength, the simulation will always take regulars as casualties first. When continuing battles, free presses are always used before reducing elites to press.