Skip to content

Instantly share code, notes, and snippets.

@jakergrossman
Created December 6, 2021 04:29
Show Gist options
  • Select an option

  • Save jakergrossman/86052723eb45f9bca71990c0aee26b17 to your computer and use it in GitHub Desktop.

Select an option

Save jakergrossman/86052723eb45f9bca71990c0aee26b17 to your computer and use it in GitHub Desktop.
Short implementation of hangman in GNU Common LISP.
#!/usr/bin/gcl -f
; set random state
(setf *random-state* (make-random-state t))
(defun read-lines (stream)
(loop :for line = (read-line stream nil nil)
:while (and line (> (length line) 0))
:collect line))
(defun get-input (filename)
(with-open-file (stream filename) (read-lines stream)))
(defun game (target-letters guess-letters guessed-letters)
; print current state of guess
(map 'list (lambda (x) (format t "~c " x)) guess-letters)
(format t "~%")
; read new guess
(format t "Make a guess [")
(loop :for n :below (length guessed-letters)
do (format t "~c" (nth n guessed-letters)))
(format t "]:")
(setq guess (read-line))
; update guess
(loop :for n :below (length guess)
do
(setq guess-char (char guess n))
(loop :for m :below (length target-letters)
do
(cond
((eq (char guess n) (nth m target-letters))
(setf (nth m guess-letters) guess-char)
(cond
((eq nil (position guess-char guessed-letters))
(setf guessed-letters (append guessed-letters (list guess-char)))))))))
; check if done
(loop :for n :below (length target-letters)
do (cond ((not (eq (nth n target-letters) (nth n guess-letters))) (game target-letters guess-letters guessed-letters)))))
(cond
; read from arguments
((> (length si::*command-args*) 1) (setq words-file (cadr si::*command-args*)))
; read from stdin
(t
(format t "Enter dictionary file: ")
(setq words-file (read-line))))
(cond
((eq (length words-file) 0)
(format t "No dictionary file entered, using default dictionary (dictionary.txt).~%" *standard-output*)
(setq words (get-input "dictionary.txt")))
((string= "--" words-file)
(setq words (read-lines *standard-input*)))
(t (setq words (get-input words-file))))
(setq target-word (nth (random (length words)) words))
(setq target-letters (loop :for n :below (length target-word) :collect (char target-word n)))
(game target-letters (loop :for n :below (length target-letters) :collect #\_) '())
(format t "You guessed ~a!~%" target-word)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment