49 lines
1.6 KiB
Common Lisp
49 lines
1.6 KiB
Common Lisp
;; 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))
|
|
number)
|
|
|
|
(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)))
|