($i < 10 ? 1 : 0), 'hit' => 6); // stronghold, card play $extras[] = array(0, 0); // start with a sample game switch ($i) { case 0: $hunts[$i] = array('num' => 2, 'hit' => 6); break; case 1: $hunts[$i] = array('num' => 2, 'hit' => 5); break; case 2: $hunts[$i] = array('num' => 2, 'hit' => 6); break; case 3: $hunts[$i] = array('num' => 2, 'hit' => 5); break; case 4: $hunts[$i] = array('num' => 2, 'hit' => 6); break; case 5: $hunts[$i] = array('num' => 2, 'hit' => 5); break; case 6: $hunts[$i] = array('num' => 2, 'hit' => 6); break; case 7: $hunts[$i] = array('num' => 2, 'hit' => 5); break; case 8: $hunts[$i] = array('num' => 2, 'hit' => 6); break; case 9: $hunts[$i] = array('num' => 2, 'hit' => 5); break; case 10: $hunts[$i] = array('num' => 2, 'hit' => 4); break; default: break; } if (array_key_exists('num'.$i, $_POST) && is_numeric($_POST['num'.$i])) { // must be at least 0 and no more than 5 $hunts[$i]['num'] = min(max(0, $_POST['num'.$i]), 5); } if (array_key_exists('hit'.$i, $_POST) && is_numeric($_POST['hit'.$i])) { // to hit value must be at least 2 and no more than 6 $hunts[$i]['hit'] = min(max(2, $_POST['hit'.$i]), 6); } if (array_key_exists('strong'.$i, $_POST) && is_numeric($_POST['strong'.$i])) { $extras[$i][0] = min(max(0, $_POST['strong'.$i]), 1); } if (array_key_exists('card'.$i, $_POST) && is_numeric($_POST['card'.$i])) { $extras[$i][1] = min(max(0, $_POST['card'.$i]), 1); } $total_dice += $hunts[$i]['num']; if ($hunts[$i]['num'] > 0) { $maxActualHunts++; } } $totalHitResults = array_pad([], $total_dice+1, 0); $oneHitResults = array_pad([], $maxActualHunts+1, 0); function ValidateGlobal ($name, $default, $minValue, $maxValue) { global $$name; $$name = $default; if (array_key_exists($name, $_POST) && is_numeric($_POST[$name])) { $$name = max($minValue, $_POST[$name]); $$name = min($maxValue, $$name); } } function RefillPool (array &$pool) { // corruption, reveal, stop, undo reveal if gollum is guide, gollum ability target // 4 eyes $pool[] = array(-100, 1, 0, 0, 0); $pool[] = array(-100, 1, 0, 0, 0); $pool[] = array(-100, 1, 0, 0, 0); $pool[] = array(-100, 1, 0, 0, 0); // 3 3 $pool[] = array(3, 0, 0, 0, 1); $pool[] = array(3, 0, 0, 0, 1); $pool[] = array(3, 0, 0, 0, 1); // 1 2r $pool[] = array(2, 1, 0, 1, 1); // 2 2 $pool[] = array(2, 0, 0, 0, 1); $pool[] = array(2, 0, 0, 0, 1); // 2 1r $pool[] = array(1, 1, 0, 1, 1); $pool[] = array(1, 1, 0, 1, 1); // 2 1 $pool[] = array(1, 0, 0, 0, 1); $pool[] = array(1, 0, 0, 0, 1); // 2 0r $pool[] = array(0, 1, 0, 1, 1); $pool[] = array(0, 1, 0, 1, 1); } function DrawTile (array &$pool) { if (count($pool) == 0) { RefillPool($pool); } $tile = array_splice ($pool, mt_rand(0, count($pool)-1), 1); return $tile[0]; } function CalculateHits($dice, $toHit) { $hits = 0; // for each die for ($i = 0; $i < $dice; $i++) { // roll a d6 and see if we hit if (mt_rand(1,6) >= $toHit) { $hits++; } } return $hits; } function ArrayAverage($a, $digits) { $totalValue = 0; $totalGames = 0; foreach ($a as $key => $value) { $totalGames += $value; $totalValue += $key*$value; } return round($totalValue/$totalGames, $digits); } function ArraySum2D (array $a) { $sum = 0; $maxD = count(array_keys($a[0])); for ($d = 0; $d < $maxD; $d++) { for ($i = 0; $i < count($a); $i++) { $sum += $a[$i][$d]; } } return $sum; } function ArrayTrim (array &$a) { $posIndex = count($a); while ($a[--$posIndex] == 0) {} $a = array_slice($a, 0, $posIndex+1); } function PrintGames (array $results) { global $games; $tempSum = 0; for ($i = 0; $i < count($results); $i++) { echo " \n"; echo " ".$i."\n"; echo " ".round($results[$i]/$games*100, 1)."%\n"; $tempSum += $results[$i]; echo " ".round($tempSum/$games*100, 0)."%\n"; echo " \n"; } } $pool = array(); RefillPool($pool); $totalHitsSum = 0; $totalSuccessfulHuntsSum = 0; $reveals = array_pad(array(), 30, 0); $corruption = array_pad(array(), 100, 0); mt_srand((float)microtime()*1000000); for ($g = 0; $g < $games; $g++) { $atLeastOneHit = 0; $totalHits = 0; $myPool = $pool; $myCorruption = 0; $myReveal = 0; // for each hunt for ($i = 0; $i < $MAX_HUNTS; $i++) { $hits = CalculateHits($hunts[$i]['num'], $hunts[$i]['hit']); $totalHits += $hits; if ($hits > 0) { $atLeastOneHit++; $myTile = DrawTile($myPool); $myReveal += $myTile[1]; // special corruption code for an Eye tile if ($myTile[0] == -100) { $myCorruption += $hits; } else { $myCorruption += $myTile[0]; } } // stronghold tile, ignore eyes and reveals if ($extras[$i][0]) { $myTile = DrawTile($myPool); if ($myTile[0] == -100) { // no corruption } else { $myCorruption += $myTile[0]; } } // card draw tile, ignore eyes if ($extras[$i][1]) { $myTile = DrawTile($myPool); $myReveal += $myTile[1]; if ($myTile[0] == -100) { // no corruption } else { $myCorruption += $myTile[0]; } } } // track the results. the second array tracks total hits vs. at least one hit $totalHitResults[$totalHits]++; $oneHitResults[$atLeastOneHit]++; $corruption[$myCorruption]++; $reveals[$myReveal]++; $totalHitsSum += $totalHits; $totalSuccessfulHuntsSum += $atLeastOneHit; } // for each game ArrayTrim($totalHitResults); ArrayTrim($oneHitResults); ArrayTrim($corruption); ArrayTrim($reveals); $averageHunts = round($totalSuccessfulHuntsSum / $games, 1); $extraTiles = ArraySum2D($extras); ?> A WotR Hunt Roll Simulation

A WotR Hunt Simulation with trials

Average results:
  • successful hunts rolled (with NAN total hits and 0 total tiles drawn)