# Custom die class to take into account
# Multiple dice, bonuses added to dice and dropped dice
class Die
# Standard initializer
def self.[] str
raise TypeError, "Argument must be a String" unless str.is_a? String
raise ArgumentError, "Error: Malformed Argument\
\nUsage:\
\n\t<Number>d<Die>\
\n\t<Number>d<Die><+ or -><Bonus>\
\n\t<Number>d<Die><+ or -><Bonus> drop <NumDropped>\
\nExamples:\
\n\tDMT::Die[\"3d6\"]\
\n\tDMT::Die[\"3d6+4\"], DMT::Die[\"3d6-2\"]\
\n\tDMT::Die[\"4d6 drop 1\"], DMT::Die[\"4d6-2 drop 1\"]\
\n" unless str.match /\A(\d+d\d+\ ?([\+\-]\ ?\d+)?(\ drop\ \d+)?)\z/
args = (str.split /\D/).reject{|s| s.empty?}.map{|i| i.to_i}
if str.include? "drop" then
if str.include? "-" then
new args[0], args[1], -args[2], args[3]
else
(args.size.eql? 3) ? (new args[0], args[1], 0, args[2]) : (new *args)
end
else
if str.include? "-" then
new args[0], args[1], -args[2]
else
new *args
end
end
end
# Die roller, produces a random number
def roll
damage = @bonus
dies = []
@number.times { dies.push (rand @value) + 1 }
(dies.sort.last dies.size - @drop).each { |d| damage += d }
damage
end
def inspect
"<Die: #{@number}d#{@value}" +
(@bonus.zero?? "" : @bonus < 0 ? @bonus.to_s : "+#{@bonus}") +
(@drop.zero?? "" : " Drop #{@drop}") + ">"
end
protected
def initialize num, val, bonus = 0, drop = 0
@number = num
@value = val
@bonus = bonus
@drop = drop
end
end
end
Name:
Anonymous2012-06-30 20:06
print(5 ? 4D6-2 DROP 1);
MODE DIE = STRUCT(INT count, sides, dropped, multiplier, additive);
PRIO D = 6, DROP = 6, KEEP = 6, ? = 5;
OP D = (INT count, sides)DIE: (count, sides, 0, 1, 0);
OP D = (INT sides)DIE: (1, sides, 0, 1, 0);
OP DROP = (DIE d, INT n)DIE: (count OF d, sides OF d, n, multiplier OF d, additive OF d);
OP KEEP = (DIE d, INT n)DIE: (count OF d, sides OF d, count OF d - n, multiplier OF d, additive OF d);
OP + = (DIE d, INT n)DIE: (count OF d, sides OF d, dropped OF d, multiplier OF d, additive OF d + n);
OP - = (DIE d, INT n)DIE: (count OF d, sides OF d, dropped OF d, multiplier OF d, additive OF d - n);
OP * = (DIE d, INT n)DIE: (count OF d, sides OF d, dropped OF d, multiplier OF d * n, additive OF d);
OP ? = (INT lim)INT: ENTIER(random * lim) + 1;
OP ? = (DIE d)INT: roll(d);
OP ? = (INT n, DIE d)[]INT: ([n]INT r; FOR i TO n DO r[i] := roll(d) OD; r);
PROC roll = (DIE d)INT:
IF count OF d <= 0 OR dropped OF d >= count OF d THEN
0
ELIF dropped OF d > 0 THEN
[sides OF d]INT r, INT min := 1, n := 0;
FOR i TO UPB r DO r[i] := 0 OD;
TO count OF d DO r[?sides OF d] +:= 1 OD;
TO dropped OF d DO
WHILE r[min] = 0 DO min +:= 1 OD;
r[min] -:= 1
OD;
FOR i TO UPB r DO n +:= i * r[i] OD;
n
ELSE
INT n := 0;
TO count OF d DO n +:= ?sides OF d OD;
n
FI * multiplier OF d + additive OF d;
~