line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
48716
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
42
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Games::Die; |
5
|
|
|
|
|
|
|
# ABSTRACT: Program that simulates ADVANCED die rolls using a grammar. |
6
|
1
|
|
|
1
|
|
4
|
use base qw(Exporter); |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
123
|
|
7
|
|
|
|
|
|
|
our @EXPORT = qw(roll); |
8
|
1
|
|
|
1
|
|
1824
|
use Parse::RecDescent; |
|
1
|
|
|
|
|
57637
|
|
|
1
|
|
|
|
|
10
|
|
9
|
1
|
|
|
1
|
|
1357
|
use Data::Dumper; |
|
1
|
|
|
|
|
8017
|
|
|
1
|
|
|
|
|
107
|
|
10
|
1
|
|
|
1
|
|
11
|
use List::Util qw(max reduce); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
979
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
#$::RD_TRACE=30; |
13
|
|
|
|
|
|
|
#Parse::RecDescent::redirect_reporting_to(*STDOUT); |
14
|
|
|
|
|
|
|
#$::RD_HINT = '1'; |
15
|
|
|
|
|
|
|
my $g = Parse::RecDescent->new(<<'EOG'); |
16
|
|
|
|
|
|
|
main: first /\Z/ {$item[1]} |
17
|
|
|
|
|
|
|
first: multiple | more |
18
|
|
|
|
|
|
|
multiple: more /x/ num {[$item[0],$item[1],$item[3]];} |
19
|
|
|
|
|
|
|
more: { [$item[0], @{$item[1]}]; } |
20
|
|
|
|
|
|
|
double: cond '>>' cond {[$item[0],$item[1],$item[3]];} |
21
|
|
|
|
|
|
|
double: cond |
22
|
|
|
|
|
|
|
cond: sum ('=='|'>='|'<='|'<>'|'='|'<'|'>'|'!=') sum {[$item[0],$item[1],$item[2], $item[3]];} |
23
|
|
|
|
|
|
|
cond: sum |
24
|
|
|
|
|
|
|
sum: { [$item[0], @{$item[1]}]; } |
25
|
|
|
|
|
|
|
summand: dice | num |
26
|
|
|
|
|
|
|
dice: 'd' num { [$item[0],['scalar',1],['scalar',0],$item[2]]} |
27
|
|
|
|
|
|
|
dice: num 'd' '{' num '}' num {[$item[0],$item[1],$item[4],$item[6]]} |
28
|
|
|
|
|
|
|
dice: num 'd' num {[$item[0],$item[1],['scalar',0],$item[3]]} |
29
|
|
|
|
|
|
|
num: /\d+/ { ['scalar', $item[1]]; } |
30
|
|
|
|
|
|
|
num: '(' double ')' {$item[2]} |
31
|
|
|
|
|
|
|
EOG |
32
|
|
|
|
|
|
|
my %table; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub ezec { |
35
|
95
|
|
|
95
|
0
|
180
|
my ( $func, @args ) = @_; |
36
|
95
|
|
|
|
|
224
|
$table{$func}->(@args); |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
#dispatch table |
40
|
|
|
|
|
|
|
$table{sum} = sub { |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
my $v = ezec( @{ shift() } ); |
43
|
|
|
|
|
|
|
my $x = $v; |
44
|
|
|
|
|
|
|
$v =~ s/\*//g; |
45
|
|
|
|
|
|
|
while (@_) { |
46
|
|
|
|
|
|
|
my $op = shift; |
47
|
|
|
|
|
|
|
my $p = ezec( @{ shift() } ); |
48
|
|
|
|
|
|
|
$v = $v + $p if $op eq '+'; |
49
|
|
|
|
|
|
|
$v = max( $v - $p, 1 ) if $op eq '-'; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
return "$v*" if $x =~ /\*/; |
52
|
|
|
|
|
|
|
return $v; |
53
|
|
|
|
|
|
|
}; |
54
|
|
|
|
|
|
|
$table{cond} = sub { |
55
|
|
|
|
|
|
|
my $l = ezec( @{ $_[0] } ); |
56
|
|
|
|
|
|
|
my $r = ezec( @{ $_[2] } ); |
57
|
|
|
|
|
|
|
my $op = $_[1]; |
58
|
|
|
|
|
|
|
$op = '==' if $op eq '='; |
59
|
|
|
|
|
|
|
$op = '!=' if $op eq '<>'; |
60
|
|
|
|
|
|
|
if ( eval("$l$op$r") ) { |
61
|
|
|
|
|
|
|
return "$l*"; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
else { return $l; } |
64
|
|
|
|
|
|
|
}; |
65
|
|
|
|
|
|
|
$table{'scalar'} = sub { |
66
|
|
|
|
|
|
|
return shift; |
67
|
|
|
|
|
|
|
}; |
68
|
|
|
|
|
|
|
$table{'more'} = sub { |
69
|
|
|
|
|
|
|
my @rolls; |
70
|
|
|
|
|
|
|
my $v = ezec( @{ shift() } ); |
71
|
|
|
|
|
|
|
push @rolls, $v; |
72
|
|
|
|
|
|
|
while (@_) { |
73
|
|
|
|
|
|
|
my $p = ezec( @{ shift() } ); |
74
|
|
|
|
|
|
|
push @rolls, $p; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
return join( "; ", @rolls ); |
77
|
|
|
|
|
|
|
}; |
78
|
|
|
|
|
|
|
$table{'multiple'} = sub { |
79
|
|
|
|
|
|
|
my @rolls; |
80
|
|
|
|
|
|
|
my $op = shift(); |
81
|
|
|
|
|
|
|
my $multiple = ezec( @{ shift() } ); |
82
|
|
|
|
|
|
|
for ( 1 .. $multiple ) { |
83
|
|
|
|
|
|
|
push @rolls, ezec(@$op); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
return join( "\n", @rolls ); |
86
|
|
|
|
|
|
|
}; |
87
|
|
|
|
|
|
|
$table{double} = sub { |
88
|
|
|
|
|
|
|
my $f = ezec( @{ $_[0] } ); |
89
|
|
|
|
|
|
|
my $s = ezec( @{ $_[1] } ); |
90
|
|
|
|
|
|
|
return "$f>>" . ( $f + $s ); |
91
|
|
|
|
|
|
|
}; |
92
|
|
|
|
|
|
|
$table{dice} = sub { |
93
|
|
|
|
|
|
|
my $v = 0; |
94
|
|
|
|
|
|
|
my $ct = ezec( @{ $_[0] } ); |
95
|
|
|
|
|
|
|
my @rolls; |
96
|
|
|
|
|
|
|
push @rolls, int( 1 + rand( ezec( @{ $_[2] } ) ) ) for ( 1 .. $ct ); |
97
|
|
|
|
|
|
|
map { $v += $_ } sort @rolls[ 0 .. $#rolls - ezec( @{ $_[1] } ) ]; |
98
|
|
|
|
|
|
|
return $v; |
99
|
|
|
|
|
|
|
}; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub roll { |
102
|
11
|
|
|
11
|
1
|
144
|
my $output = $g->main( join( " ", @_ ) ); |
103
|
11
|
|
|
|
|
392393
|
my $result; |
104
|
11
|
|
|
|
|
35
|
eval { $result = ezec(@$output); }; |
|
11
|
|
|
|
|
50
|
|
105
|
11
|
50
|
|
|
|
26
|
if ($@) { |
106
|
0
|
|
|
|
|
0
|
$result = "dice not recognized"; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
#print "->" . Dumper( $output, $@ ); |
110
|
11
|
|
|
|
|
111
|
return $result; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
1; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
__END__ |