Created
March 23, 2014 01:00
-
-
Save tormaroe/9716815 to your computer and use it in GitHub Desktop.
My implementation in Scheme of the game Word, that was published in BASIC Computer Games in 1978.
This file contains 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
(use srfi-13 extras) | |
(define header #<<EOF | |
-------------------------------------------------------------------- | |
WORD | |
Adaption of original game in BASIC by Charles Reid of Lexington High | |
School, Massachusetts. Scheme version by Torbjørn Marø, 2014. | |
-------------------------------------------------------------------- | |
I am thinking of a word -- you guess it. I will give you clues to | |
help you get it. Good luck!! | |
EOF | |
) | |
(define words | |
'("SMOKE" "CANDY" "DINKY" "WATER" "TRAIN" "NIGHT" "MIGHT" "FIRST" | |
"CHAMP" "WOULD" "CLUMP" "DOPEY" "CRUSH" "EXTRA" "BASIC" "EIGHT")) | |
(define (random-elem lst) | |
(list-ref lst (random (length lst)))) | |
(define (random-sort l) | |
(sort l | |
(lambda (x y) | |
(equal? 0 (random 2))))) | |
;;; The GAME-STATE data type | |
(define-record game-state word | |
current-guess | |
continue | |
matches | |
exact-matches | |
guess-count) | |
(define (init-game) | |
(make-game-state | |
(random-elem words) ; word | |
" " ; current-guess | |
#t ; continue | |
'() ; matches | |
"-----" ; exact-matches | |
0)) ; guess-count | |
(define (game-state-correct? state) | |
(equal? (game-state-exact-matches state) | |
(game-state-word state))) | |
;;; REPL logic | |
(define (game-read state) | |
(display "\nGuess a five letter word? ") | |
(let ((input (read-line))) | |
(cond ((equal? input "?") | |
(game-state-current-guess-set! state "?") | |
state) | |
((= 5 (string-length input)) | |
(game-state-current-guess-set! state | |
(string-upcase input)) | |
(game-state-guess-count-set! state | |
(+ (game-state-guess-count state) 1)) | |
state) | |
(else | |
(display "Bad input length! ") | |
(game-read state))))) | |
(define (find-matches state) | |
(let loop ((i 0) (matches '()) (exact "-----")) | |
(cond | |
((< i 5) | |
(let ((c (substring (game-state-word state) i (+ i 1))) | |
(guess (game-state-current-guess state))) | |
(when (string-contains guess c) | |
(set! matches (cons c matches)) | |
(when (= i (string-index guess (string->char-set c))) | |
(set! exact (string-replace exact c i (+ i 1)))))) | |
(loop (+ i 1) matches exact)) | |
(else | |
(game-state-matches-set! state (random-sort matches)) | |
(game-state-exact-matches-set! state exact))))) | |
(define (game-eval state) | |
(let ((guess (game-state-current-guess state))) | |
(if (equal? guess "?") | |
(game-state-continue-set! state #f) | |
(find-matches state))) | |
state) | |
(define (game-print state) | |
(when (game-state-continue state) | |
(printf | |
"There were ~A matches and the common letters were.. ~A~%" | |
(length (game-state-matches state)) | |
(apply string-append (game-state-matches state))) | |
(printf | |
"From the exact letter matches, you know........... ~A~%" | |
(game-state-exact-matches state)) | |
(if (game-state-correct? state) | |
(printf | |
"You have guessed the word. It took ~A guesses!~%" | |
(game-state-guess-count state)) | |
(printf | |
"~%If you give up, type '?' for your next guess.~%"))) | |
state) | |
(define (start-game) | |
(display "\nYou are starting a new game...\n") | |
(let loop ((state (init-game))) | |
(when (and (game-state-continue state) | |
(not (game-state-correct? state))) | |
(loop (game-print | |
(game-eval | |
(game-read state))))))) | |
;;; MAIN | |
(define (yes-or-no) | |
(equal? "Y" (string-upcase (substring (read-line) 0 1)))) | |
(display header) | |
(let loop () | |
(start-game) | |
(display "Want to play again? ") | |
(if (yes-or-no) | |
(loop) | |
(display "\nThanks for playing - bye bye!\n\n"))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment