about summary refs log tree commit diff stats
path: root/loot.lsp
diff options
context:
space:
mode:
authorDarren Bane <darren.bane@gmail.com>2020-11-18 23:59:17 +0000
committerDarren Bane <darren.bane@gmail.com>2020-11-18 23:59:17 +0000
commit6e7cdcd4280f5330229ec9c943b9caf090846452 (patch)
tree7e7542c9edb9ef9805022ca105f42a56372aad9b /loot.lsp
parentf1dd340e2def134d0641ebbbf92934f69086b643 (diff)
downloadlsp-6e7cdcd4280f5330229ec9c943b9caf090846452.tar.gz
Checkpointing from my Mac
Diffstat (limited to 'loot.lsp')
-rwxr-xr-xloot.lsp41
1 files changed, 41 insertions, 0 deletions
diff --git a/loot.lsp b/loot.lsp
new file mode 100755
index 0000000..6192dbf
--- /dev/null
+++ b/loot.lsp
@@ -0,0 +1,41 @@
+;;; Port of https://en.wikipedia.org/wiki/ModernPascal#Code_Sample[3].
+;;; And then to CL.
+;;; I prefer my version.
+(defconstant +max-probability+ 1000)
+;; Because this is a simple enum and not a full sum/product type,
+;; I use symbols instead of CLOS.
+(defconstant +loot-type+ (vector 'bloodstone 'copper 'emeraldite 'gold
+                           'heronite 'platinum 'shadownite 'silver
+                           'soranite 'umbrarite 'cobalt 'iron
+                           'nothing))
+(defclass <looter> () ((probabilities :accessor probabilities)))
+(defgeneric choose (self))
+(defmethod choose ((self <looter>))
+  (let ((random-value (random (- +max-probability+ 1))))
+    (do ((loop 0 (+ loop 1)))
+        ((>= (elt (probabilities self) (mod loop 13)) random-value) (elt +loot-type+ (mod loop 13))))))
+(defmethod initialize-instance :after ((self <looter>) &rest initargs)
+  (setf (probabilities self) (vector 10 77 105 125 142 159 172 200 201 202 216 282 +max-probability+)))
+(defun as-string (l)
+  ;; Could use assoc here, but this is closer to the original.
+  ;; Also saves translating nil to "".
+  (case l
+    ((bloodstone) "Bloodstone")
+    ((copper) "Copper")
+    ((emeraldite) "Emeraldite")
+    ((gold) "Gold")
+    ((heronite) "Heronite")
+    ((platinum) "Platinum")
+    ((shadownite) "Shadownite")
+    ((silver) "Silver")
+    ((soranite) "Soranite")
+    ((umbrarite) "Umbrarite")
+    ((cobalt) "Cobalt")
+    ((iron) "Iron")
+    (t "")))
+(defun main ()
+  (let ((loot (make-instance (find-class '<looter>))))
+    (do ((n 0 (+ n 1)))
+      ((> n 99))
+      (format *standard-output* "~A~%" (as-string (choose loot))))))
+(main)