Risk Auto Roller — Source Code
Back to Auto Roller
<?php
// the maximum number of dice that can be used by each side
define("ATTACKER_MAX_DICE", 3);
define("DEFENDER_MAX_DICE", 2);
// number of troops allowed on each side in a battle. To protect server.
define("TROOP_LIMIT", 200);
// values of inputs to save for HTML page
$attackerSave = "";
$defenderSave = "";
$attackerStopSave = "";
$aboveCount = NULL;
$belowCount = NULL;
// set up attacker stop strategy
$stopMethod = "none";
$stopOptions = array("fixed" => false, "less" => false, "more" => false,
"equal" => false, "none" => false);
// assume everything is OK
$valid = true;
// only show results if form has been submitted
if ($_SERVER['REQUEST_METHOD'] == "POST")
{
// make sure our input is good
if (isset($_POST['attackers'], $_POST['defenders']) && (int)$_POST['attackers'] > 1 && (int)$_POST['defenders'] > 0)
{
$attackers = $attackerSave = (int)$_POST['attackers'];
$defenders = $defenderSave = (int)$_POST['defenders'];
// check our stopping strategy. If it's not set, default to
// 'bitter end.'
if (isset($_POST['stopMethod']) && array_key_exists($_POST['stopMethod'], $stopOptions))
{
$stopMethod = $_POST['stopMethod'];
// get fixed number of troops for attacker to stop at. Make sure it's in legal range
if ($stopMethod == "fixed" && isset($_POST['attackerStop']) && trim($_POST['attackerStop']) != "" && is_numeric($_POST['attackerStop']) && (int)$_POST['attackerStop'] < $attackers)
{
$attackerStop = (int)$_POST['attackerStop'];
$attackerStopSave = $attackerStop;
}
// get variable number of troops above defender count
else if ($stopMethod == "more" && isset($_POST['aboveCount']) && trim($_POST['aboveCount']) != "" && (int)$_POST['aboveCount'] >= 0 && $attackers - $defenders > (int)$_POST['aboveCount'])
{
$aboveCount = (int)$_POST['aboveCount'];
}
// get variable number of troops below defender count
else if ($stopMethod == "less" && isset($_POST['belowCount']) && trim($_POST['belowCount']) != "" && (int)$_POST['belowCount'] >= 0 && $defenders - $attackers < (int)$_POST['belowCount'])
{
$belowCount = (int)$_POST['belowCount'];
}
// stop case for when the troop counts are equal. Sneakily, we
// just pick the 'above' method, with an input of zero.
else if ($stopMethod == "equal" && $attackers != $defenders)
{
$aboveCount = 0;
}
// now, if there was something wrong and all the conditions weren't right
// for the given stop method, decide the correct error message
else if ($stopMethod != "none")
{
$valid = false;
switch ($stopMethod)
{
case "fixed":
$error = "The number of troops the attacker stops at must be less than the number he attacks with.";
break;
case "more":
$error = "Attacker already have fewer than " . $_POST['aboveCount'] . " troops more than the defender.";
break;
case "less":
$error = "Attacker already have more than " . $_POST['belowCount'] . " troops less than the defender.";
break;
case "equal":
$error = "The number of troops is already equal.";
break;
}
} // end if input for stop strategy wasn't correct
// if the stop strategy is none at all
if ($valid && $stopMethod == "none")
{
$stopMethod = "none";
$valid = true;
}
} // end if stop strategy is defined
// set the attacker stopping value into a legal range
$attackerStop = max(1, $attackerStop);
$attackerStop = min($attackers - 1, $attackerStop);
// set up array to track each roll and troop totals
$rollTrack = array();
// set up total track array
$totalTrack [] = array('attackers' => $attackers, 'defenders' => $defenders);
// check for huge inputs
if ($attackers > TROOP_LIMIT || $defenders > TROOP_LIMIT)
{
$error = "Sorry, I only allow up to " . TROOP_LIMIT . " troops on this page to reduce server load. Although a battle of 1,000,000 soldiers would be cool, it would hit the server pretty hard.";
$valid = false;
}
$roll = 0;
// now, loop until we hit a stop condition
while ($valid && $attackers > $attackerStop && $defenders > 0)
{
$roll++;
// dynamically update above or below defender counts, for the
// attacker stop condition
if (!is_null($aboveCount))
{
$attackerStop = $defenders + $aboveCount;
if ($attackers < $attackerStop)
{
break;
}
}
else if (!is_null($belowCount))
{
$attackerStop = $defenders - $belowCount;
if ($attackers < $attackerStop)
{
break;
}
}
// figure out how many dice each combatant gets this round
$dice['attackers'] = min(ATTACKER_MAX_DICE, $attackers - 1, $attackers - $attackerStop);
$dice['defenders'] = min(DEFENDER_MAX_DICE, $defenders);
// if attacker has zero dice, then the battle is over
if ($dice['attackers'] < 1)
break;
// array for each combatant's rolls
$rolls = array();
// shake those dice
for ($i = 0; $i < $dice['attackers']; $i++)
$rolls['attackers'][] = rand(1, 6);
for ($i = 0; $i < $dice['defenders']; $i++)
$rolls['defenders'][] = rand(1, 6);
// sort in reverse, for comparing
rsort($rolls['attackers']);
rsort($rolls['defenders']);
// we only compare the same number of dice. Since the arrays of roll are
// sorted, this is OK.
for ($i = 0; $i < min($dice['attackers'], $dice['defenders']); $i++)
{
if ($rolls['attackers'][$i] <= $rolls['defenders'][$i])
$attackers--;
else
$defenders--;
}
// save tracking data
$totalTrack [] = array('attackers' => $attackers, 'defenders' => $defenders);
$rollTrack [] = $rolls;
} // end main battle loop
// figure out WHY we stopped
if (!isset($stopBecause))
{
if ($defenders <= 0)
$stopBecause = "Defender was annihilated.";
else if ($stopMethod == "more")
$stopBecause = "Attacker troop count reached limit above defender count.";
else if ($stopMethod == "less")
$stopBecause = "Attacker troop count reached limit below defender count.";
else if ($stopMethod == "equal" && $attackers == $defenders)
$stopBecause = "Attacker count equals defender count.";
else if ($stopMethod == "fixed" && $attackerStop != 1)
$stopBecause = "Attacker count reached fixed limit.";
else
$stopBecause = "Attacker cannot continue battle because only one troop remains.";
} // end block of code to figure out reason for stopping
}
else // Troop counts were bad or too low
{
$error = "Bad numbers assigned to attacking and defending troops. Attackers must have at least two troops, and defenders must have at least one.";
$valid = false;
}
} // end if form was submitted
?>
<h2>Risk Auto Roller</h2>
<?php if ($valid && isset($totalTrack, $rollTrack)): ?>
<h3>Results</h3>
<p>
<strong>Attackers: </strong><?php echo $attackers ?><br />
<strong>Defenders: </strong><?php echo $defenders ?>
</p>
<h3>Rolls</h3>
<table class="rolls">
<tr>
<th style="width: 8%;">Roll</th>
<th style="width: 8%;">Attackers</th>
<th style="width: 8%;">Defenders</th>
<th style="width: 38%;">Attacker Rolls</th>
<th style="width: 38%;">Defender Rolls</th>
</tr>
<?php for ($i = 0; $i < count($totalTrack); $i++): ?>
<tr<?php if ($i >= count($rollTrack)): ?> style="height: 36px;"<?php endif; ?>>
<td><?php echo ($i < count($rollTrack) ? $i + 1 : '-') ?></td>
<td>
<?php echo $totalTrack[$i]['attackers'] ?>
<?php if ($i > 0 && $totalTrack[$i-1]['attackers'] > $totalTrack[$i]['attackers']): ?><span class="change">(-<?= $totalTrack[$i-1]['attackers'] - $totalTrack[$i]['attackers'] ?>)</span><?php endif; ?>
</td>
<td>
<?php echo $totalTrack[$i]['defenders'] ?>
<?php if ($i > 0 && $totalTrack[$i-1]['defenders'] > $totalTrack[$i]['defenders']): ?><span class="change">(-<?= $totalTrack[$i-1]['defenders'] - $totalTrack[$i]['defenders'] ?>)</span><?php endif; ?>
</td>
<?php if ($i < count($rollTrack)): ?>
<td>
<?php for ($j = 0; $i < count($rollTrack) && $j < count($rollTrack[$i]['attackers']); $j++): ?><img src="img/attacker-dice-<?php echo $rollTrack[$i]['attackers'][$j] ?>.png" alt="<?php echo $rollTrack[$i]['attackers'][$j] ?><?php echo ($j + 1 < count($rollTrack[$j]['attackers']) ? ', ' : '') ?>" />
<?php endfor; ?>
</td>
<td>
<?php for ($j = 0; $i < count($rollTrack) && $j < count($rollTrack[$i]['defenders']); $j++): ?><img src="img/defender-dice-<?php echo $rollTrack[$i]['defenders'][$j] ?>.png" alt="<?php echo $rollTrack[$i]['defenders'][$j] ?><?php echo ($j + 1 < count($rollTrack[$j]['defenders']) ? ', ' : '') ?>" />
<?php endfor; ?>
</td>
<?php else: ?>
<td colspan="2" class="reason">
<strong>Battle ended: </strong><?php echo $stopBecause ?>
</td>
<?php endif; ?>
</tr>
<?php endfor; ?>
</table>
<h3>Roll Again</h3>
<?php elseif (!$valid): ?>
<h3>Invalid Input</h3>
<?php if (isset($error)): ?>
<p><?php echo $error ?></p>
<?php endif; ?>
<p>Please double-check your input.</p>
<h3>Roll Again</h3>
<?php else: ?>
<h3>Roll</h3>
<?php endif; ?>
<form action="riskRoller.php" method="post" class="roll">
<fieldset>
<legend>Troops</legend>
<div class="item">
<label for="attackers">Attackers:</label>
<input name="attackers" id="attackers" value="<?php echo $attackerSave ?>" class="short" />
</div>
<div class="item">
<label for="defenders">Defenders:</label>
<input name="defenders" id="defenders" value="<?php echo $defenderSave ?>" class="short" />
</div>
</fieldset>
<fieldset>
<legend>Attacker Stops</legend>
<div class="option">
<input type="radio" class="radio" name="stopMethod" value="none" id="stopNone" <?php if ($stopMethod == "none"): ?>checked="checked"<?php endif; ?>/>
<label for="stopNone"><strong>Bitter End: </strong>Stop when I cannot continue attacking</label>
</div>
<div class="option">
<label for="attackerStop">
<input type="radio" class="radio" name="stopMethod" value="fixed" id="stopFixed" <?php if ($stopMethod == "fixed"): ?>checked="checked"<?php endif; ?> />
</label>
<label for="stopFixed">
<strong>Fixed Number: </strong>Stop when I have </label>
<input name="attackerStop" id="attackerStop" value="<?php echo $attackerStopSave ?>" class="short" />
<label for="stopFixed">units left</label>
</div>
<div class="option">
<label for="aboveCount">
<input type="radio" class="radio" name="stopMethod" value="more" id="stopMore" <?php if ($stopMethod == "more"): ?>checked="checked"<?php endif; ?> />
</label>
<label for="stopMore"><strong>More Than Defender: </strong>Stop if I have exactly </label>
<input name="aboveCount" id="aboveCount" <?php if (!is_null($aboveCount)): ?>value="<?php echo $aboveCount ?>"<?php endif; ?> class="short" />
<label for="stopMore">more units than the defender</label>
</div>
<div class="option">
<input type="radio" class="radio" name="stopMethod" value="equal" id="stopEqual" <?php if ($stopMethod == "equal"): ?>checked="checked"<?php endif; ?> />
<label for="stopEqual"><strong>Equal to Defender: </strong>
Stop when I have the same number of units as the defender</label>
</div>
<div class="option">
<label for="belowCount">
<input type="radio" class="radio" name="stopMethod" value="less" id="stopLess" <?php if ($stopMethod == "less"): ?>checked="checked"<?php endif; ?> />
</label>
<label for="stopLess">
<strong>Less Than Defender: </strong>Stop if I have exactly</label>
<input name="belowCount" id="belowCount" <?php if (!is_null($belowCount)): ?>value="<?php echo $belowCount ?>"<?php endif; ?> class="short" />
<label for="stopLess">fewer units than the defender</label>
</div>
</fieldset>
<fieldset class="buttons">
<button type="submit">Run Battle</button>
</fieldset>
</form>