Chainmail Post Melee Morale
Implements Post Melee Morale algorithm on page 15 of Chainmail by Gygax & Perren.
by krusader74
HTML
<form onsubmit="return compute();">
<fieldset>
<legend>Chainmail Post Melee Morale</legend>
<table>
<tr>
<td></td>
<td>Side A</td>
<td>Side B</td>
</tr>
<tr>
<td>Troop type</td>
<td>
<select id="TypeA" required>
<option value="3">Peasants</option>
<option value="4">Light Foot and Levies</option>
<option value="5">Heavy Foot</option>
<option value="6">Elite Heavy Foot</option>
<option value="6">Light Horse</option>
<option value="7">Armored Foot, Janissaries</option>
<option value="8">Medium Horse, Landsknechte</option>
<option value="9">Heavy Horse, Swiss Pikemen</option>
</select>
</td>
<td>
<select id="TypeB" required>
<option value="3">Peasants</option>
<option value="4">Light Foot and Levies</option>
<option value="5">Heavy Foot</option>
<option value="6">Elite Heavy Foot</option>
<option value="6">Light Horse</option>
<option value="7">Armored Foot, Janissaries</option>
<option value="8">Medium Horse, Landsknechte</option>
<option value="9">Heavy Horse, Swiss Pikemen</option>
</select>
</td>
</tr>
<tr>
<td>Number of troops before melee</td>
<td><input id="Num1A" type="number" min=1 required></td>
<td><input id="Num1B" type="number" min=1 required></td>
</tr>
<tr>
<td>Number of troops after melee</td>
<td><input id="Num2A" type="number" min=0 required></td>
<td><input id="Num2B" type="number" min=0 required></td>
</tr>
<tr><td></td><td></td><td>
<input id="submit" type="submit" value="Compute Post Melee Morale">
</td></tr>
</table>
</fieldset>
<fieldset>
<legend>Results</legend>
<table>
<tr>
<td></td>
<td></td>
<td>Side A</td>
<td>Side B</td>
</tr>
<tr>
<td>1.</td>
<td>Greater kills</td>
<td><div id="KillsA"></div></td>
<td><div id="KillsB"></div></td>
</tr>
<tr>
<td></td>
<td>Difference</td>
<td><div...
CSS
html{
font:1em/1.5 Georgia, serif;
padding:5%;
background-color:#fff;
color:#333;
}
JavaScript
function d6 () {
return Math.floor((Math.random()*6)+1);
}
function clear () {
document.getElementById("KillsA").textContent = "";
document.getElementById("Diff1A").textContent = "";
document.getElementById("d6A").textContent = "";
document.getElementById("Subtotal1A").textContent = "";
document.getElementById("KillsB").textContent = "";
document.getElementById("Diff1B").textContent = "";
document.getElementById("d6B").textContent = "";
document.getElementById("Subtotal1B").textContent = "";
document.getElementById("SurvivorsA").textContent = "";
document.getElementById("SurvivorsB").textContent = "";
document.getElementById("Subtotal2A").textContent = "";
document.getElementById("Subtotal2B").textContent = "";
document.getElementById("MoraleRatingA").textContent = "";
document.getElementById("MoraleRatingB").textContent = "";
document.getElementById("Subtotal3A").textContent = "";
document.getElementById("Subtotal3B").textContent = "";
document.getElementById("TotalsA").textContent = "";
document.getElementById("TotalsB").textContent = "";
document.getElementById("Totals").textContent = "Totals";
document.getElementById("DifferenceA").textContent = "";
document.getElementById("DifferenceB").textContent = "";
document.getElementById("ReactionA").textContent = "";
document.getElementById("ReactionB").textContent = "";
}
function reaction (difference) {
if ( difference < 0 ) { return "error"; }
if ( difference >= 0 && difference <= 19 ) { return "melee continues"; }
if ( difference >= 20 && difference <= 39 ) { return "back 1/2 move, good order"; }
if ( difference >= 40 && difference <= 59 ) { return "back 1 move, good order"; }
if ( difference >= 60 && difference <= 79 ) { return "retreat 1 move"; }
if ( difference >= 80 && difference <= 99 ) { return "rout 1 1/2 move"; }
if ( difference >= 100 ) { return "surrender"; }
}
function compute () {
var MoraleRatingA=parseInt(document.getElementById("TypeA").value, 10);
var...