When I execute the following Common Lisp program by calling (play)
, I get the error: Argument X is not a NUMBER: Guess
;;;; number-game.lisp
;;;;
;;;; Andrew Levenson
;;;; 10/25/2010
;;;;
;;;; Simple number guessing game. User has
;;;; five guesses to determine a number between
;;;; one and one hundred, inclusive (1-100).
;;; Set global variable for the target number:
(defparameter *target* nil)
;;; Set the iterator so we may check the number of guesses
(defparameter *number-of-guesses* 0)
;;; Welcome the user
(defun welcome-user ()
(format t "Welcome to the number guessing game!~%"))
;;; Prompt for a guess
(defun prompt-for-guess ()
(format t "Please enter your guess (1-100): ")
(finish-output nil) ; nil directs finish-output to standard IO
(check-guess 'read-guess))
;;; Read in a guess
(defun read-guess ()
(let ((guess (parse-integer(read-line *query-io*))))
(if (numberp guess) ; If true, return guess. Else, call prompt-for-guess
(progn
(setq *number-of-guesses* (+ *number-of-guesses* 1))
'guess)
(prompt-for-guess))))
;;; Check if the guess is higher than, lower than, or equal to, the target
(defun check-guess (fn)
(let ((guess (funcall fn)))
(if (= guess *target*)
(equal-to)
(if (> guess *target*)
(greater-than (guess))
(if (< guess *target*)
(less-than (guess)))))))
;;; If the guess is equal to the target, the game is over
(defun equal-to ()
(format t "Congratulations! You have guessed the target number, ~a!~%" *target*)
(y-or-n-p "Play again? [y/n] "))
;;; If the guess is greater than the target, inform the player.
(defun greater-than (guess)
(format t "Sorry, ~a is greater than the target.~%" guess)
(if (< *number-of-guesses* 6)
(prompt-for-guess)
(game-over)))
;;; If the guess is less than the target, inform the player.
(defun less-than (guess)
(format t "Sorry, ~a is less than the target.~%" guess)
(if (< *number-of-guesses* 6)
(prompt-for-guess)
(game-over)))
;;; If the player has run out of guesses, give them the option
;;; of playing the game again.
(defun game-over ()
(y-or-n-p "You have run out of guesses. Play again? [y/n] "))
;;; Play the game
(defun play ()
;; If it's their first time playing this session,
;; make sure to greet the user.
(unless (> *number-of-guesses* 0)
(welcome-user))
;; Reset their remaining guesses
(setq *number-of-guesses* 0)
;; Set the target value
(setq *target*
;; Random can return float values,
;; so we must round the result to get
;; an integer value.
(round
;; Add one to the result, because
;; (random 100) yields a number between
;; 0 and 99, whereas we want a number
;; from 1 to 100 inclusive.
(+ (random 100) 1)))
(if (equal (prompt-for-guess) "y")
(play)
(quit)))
What am I doing wrong that guess
is not a number value in check-guess
?