about summary refs log blame commit diff stats
path: root/loot.lsp
blob: 727f8f33994b693c5f76a8d97f6b86bec662e895 (plain) (tree)
1
2
3
4
5
6
7
8






                                                                      
                                                                 





                                                                


                                                                                                       


















                                                                                                       



                                                                      
      
;;; 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 'shaownite '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))))
    (for ((loop 0 (+ loop 1)))
	((>= (elt (probabilities self) (mod loop 13)) random-value) (elt +loot-type+ (mod loop 13))))))
(defmethod initialize-object :after ((self <looter>) 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 (create (class <looter>))))
    (for ((n 0 (+ n 1)))
	((> n 99))
	(format (standard-output) "~A~%" (as-string (choose loot))))))
(main)