syncbot.scm 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #!/usr/bin/guile \
  2. -e main -s
  3. !#
  4. ;; Copyright (C) 2015 Christopher Allan Webber <cwebber@dustycloud.org>
  5. ;; This library is free software; you can redistribute it and/or
  6. ;; modify it under the terms of the GNU Lesser General Public
  7. ;; License as published by the Free Software Foundation; either
  8. ;; version 3 of the License, or (at your option) any later version.
  9. ;;
  10. ;; This library is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;; Lesser General Public License for more details.
  14. ;;
  15. ;; You should have received a copy of the GNU Lesser General Public
  16. ;; License along with this library; if not, write to the Free Software
  17. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  18. ;; 02110-1301 USA
  19. (use-modules (eightsync systems irc)
  20. (eightsync agenda)
  21. (ice-9 match)
  22. (srfi srfi-1))
  23. (set! *random-state* (random-state-from-platform))
  24. (define (random-choice lst)
  25. (list-ref lst (random (length lst))))
  26. (define (random-food-response)
  27. (random-choice
  28. `("Yippie! *does a dance!*"
  29. "oh boy! oh girl! oh arbitrary-gender-exclamation!"
  30. "Scrum-diddly-umptious!"
  31. "eeeee!"
  32. ":D :D :D"
  33. "*catches botsnack in midair*"
  34. "YESSSSSS *nom nom nom nom nom*"
  35. "thanks!"
  36. "*eyes treat suspiciously... then furiously devours it!*"
  37. "*gratefully affirms that botsnack is the most important command an irc bot can know*"
  38. ,(string-concatenate
  39. (list "Horray! A delicious "
  40. (random-choice
  41. '("pear" "banana"
  42. "caramel" "tapioca pudding"
  43. "fudge slurry"
  44. "banana walnut muffin"
  45. "iced soy vanilla mocha salted caramel latte"
  46. "cartoon canine snack"))
  47. "!")))))
  48. (define fate-ladder
  49. '((-2 . "terrible")
  50. (-1 . "poor")
  51. (0 . "mediocre")
  52. (1 . "average")
  53. (2 . "fair")
  54. (3 . "good")
  55. (4 . "great")
  56. (5 . "superb")
  57. (6 . "fantastic")
  58. (7 . "epic")
  59. (8 . "legendary")))
  60. (define (fate-ladder-value roll-number)
  61. (cond ((< roll-number -2)
  62. "it's... really not good...")
  63. ((> roll-number 8)
  64. "it's... off the charts!")
  65. (else
  66. (assoc-ref fate-ladder roll-number))))
  67. (define fate-dice-map
  68. '((-1 . "[-]") (0 . "[_]") (1 . "[+]")))
  69. (define* (roll-fate #:optional (base-roll 0))
  70. (let* ((rolls (map (lambda _ (- (random 3) 1)) (iota 4)))
  71. (dice-string (string-join
  72. (map (lambda (x) (assoc-ref fate-dice-map x))
  73. rolls)
  74. " "))
  75. (score (apply + base-roll rolls)))
  76. (format #f "Rolling at ~a: ~a -> ~a! (~a)"
  77. base-roll dice-string score
  78. (fate-ladder-value score))))
  79. (define* (roll-1d6)
  80. (let* ((numbers '(-5 -3 -1 2 4 6))
  81. (rolld6
  82. (lambda () (list-ref
  83. numbers
  84. (random 6)))))
  85. (let rolling ((rolled
  86. (cons (rolld6) '())))
  87. (cond
  88. ((and (= 1 (length rolled))
  89. (member
  90. (car rolled) '(-5 6)))
  91. (rolling (cons (rolld6) rolled)))
  92. ((and (< 1 (length rolled))
  93. (equal? (car rolled)
  94. (car (cdr rolled))))
  95. (rolling (cons (rolld6) rolled)))
  96. ((= 1 (length rolled))
  97. (car rolled))
  98. (else
  99. (apply + (cdr rolled)))))))
  100. (define (handle-message socket my-name speaker
  101. channel message is-action)
  102. (define (looks-like-me? str)
  103. (or (equal? str my-name)
  104. (equal? str (string-concatenate (list my-name ":")))))
  105. (let ((channel (if (looks-like-me? channel)
  106. speaker
  107. channel)))
  108. (write message)
  109. (match (string-split message #\space)
  110. (((? looks-like-me? _) action action-args ...)
  111. (match action
  112. ("botsnack"
  113. (irc-send-message socket channel (random-food-response)))
  114. ((or "hello" "hello!" "hello." "greetings" "greetings." "greetings!"
  115. "hei" "hei." "hei!" "hi" "hi." "hi!")
  116. (irc-send-formatted socket channel "Oh hi ~a!" speaker))
  117. ("failboat"
  118. (/ 1 0))
  119. ("help"
  120. (irc-send-message socket channel
  121. "I can't help you... I can't even help myself!"))
  122. ("echo"
  123. (irc-send-message socket channel
  124. (string-join action-args " ")))
  125. ("roll-fate"
  126. (let ((base-roll
  127. (match action-args
  128. (((? string->number base-roll) rest ...)
  129. (string->number base-roll))
  130. (_ 0))))
  131. (irc-send-formatted socket channel
  132. "~a: ~a"
  133. speaker (roll-fate base-roll))))
  134. ("d6"
  135. (irc-send-formatted socket channel
  136. "~a: *rolls*... you get a ~a!"
  137. speaker (+ (random 6) 1)))
  138. ((or "1d6" "±d6")
  139. (irc-send-formatted socket channel
  140. "~a: *rolls*... you get a ~a!"
  141. speaker (roll-1d6)))
  142. ("d20"
  143. (let ((score (+ (random 20) 1)))
  144. (if (eqv? score 20)
  145. (irc-send-formatted socket channel
  146. "~a: *rolls*... you get a ~a! *critical!*"
  147. speaker score)
  148. (irc-send-formatted socket channel
  149. "~a: *rolls*... you get a ~a!"
  150. speaker score))))
  151. ((or "d12" "d10" "d4")
  152. (irc-send-formatted socket channel
  153. "~a: *checks bag*... I left that one at home :("
  154. speaker))
  155. ;; Add yours here
  156. (whatever
  157. (display whatever)(newline)
  158. (irc-format socket "PRIVMSG ~a :*stupid puppy look*" channel))))
  159. ((":)" ...)
  160. ;; only wink back once every 20 times
  161. (if (equal? (random 20) 1)
  162. (irc-send-message
  163. socket channel
  164. (random-choice '(";)" ":)" ":D" "^_^" ":3")))))
  165. (_
  166. (cond
  167. (is-action
  168. (format #t "~a emoted ~s in channel ~a\n"
  169. speaker message channel))
  170. (else
  171. (format #t "~a said ~s in channel ~a\n"
  172. speaker message channel)))))))
  173. (define main
  174. (make-irc-bot-cli (make-handle-line
  175. #:handle-privmsg (wrap-apply handle-message))))