Be me, someone whom like to play pen-and-paper RPGs, like Dungeons & Dragons or GURPS.
Also, be me, avid computer programmer.
I’ve created dice rolling programs in quite a few languages, C#, Java, and a few others.
Being a web programmer, my strongest language is PHP. I also needed to learn the workings of Symfony Console, a PHP package that let’s you run PHP applications in the console.
The rolling of the dice was pretty strait forward:
7 8 9 10 |
public static function rollOne(int $sides) { return (random_int(1, $sides)); } |
Cool, so now we can roll a variable-sided die. But how do we get it to work in the console?
We first need to set up our application in Composer, using a composer.json
file like so:
1 2 3 4 5 6 7 8 9 10 |
{ "require": { "symfony/console": "^3.3" }, "autoload": { "psr-4": { "Dice\\": "src/" } } } |
After we install everything, we can start using the Symfony application methods.
I’m going to create a file called dice. No extension, just dice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/usr/bin/env php <?php require_once __DIR__ . '/vendor/autoload.php'; use Dice\RollCommand; use Symfony\Component\Console\Application; $app = new Application(); $app->add(new RollCommand()); $app->run(); |
I’m going to have two classes, the RollCommand
and Dice
. I’ve specified in the composer.json
file that my code will be in the src
folder, so I will create the classes there.
Here’s the first version of those classes I wrote:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php namespace Dice; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class RollCommand extends Command { protected function configure() { $this->setName("Roll") ->setDescription("Rolls fair dice.") ->addArgument('Dice String', InputArgument::REQUIRED, 'e.g.: 2d6, 1d20+4') ; } protected function execute(InputInterface $input, OutputInterface $output) { $dice = new Dice(); $matches = []; preg_match('/(\d+)d(\d+)\+?(\d)?/i', $input->getArgument('Dice String'), $matches); $modifier = empty($matches[3]) ? 0 : (int)$matches[3]; $roll = $dice::roll((int)$matches[1], (int)$matches[2]); $output->writeln('Your roll without modifier was ' . array_sum($roll) . ' [' . implode('|', $roll) . '] + ' . $modifier . ' for a total of ' . (array_sum($roll) + $modifier)); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace Dice; class Dice { public static function rollOne(int $sides) { return (random_int(1, $sides)); } public static function roll(int $number, int $sides) { $rolls = []; for ($i = 0; $i < $number; $i++) { $rolls[] = self::rollOne($sides); } return $rolls; } } |
Sweet, let’s test that.
1 2 3 4 5 6 7 |
$ php dice Roll 1d6 Your roll without modifier was 1 [1] + 0 for a total of 1 $ php dice Roll 2d8+2 Your roll without modifier was 11 [3|8] + 2 for a total of 13 |
That works well! We know what the unmodified roll was, and what each die rolled. Information that is sometimes important, as with critical rolls.
The repository for this post can be found on GitHub here .
The repository for this post can be found on GitLab here .
The repository for this post can be found on Lupe Code’s GitLab mirror here .