Created
December 6, 2021 04:29
-
-
Save jakergrossman/86052723eb45f9bca71990c0aee26b17 to your computer and use it in GitHub Desktop.
Short implementation of hangman in GNU Common LISP.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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