;; Simple number guessing game in Common Lisp (defmacro while (condition &body body) "While `condition' is not nil, evaluate `body'." `(loop while ,condition do (progn ,@body))) (defun make-random (max) "Generate a random number up to `max' using a new random state." (let ((*random-state* (make-random-state t))) (random max))) (defun read-integer () (parse-integer (read-line *query-io*) :junk-allowed t)) (defun attempt-guess (number) "Run one round of a number guessing game where `number' is the number the user is trying to guess." (let ((guess nil) (incorrect t)) (loop do (format *query-io* "Enter a number: ") (force-output *query-io*) (setf guess (read-integer)) (format t (cond ((< guess number) "The number is larger than ~D~%") ((> guess number) "The number is smaller than ~D~%") (t "Correct! The number was ~D~%")) guess) (when (= guess number) (setf incorrect nil)) while incorrect)) t) (defun begin-number-guessing-game (&key one-shot (maximum 100)) "If `one-shot' is t, run one round of a number guessing game. Otherwise run a chain of games until the user wants to stop. In both cases, `:maximum' is the maximum possible number." (when one-shot (return-from begin-number-guessing-game (attempt-guess (make-random maximum)))) (let ((playing nil)) (loop do (attempt-guess (make-random maximum)) (setf playing (y-or-n-p "Play again?")) (format t "~%") while playing)))