Skip to content

Instantly share code, notes, and snippets.

@nathanic
Created February 15, 2015 22:49
Show Gist options
  • Save nathanic/27c0e31daae43d6c9091 to your computer and use it in GitHub Desktop.
Save nathanic/27c0e31daae43d6c9091 to your computer and use it in GitHub Desktop.
bitsbot dice plugin
(ns lazybot.plugins.dice
(:use lazybot.registry)
(:use lazybot.utilities)
(:require [clojure.string :as string])
(:require [instaparse.core :as insta])
(:require [clojure.core.match :refer [match]]))
; parser expects input like
; "3d20 + 2d4 + 10"
; and produces a list of structures like
; ([:die 3 20] [:die 2 4] [:const 10])
(def parse-throws
(insta/parser
"<command> := throw | throw <' '* '+' ' '*> command
<throw> := die | const
die := #'[0-9]*' <'d'> #'[0-9]+'
const := #'-?[0-9]+'
"))
(defn parse-int [s]
(Long/valueOf s))
(defn parse-quantity [s]
(if (empty? s)
1
(parse-int s)))
(defn eval-throw [throwspec]
(match [throwspec]
[[:die quantity size]]
(reduce + (for [_ (range (parse-quantity quantity))]
(+ 1 (rand-int (parse-int size)))))
[[:const quantity]]
(parse-int quantity)))
(defn describe-failure [f]
(str "Parse failure at column " (:column f) ": expecting `"
(string/join "` or `" (map :expecting (:reason f)))
"`"))
(defn eval-throws [throws]
(if (insta/failure? throws)
(describe-failure throws)
(reduce + (map eval-throw throws))))
(defplugin
(:cmd
"roll some RPG dice. example: `@roll 4d20 + 3d4 + 10` rolls 4 20-sided dice, 3 4-sided dice, and adds a modifier of +10" #{"roll"}
(fn [{:keys [nick raw-args] :as com-m}]
(showing-exceptions com-m
(if (empty? raw-args)
(send-message com-m (prefix nick
"Supply a D&D-style dice description such as @roll 3d20"))
(send-message com-m (prefix nick
"rolling (" (color :magenta raw-args) ") => "
(color :dark-green (eval-throws (parse-throws raw-args)))))))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment