addons/roller: A capable die roller
This commit is contained in:
parent
1a7b4bb970
commit
5938547e05
1 changed files with 108 additions and 0 deletions
108
lib/addons/roller.rb
Normal file
108
lib/addons/roller.rb
Normal file
|
@ -0,0 +1,108 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Chronicle
|
||||
module Matrix
|
||||
# Roll dice and get the results
|
||||
#
|
||||
# @param message [hash] The message data from Matrix
|
||||
def handle_roll(client, message)
|
||||
msgstr = message.content[:body]
|
||||
.gsub(/!roll\s*/, '')
|
||||
.strip
|
||||
|
||||
room = client.ensure_room(message.room_id)
|
||||
|
||||
res = Roller.roll(msgstr)
|
||||
|
||||
final_msg = res.reduce("") { |x,y| x+y+"\n" }
|
||||
|
||||
room.send_notice(final_msg)
|
||||
end
|
||||
|
||||
module Roller
|
||||
# Solve an arithmatic forumla from a string
|
||||
#
|
||||
# @param string [String] The string representation of the formula
|
||||
# @return Integer of the solution
|
||||
def self.solve(string)
|
||||
formatted = string.gsub(/\s+/, '')
|
||||
formatted = formatted.gsub(/\[[\d,]*\]/) do |a|
|
||||
a.scan(/\d*/).reduce(0) { |x, y| x + y.to_i }
|
||||
end
|
||||
|
||||
if formatted.match(/\(.*\)/)
|
||||
formatted = formatted.sub(/\(.*\)/) do |m|
|
||||
solve(m[1..-2])
|
||||
end
|
||||
|
||||
solve(formatted)
|
||||
|
||||
elsif formatted.match(/\d+\*\d+/)
|
||||
formatted = formatted.sub(/\d+\*\d+/) do |m|
|
||||
m.split('*').reduce(1) { |x, y| x * y.to_i }
|
||||
end
|
||||
|
||||
solve(formatted)
|
||||
|
||||
elsif formatted.match(/\d+\/\d+/)
|
||||
formatted = formatted.sub(/\d*\/\d*/) do |m|
|
||||
m.split('/').reduce { |x, y| x.to_i / y.to_i }
|
||||
end
|
||||
|
||||
solve(formatted)
|
||||
|
||||
elsif formatted.match(/\d+\+\d+/)
|
||||
formatted = formatted.sub(/\d+\+\d+/) do |m|
|
||||
m.split('+').reduce(0) { |x, y| x + y.to_i }
|
||||
end
|
||||
|
||||
solve(formatted)
|
||||
|
||||
elsif formatted.match(/\d+\-\d+/)
|
||||
formatted = formatted.sub(/\d+\-\d+/) do |m|
|
||||
m.split('-').reduce { |x, y| x.to_i + -(y.to_i) }
|
||||
end
|
||||
|
||||
solve(formatted)
|
||||
|
||||
else
|
||||
formatted.to_i
|
||||
end
|
||||
end
|
||||
|
||||
# Pretty-print a result
|
||||
#
|
||||
# @param func [String] The name of the function
|
||||
# @param orig [String] The original request
|
||||
# @param string [String] The processed request
|
||||
# @param res [String] The result of the process
|
||||
# @return String re-formatted
|
||||
def self.pretty(func, orig, string, res)
|
||||
orig.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
||||
string.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
||||
"#{func.capitalize}: #{orig} (#{string}) ==> #{res}"
|
||||
end
|
||||
|
||||
# Roll dice
|
||||
#
|
||||
# @param string [String] The string representation of the dice roll
|
||||
# example: 2d4+6
|
||||
# @return Array of the message and the result
|
||||
def self.roll(string)
|
||||
results = []
|
||||
string.gsub(/\s+/,'').split(',').each do |roll|
|
||||
orig = roll
|
||||
res = roll.gsub(/[0-9]*d[0-9]*/) do |d|
|
||||
num,sides = d.split('d')
|
||||
num = num.empty? ? '1' : num
|
||||
Array.new(num.to_i.abs) { Random.new.rand(sides.to_i) + 1 }
|
||||
end
|
||||
|
||||
results << pretty("Roll", orig, res, solve(res))
|
||||
end
|
||||
|
||||
results
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue