#!/usr/bin/env ruby # d20+1 # 20 1 d 1 + p # 10d6k8 # 6 10 d 10 8 keep 8 .+ p # 3d6>2 # 6 3 d 3 2 > p # 3d12/2 # 12 3 d + + 2 / p stack = [] loop do print "> " gets.split.each do |token| case token when /[0-9]+/ stack.push(token.to_i) when "+" a, b = stack.pop(2) stack.push(a + b) when ".+" n = stack.pop h = stack.pop(n) stack.push(h.sum) when "-" a, b = stack.pop(2) stack.push(a - b) when "*" a, b = stack.pop(2) stack.push(a * b) when "/" a, b = stack.pop(2) stack.push(a / b) when "%" a, b = stack.pop(2) stack.push(a % b) when "d", "roll" n = stack.pop d = stack.pop n.times { stack.push(rand(d) + 1) } when "p" puts stack.pop when "s" puts stack.join(" ") when "ex", "explode" x = stack.pop n = stack.pop h = stack.pop(n) lm = 0 loop do m = h.count(x) break if m == lm (m-lm).times { h << (rand(x) + 1) } lm = m end stack.push(*h) when "k", "kh", "keep", "keephigh", "keephighest" k = stack.pop n = stack.pop h = stack.pop(n).sort stack.push(*h.pop(k)) when "kl", "keeplow", "keeplowest" k = stack.pop n = stack.pop h = stack.pop(n).sort stack.push(*h.shift(k)) when ">" t = stack.pop n = stack.pop h = stack.pop(n) stack.push(h.count{ |d| d > t }) when "<" t = stack.pop n = stack.pop h = stack.pop(n) stack.push(h.count{ |d| d < t }) when "!" stack.pop when ".!" n = stack.pop stack.pop(n) when "q" exit else puts "I don't know how to #{token}!" end end end