3v4l.org

run code in 300+ PHP versions simultaneously
<?php function parseRollCode($rollCode) { $cleanRollCode = preg_replace('/\s+/', '', strtolower($rollCode)); $intro = "<strong>Dice Roll:</strong> {$cleanRollCode}"; $error = "Invalid Roll Code"; $result = [ 'input' => $rollCode, 'total' => 0, 'detailText' => $intro ]; /* $out... [0] => roll tokens (optional leading sign) [1] => optional signs [2] => number&type die segments [3] => reroll threshold segments [4] => keep setting segments [5] => constant segments */ if (!preg_match_all('~\G(^-?|[+-])(?:(\d+d\d+)(r\d+)?([v^]\d+)?|(\d+))(?=[+-]|$)~x', $cleanRollCode, $out)) { $result['detailText'] .= "\n{$error}"; return $result; } foreach ($out[0] as $index => $segment) { $result['detailText'] .= "\n<strong>{$segment} Results:</strong>"; if (!empty($out[5][$index])) { $result['detailText'] .= ' (subtotal: ' . ((int)$segment) . ')'; $result['total'] += $segment; } else { // dice count & die type [$diceCount, $dieType] = explode('d', $out[2][$index], 2); // positive or negative arithmetic $signFactor = (!empty($out[1][$index][0]) && $out[1][$index][0] == '-' ? -1 : 1); // reroll threshold $rerollThreshold = (int)ltrim($out[3][$index] ?? 0, 'r'); if ($rerollThreshold >= $dieType) { return ['input' => $rollCode, 'total' => 0, 'detailText' => "{$intro}\n{$error}"]; } $rollResults = []; for ($r = 0; $r < $diceCount; ++$r) { $rollResults[] = rand($rerollThreshold + 1, $dieType); } // keep settings if (!empty($out[4][$index])) { $keepCount = ltrim($out[4][$index], '^v'); if ($keepCount > $diceCount) { return ['input' => $rollCode, 'total' => 0, 'detailText' => "{$intro}\n{$error}"]; } if ($out[4][$index][0] == '^') { arsort($rollResults); } else { asort($rollResults); } $keep = array_slice($rollResults, 0, $keepCount, true); $subtotal = array_sum($keep) * $signFactor; for ($i = 0, $len = count($rollResults); $i < $len; ++$i) { $result['detailText'] .= ' ' . ($keep[$i] ?? "<s>{$rollResults[$i]}</s>"); } $result['detailText'] .= " (subtotal: {$subtotal})"; $result['total'] += $subtotal; } else { $subtotal = array_sum($rollResults) * $signFactor; $result['detailText'] .= " " . implode(" ", $rollResults) . " (subtotal: {$subtotal})"; $result['total'] += $subtotal; } } } return $result; } $rolls = ["1 d2 0", "-1d20+5", "d20", "2d20^1", "4d6r1^3", "5d20^3", "5d8v2", "2d20v1", "5+3d4", "3d20^1", "3d6r1 + 1d4r2", "-1d20", "1d20+5", "1d20 + 5", "1d-20", "1d20+1d6", "5d20-3d6", "1d6r2", "5d6r-6", "3d20^1v1", "1d20r30", "1d20r20", "1d20r19", "1d20v2", "1d20v1", "1d20^2", "1d20+5d8r2^3-5-1d6+3d4+2-4+6-8"]; foreach ($rolls as $roll) { $rollResult = parseRollCode($roll); echo "{$rollResult['detailText']}\n<strong>Total:</strong> {$rollResult['total']}\n---\n"; }

preferences:
24.68 ms | 415 KiB | 5 Q