From b9e2736cf0bd8ef9e46af7d37491173ec6caf779 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Wed, 14 Aug 2024 15:15:44 +0100 Subject: [goforthanddie.rb] Make gooder --- goforthanddie.rb | 188 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 47 deletions(-) diff --git a/goforthanddie.rb b/goforthanddie.rb index 0a24300..58aac52 100755 --- a/goforthanddie.rb +++ b/goforthanddie.rb @@ -1,15 +1,22 @@ #!/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 = [] +def getmarkedlist(stack, markerautoclear) + h = [] + wm = false + loop do + t = stack.pop + wm = t == :mark + break if wm + h << t + break if stack.empty? + end + stack.push(:mark) if wm && !markerautoclear + h +end -loop do - print "> " - gets.split.each do |token| +def handle(str, stack, markermode, markerautoclear, destructiveprint) + exit if str.nil? + str.split.each do |token| case token when /[0-9]+/ stack.push(token.to_i) @@ -17,9 +24,14 @@ loop do a, b = stack.pop(2) stack.push(a + b) when ".+" - n = stack.pop - h = stack.pop(n) - stack.push(h.sum) + if markermode + h = getmarkedlist(stack, markerautoclear) + stack.push(h.sum) + else + n = stack.pop + h = stack.pop(n) + stack.push(h.sum) + end when "-" a, b = stack.pop(2) stack.push(a - b) @@ -37,50 +49,132 @@ loop do 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 + t = stack.pop + puts t + stack.push(t) unless destructiveprint + when ".ex", ".explode" + if markermode + x = stack.pop + h = getmarkedlist(stack, markerautoclear) + h.reverse! + 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) + else + 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) + end + when ".k", ".kh", ".keep", ".keephigh", ".keephighest" + if markermode + k = stack.pop + h = getmarkedlist(stack, markerautoclear) + h.sort! + stack.push(*h.pop(k)) + else + k = stack.pop + n = stack.pop + h = stack.pop(n).sort + stack.push(*h.pop(k)) + end + when ".kl", ".keeplow", ".keeplowest" + if markermode + k = stack.pop + h = getmarkedlist(stack, markerautoclear) + h.sort! + stack.push(*h.shift(k)) + else + k = stack.pop + n = stack.pop + h = stack.pop(n).sort + stack.push(*h.shift(k)) 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 }) + c = stack.pop + h = stack.pop + stack.push(c > h ? 1 : 0) + when ".>" + if markermode + c = stack.pop + h = getmarkedlist(stack, markerautoclear) + stack.push(h.count{ |d| c > d }) + else + c = stack.pop + n = stack.pop + h = stack.pop(n) + stack.push(h.count{ |d| c > d }) + end when "<" - t = stack.pop - n = stack.pop - h = stack.pop(n) - stack.push(h.count{ |d| d < t }) + c = stack.pop + h = stack.pop + stack.push(c < h ? 1 : 0) + when ".<" + if markermode + c = stack.pop + h = getmarkedlist(stack, markerautoclear) + stack.push(h.count{ |d| c < d }) + else + c = stack.pop + n = stack.pop + h = stack.pop(n) + stack.push(h.count{ |d| c < d }) + end when "!" stack.pop when ".!" - n = stack.pop - stack.pop(n) - when "q" + if markermode + getmarkedlist(stack, markerautoclear) + else + n = stack.pop + stack.pop(n) + end + when "m", "mark" + stack.push(:mark) + when "~s", "~stack" + puts stack.join(" ") + when "~mm" + markermode = !markermode + when "~mac" + markerautoclear = !markerautoclear + when "~dp" + destructiveprint = !destructiveprint + when "~state" + print "Stack: " + pp stack + print "Marker Mode: #{markermode ? "ON " : "OFF"} " + puts "Marker Auto-Clear: #{markerautoclear ? "ON " : "OFF"}" + puts "Destructive Print: #{destructiveprint ? "ON " : "OFF"}" + when "~q" exit else puts "I don't know how to #{token}!" end end end + +stack = [] +markermode = true +markerautoclear = false +destructiveprint = true + +if $stdin.tty? + loop do + print "> " + handle(gets, stack, markermode, markerautoclear, destructiveprint) + end +else + handle($stdin.read, stack, markermode, markerautoclear, destructiveprint) +end -- cgit v1.2.1