;; ;; 6.090 IAP '05 - animal guessing game ;; (load-option 'format) (define (ask-yes-no question) (let ((c (prompt-for-command-char (string-append question " (y or n)?")))) (if (char-ci=? c #\y) #t (if (char-ci=? c #\n) #f (begin (format #t "~%Answer y or n~%") (ask-yes-no question)))))) (define (read-in-string question) (format #t "~%~A~%" question) (format #t "(Please enter a string (surrounded by \"s) and use C-x, C-e to submit it)~%") (let ((val (read))) (if (string? val) val (read-in-string question)))) (define (print-msg text) (format #t "~%~A~%" text) #t) ;; animal abstraction (define (make-animal name) (list "animal" name)) (define (animal? x) (string=? (first x) "animal")) (define (animal-name animal) (second animal)) (define (ask-about-animal animal) (ask-yes-no (string-append "Is it a " (animal-name animal)))) ;; question tree abstraction (define (make-question text yes-branch no-branch) (list "question" text yes-branch no-branch)) (define (question? x) (string=? (first x) "question")) (define (question-text ques) (second ques)) (define (question-yes ques) (third ques)) (define (question-no ques) (fourth ques)) (define (ask-question ques) (ask-yes-no (question-text ques))) ;; (define (list-guesser knowledge) (if (null? knowledge) (print-msg "I give up.") (if (ask-about-animal (car knowledge)) (print-msg "Yay!") (list-guesser (cdr knowledge))))) (define (new-list-guesser knowledge) (if (null? knowledge) (begin (print-msg "I give up.") (improve-list)) (if (ask-about-animal (car knowledge)) (begin (print-msg "Yay!") knowledge) (cons (car knowledge) (new-list-guesser (cdr knowledge)))))) (define (improve-list) (list (make-animal (read-in-string "What was your animal")))) (define (tree-guesser knowledge) (if (animal? knowledge) (if (ask-about-animal knowledge) (print-msg "Yay!") (print-msg "I give up")) (if (ask-question knowledge) (tree-guesser (question-yes knowledge)) (tree-guesser (question-no knowledge))))) (define (new-tree-guesser knowledge) (if (animal? knowledge) (if (ask-about-animal knowledge) (begin (print-msg "Yay!") knowledge) (begin (print-msg "I give up.") (improve-tree knowledge))) (if (ask-question knowledge) (make-question (question-text knowledge) (new-tree-guesser (question-yes knowledge)) (question-no knowledge)) (make-question (question-text knowledge) (question-yes knowledge) (new-tree-guesser (question-no knowledge)))))) (define (improve-tree animal) (let ((newa (read-in-string "What was your animal"))) (let ((q (read-in-string (string-append "enter a question that differentiates a " newa " from a " (animal-name animal))))) (let ((which (ask-yes-no (string-append "for a " newa " would the answer be yes or no")))) (if which (make-question q (make-animal newa) animal) (make-question q animal (make-animal newa))))))) (define (play-game guesser knowledge) (let ((newqs (guesser knowledge))) (if (ask-yes-no "play again") (play-game guesser newqs) newqs))) (define sample-list (list (make-animal "elephant") (make-animal "hummingbird"))) (define sample-tree (make-question "does it fly" (make-animal "hummingbird") (make-animal "elephant"))) (define larger-tree (make-question "does it fly" (make-question "is it an insect" (make-animal "mosquito") (make-animal "hummingbird")) (make-question "is it a mammal" (make-animal "elephant") (make-animal "iguana"))))