rendered paste bodypackage Dice;
use warnings;
use strict;
use Carp;
use overload bool => sub { return $_[0]->{dice} + $_[0]->{pips} },
'""' => \&str,
'*' => \&mul,
'+' => \&add,
'++' => \&add,
'-' => \&subt,
'--' => \&subt;
sub mul {
my $a = shift;
confess "Nothing to subtract!" unless @_;
my $b = shift;
confess "Variable \$b <$b> isn't a number!" unless $b =~ /^[+-]?\d+?$/;
return Dice->new($a->{dice} * $b, $a->{pips} * $b);
}
sub subt {
my $a = shift;
confess "Nothing to subtract!" unless @_;
my $b = shift;
my $order = @_ ? shift : 5;
if (not ref $b) {
eval { $b = Dice->new($b) };
if ($@) {
print STDERR "$@\n";
$b = Dice->new(0, 0);
}
}
($a, $b) = ($b, $a) if $order;
confess "Variable \$a <$a> is not an object reference!" unless ref $a;
confess "Variable \$b <$b> is not an object reference!" unless ref $b;
my $res;
if (ref $b eq ref $a) { # $b is a die code penalty or something
$res = Dice->new($a->{dice} - $b->{dice}, $a->{pips} - $b->{pips});
} elsif ($b =~ /([+-]?\d+?) \+ ([+-]?\d+?)/) {
$res = Dice->new($a->{dice} - $1, $a->{pips} - $2);
} else {
confess "Gah!";
}
$order eq '' ? $_[0] = $res : $res;
}
sub add {
my $d = shift;
confess "That's not an object!" unless ref $d;
confess "Nothing to add!" unless @_;
my $val = shift;
my $res;
my $mut = @_ ? shift : 5;
if (ref $d eq ref $val) {
return Dice->new($d->{dice} + $val->{dice}, $d->{pips} + $val->{pips});
} elsif ($val =~ /([+-]\d+?)D \+ (\d+?)/) {
print STDERR $val, "\n";
$res = Dice->new($d->{dice} + $1, $d->{pips} + $2);
} elsif ($val =~ /^[+-]?\d+?/) { # stringy and numberish at the same time!!
$res = Dice->new($d->{dice} + @_ ? int shift : 0, $d->{pips} + $val);
} elsif (not defined $val) {
$res = Dice->new($d->{dice} + 1, $d->{pips});
} else {
confess "Inexplicable value $val!";
}
$mut eq '' ? $_[0] = $res : $res;
}
sub str {
my $d = shift;
ref $d
? sprintf '%dD + %d', $d->{dice}, $d->{pips}
: sprintf '%dD + %d', @_ ? int shift : 1, @_ ? int shift : 0
}
sub new {
my $class = shift;
# everyone's favorite copy constructor!
return new("$class") if ref $class and not @_;
my $dice = @_ ? shift : 1;
my $pips;
if ($dice =~ /^([+-]?\d+?)D \+ (\d+?)$/) {
$dice = $1;
$pips = $2;
} elsif ($dice =~ /^[+-]?\d+?$/) {
$pips = @_ ? int shift : 0;
} else {
confess "Got passed an inexplicable value of $dice\n";
}
my $self = {dice => $dice, pips => $pips};
bless $self, $class;
return $self;
}
5;