use 5.010; use strict; use warnings; use Readonly; use Games::Dice::Advanced; use IO::Prompt::Hooked; Readonly my $RE_GOOD_ROLL => qr{ ^\s* # Start of line, ignore whitespace (?&POS_INT)? # How many rolls (optional). \s* d \s* # 'd' (forgiving of whitespace) (?&POS_INT) # Die to roll. \s*$ # End of input, ignore whitespace. (?(DEFINE) (? [1-9][0-9]{0,2}? ) ) # Definition of positive int. }x; Readonly my $DEFAULT_ROLL => '1d6'; my $roll; while (defined(my $input = ask($roll // $DEFAULT_ROLL))) { $roll = interpret_input($input); my $result = Games::Dice::Advanced->roll($roll); print "Result of ( $roll ) is [ $result ].\n\n"; } sub interpret_input { my $i = shift; $i =~ s/\s+//g; $i =~ s/^d/1d/; return $i; } sub ask { my $default = shift; return prompt( default => $default, message => 'Enter a dice roll ("q" to quit): ', validate => $RE_GOOD_ROLL, error => "Input must be in format of d8, or 2d6.\n\n", escape => qr/^ \s* q (?: uit )? /ix, # q or quit, case insensitively. ); }