(defparameter *words* (with-open-file (s "../programs/words_alpha.txt") (let ((arr (make-array 0 :fill-pointer 0 :adjustable t))) (loop :for line := (read-line s nil) :while line :do (vector-push-extend (subseq line 0 (1- (length line))) arr) ;;remove newline :finally (return arr))))) (defun random-word (words) (check-type words (or list vector)) (elt words (random (length words)))) (defun hangman (n-of-guesses) "Plays a game of hangman with a random word" (check-type n-of-guesses (integer 1 *)) (let ((random-word (random-word *words*))) (print random-word) (labels ((guess (word current guess-count guesses) (cond ((zerop guess-count) (error "out of guesses")) ((string= word current) t) (t (let ((guess (progn (format t "Current guesses ~A~%Guesses left ~A~%" guesses guess-count) (format t "Attempted ~S~%Enter a character: " current) (read-line)))) (cond ((not (= (length guess) 1)) (format t "Your guess is greater than length 1 try again~%") (guess word current guess-count guesses)) ((find guess guesses) (format t "You have already attempted that guess~%") (guess word current guess-count guesses)) ((find (aref guess 0) word) (guess word (show-in-string current word (aref guess 0)) guess-count (cons guess guesses))) ((not (find (aref guess 0) word)) (format t "failed to find ~S. Try again~%" (aref guess 0)) (guess word current (1- guess-count) (cons guess guesses))))))))) (handler-case (when (guess random-word (make-string (length random-word) :initial-element #\Space) n-of-guesses nil) (format nil "Success the word was ~S" random-word)) (simple-error () "Hangman!"))))) (defun show-in-string (str comparitor char) "Given a string (STR) a comparison string (COMPARITOR) and a character (CHAR), check if character is found within STR, if it is then return a new string with the new character displayed. STR should be a string containing spaces where letters are 'unknown'." (check-type str string) (check-type comparitor string) (check-type char character) (unless (= (length str) (length comparitor)) (error "string and comparitor are not the same length")) (let ((calced (map 'string (lambda (char1 char2) (if (and (char= char1 char) (char= char2 #\Space)) char1 char2)) comparitor str))) (if (string= calced str) nil calced)))