I didn't try anything fancy for this. I did try to get eval to do all
the work, but ran into too many problems. Here's my solution:
$searches = [
[/\(\d*\)/, lambda{|m| m[1..-2]}],
[/^d/, lambda{|m| "1d"}],
[/d%/, lambda{|m| "d100"}],
[/(\+|-|\*|\/|\()d\d+/, lambda{|m| m[0..0]+'1'+m[1..-1]}],
[/\d+d\d+/, lambda{|m| dice(*m.split('d').map {|i|i.to_i}) }],
[/\d+(\*|\/)\d+/, lambda{|m| eval m}],
[/\d+(\+|-)\d+/, lambda{|m| eval m}]
]
def parse(to_parse)
s = to_parse
while(s =~ /d|\+|-|\*|\/|\(|\)/)
$searches.each do |search|
if(s =~ search[0]) then
s = s.sub(search[0], &search[1])
break
end
end
end
s
end
def dice(times, sides)
Array.new(times){rand(sides)+1}.inject(0) {|s,i|s+i}
end
srand
string = ARGV[0]
(puts "usage: #{$0} <string> [<iterations>]"; exit) if !string
(ARGV[1] || 1).to_i.times { print parse(string), ' ' }
-----Horndude77