#lang scheme ;; simon.ss plays a single round of the "Simon" game ;; provides: ;; (simple-simon n) consumes a positive integer n ;; produces a sequence of colors ;; from {red, blue, green, yellow} ;; ;; (press c) consumes a color c ;; produces 'win if c is correct and game done ;; 'ok if correct and game not done ;; 'lose if c is incorrect (provide simple-simon press score best-score) ;; helper function (random-color) produces a color ;; from {red, blue, green, yellow} (define (random-color) (define r (random 4)) (cond [(= r 0) 'blue] [(= r 1) 'red] [(= r 2) 'yellow] [true 'green])) ;; Mutable variable to hold the colors that ;; need to be pressed to win the game (define colors empty) (define maximum_presses 0) ;; (simple-simon n) provided by module; see interface (define (simple-simon n) (set! maximum_presses n) (set! correct_presses 0) (local [(define (build-list x) (cond [(= x 0) empty] [true (cons (random-color) (build-list (sub1 x)))]))] (set! colors (build-list n))) colors) (define correct_presses 0) ;; (press c) provided by module; see interface (define (press c) (define shouldbe (first colors)) (set! colors (rest colors)) (cond [(equal? c shouldbe) (set! correct_presses (add1 correct_presses)) (cond [(empty? colors) 'win] [true 'ok])] [true 'lose])) (define my-best 'undefined) ;; scoring function (define (score) (cond [(= maximum_presses 0) 'undefined] [else (local [(define this-score (- (* 2 correct_presses) maximum_presses))] (cond [(or (eq? my-best 'undefined) (> this-score my-best)) (set! my-best this-score) this-score] [else this-score]))])) (define (best-score) (score) my-best)