Hangman's Hope

Tagged as LISP, Programming

Written on 2008-10-17 08:02:04

The last week has been really, really hard. Mostly because I've been confronted with something I hoped wouldn't have to happen: The necessity of returning to academia. I've applied to a few more jobs and we'll see what happens there. I got turned down by King & Spalding in a letter today and am going to call tomorrow and ask why. I'm really just not getting enough done on my own to justify being out of school. I'm not learning enough. Perhaps I do need the structure. I'm disappointed but I have to re-evaluate based on my experience. State changes and given my present state I'm looking at returning to SPSU in the Spring or Fall of next of year. There's some notion of transferring to GA Tech as well but I'm not sure what I think about that.

One nice thing about SPSU would be that I'd at least have the spare time to continue pursuing LISP and other personal studies. It's also worth noting that a significant motivation in this year off was to at least get the fundamental concepts of programming down some before being buried in the specifics of the monstrous languages used to instruct most Freshman in Computer Science these days (i.e. Java; pythonistas at Tech, you're lucky).

Anyway, tonight I was frustrated with the fact that I hadn't written any code in a long time and I hadn't written a real program of my own in an even longer time. For one reason or another, implementing Hangman in Common Lisp seemed like a good idea. Now, I'm not claiming that hangman is ever any great feat...except maybe if you write it in BrainFuck. Nor is it any great feat to write it in under a hundred lines. Worse still is that it lacks any ASCII art. That said, I did this in a few hours, found it pretty fun and think it came out fairly readable and concise in the end. After all, how couldn't it? It's hangman.


;; Hangman
;; Brit Butler
;; v.01
;; Feature Ideas: ASCII hangman. Eliminate explicit elt references and other hackish
;; stuff, especially show-letter. Import dictionary in place of *word-list*.

(defparameter *word-list* '("cookies" "kittens" "fairies"
"unicorns" "words" "linux"
"lisp" "music" "songs"
"sex" "love" "fun"
"code" "cease" "and"
"desist" "read" "print"
"eval" "loop" "macro"))

(defparameter *turn-count* '())
(defparameter *letters-picked* '())
(defparameter *word-in-progress* '())
(defparameter *solved-word* '())

(defun hangman ()
(setf *turn-count* 7)
(setf *letters-picked* '())
(select-game-type)
(work-on-word))

(defun select-game-type ()
(if (y-or-n-p "Would you prefer to have a word chosen at random?")
(set-the-words (elt *word-list* (random (length *word-list*))))
(set-the-words (string-downcase (read-prompt "Please input your desired word: ")))))

(defun set-the-words (word-of-the-run)
(setf *solved-word* word-of-the-run)
(setf *word-in-progress* (make-array (length word-of-the-run)
:initial-element #\- :element-type 'character))
(format t "~a~%" *word-in-progress*))

(defun read-prompt (query-string)
(format *query-io* query-string)
(read-line *query-io*))

(defun check-letter (letter)
(if (already-picked? letter)
(format t "You already picked that goofball! Try again...~%")
(push letter *letters-picked*))
(cond ((is-in-word? letter) (show-letter letter))
((not (is-in-word? letter)) (decf *turn-count*)
(format t "Nope. Not in there. ~a turns left.~%" *turn-count*))))

(defun is-in-word? (letter &key (start 0))
(position letter *solved-word* :start start))

(defun already-picked? (letter)
(position letter *letters-picked*))

(defun show-letter (letter)
(setf (elt *word-in-progress* (is-in-word? letter)) letter)
(format t "~a~%" *word-in-progress*))

(defun pick-a-letter (&key (message "Pick a letter please: "))
(let ((rtn (read-prompt message)))
(if (> (length rtn) 1)
(pick-a-letter
:message "We only need ONE letter thank you very much. Try again: ")
(check-letter (elt rtn 0)))))

(defun work-on-word ()
(pick-a-letter)
(word-finished?))

(defun word-finished? ()
(if (= *turn-count* 0)
(game-over)
(if (string= *solved-word* *word-in-progress*)
(play-again? "Congratulations.")
(work-on-word))))

(defun game-over ()
(format t "Sorry. The word was ~a.~%" *solved-word*)
(play-again? "You're all out of turns. Game over."))

(defun play-again? (message)
(format t "~a~%" message)
(if (y-or-n-p "Would you like to play again?")
(hangman)
(format t "Thanks for playing!~%")))
comments powered by Disqus

Unless otherwise credited all material Creative Commons License by Brit Butler