|
@@ -0,0 +1,48 @@
|
|
|
+(defvar *initialized-p* nil)
|
|
|
+
|
|
|
+(defun ensure-positive (number)
|
|
|
+ (if (< number 0)
|
|
|
+ (- number)
|
|
|
+ number))
|
|
|
+
|
|
|
+(defun ensure-initialized ()
|
|
|
+ (when (not *initialized-p*)
|
|
|
+ (setq *random-state* (make-random-state t)
|
|
|
+ *initialized-p* t)
|
|
|
+ (dotimes (number (ensure-positive (random 100)))
|
|
|
+ (dotimes (other (ensure-positive (random (1+ number))))
|
|
|
+ (dotimes (yet-another (ensure-positive (random (1+ other))))
|
|
|
+ (ensure-positive (random (1+ yet-another))))))))
|
|
|
+
|
|
|
+(defun flip-coin (stream number)
|
|
|
+ (ensure-initialized)
|
|
|
+ (format stream "Flipping ~a coins.~&" number)
|
|
|
+ (dotimes (n number)
|
|
|
+ (if (= (mod (random 100) 2) 0)
|
|
|
+ (format stream "Heads.~&")
|
|
|
+ (format stream "Tails.~&"))))
|
|
|
+
|
|
|
+(defun roll-die (stream number type)
|
|
|
+ (ensure-initialized)
|
|
|
+ (format stream "Rolling a ~a-sided die ~a times.~&" type number)
|
|
|
+ (dotimes (n number)
|
|
|
+ (let ((die (1+ (mod (ensure-positive (random (* 100 type))) type))))
|
|
|
+ (format stream "You rolled a ~a.~&" die))))
|
|
|
+
|
|
|
+(defun main ()
|
|
|
+ (let ((type (if (not (null (second *posix-argv*)))
|
|
|
+ (intern (string-upcase (second *posix-argv*)) "KEYWORD")))
|
|
|
+ (times (if (and (not (null (second *posix-argv*)))
|
|
|
+ (not (null (third *posix-argv*))))
|
|
|
+ (parse-integer (third *posix-argv*) :junk-allowed t)
|
|
|
+ 1)))
|
|
|
+ (case type
|
|
|
+ (:die
|
|
|
+ (roll-die *standard-output* times (if (not (null (fourth *posix-argv*)))
|
|
|
+ (parse-integer (fourth *posix-argv*) :junk-allowed t)
|
|
|
+ 6)))
|
|
|
+ (:coin
|
|
|
+ (flip-coin *standard-output* times))
|
|
|
+ (t
|
|
|
+ (format *standard-output*
|
|
|
+ "make-decision [ die [ times [ type ] ] | coin [ times ] ]~&")))))
|