#lang racket ;; Change as appropriate for your OS (require "firmata-mac.rkt") (define yellow 8) (define green 9) (define red 10) (define blue 11) (define in-yellow 2) (define in-green 3) (define in-red 4) (define in-blue 5) (define colours (list yellow green red blue)) (define in-colours (list in-yellow in-green in-red in-blue)) ;; We now need to track the state of the buttons (define curStateYellow "UP") (define previousStateYellow "UP") (define curStateGreen "UP") (define previousStateGreen "UP") (define curStateRed "UP") (define previousStateRed "UP") (define curStateBlue "UP") (define previousStateBlue "UP") ;; The sequence of sounds to be played, initially empty (define seq '()) ;; The game can be in a number of states: we start from game over. (define state "gameOver") ;; Just a test sequence going up (define (lightsUp lights) (cond ( (> (length lights) 0) (set-arduino-pin! (first lights)) (sleep 0.1) (clear-arduino-pin! (first lights)) (sleep 0.05) (lightsUp (rest lights)) ) ) ) ;; Just blink a colour thrice (define (blink3 colour) (set-arduino-pin! colour) (sleep 0.3) (clear-arduino-pin! colour) (sleep 0.1) (set-arduino-pin! colour) (sleep 0.3) (clear-arduino-pin! colour) (sleep 0.1) (set-arduino-pin! colour) (sleep 0.3) (clear-arduino-pin! colour) ) ;; end of blink a colour 3 times ;; Just show the sequence (define (showSeq s) (cond ( (> (length s) 0) (set-arduino-pin! (first s)) (play-index (first s)) ;; (sleep 0.35) (clear-arduino-pin! (first s)) (sleep 0.2) (showSeq (rest s)) ) ) ) ;; end of showSeq ;; play a sound with afplay (works on a mac) (define (play note) (system (string-append "afplay " note ".wav &")) ) ;; play a note using its position (yellow - green - red - blue) (define (play-index i) (cond ( (= i yellow) (play "yellow")) ( (= i green) (play "green")) ( (= i red) (play "red")) ( (= i blue) (play "blue")) ) ) ;; set up things and do a demo sequence. (define (setup) (map (λ (i) (set-pin-mode! i OUTPUT_MODE)) colours) (report-digital-port! 0 1) (map (λ (i) (set-pin-mode! i INPUT_MODE)) in-colours) ;; We blink all lights to notify that we are ready (map (λ (i) (set-arduino-pin! i)) colours) (sleep 0.2) (map (λ (i) (clear-arduino-pin! i)) colours) (sleep 0.2) (map (λ (i) (set-arduino-pin! i)) colours) (sleep 0.2) (map (λ (i) (clear-arduino-pin! i)) colours) (sleep 0.1) ;; maybe play a sound here ) ;; end of setup ;; The main loop: we go through various states: gameOver -> showSequence -> playing -> wrongChoice -> gameOver (define (mainLoop) (cond ( (equal? state "gameOver") (printf "DEBUG: Current state is gameOver\n") ;; If we are in game over, we clear the sequence, we add ;; a random value and we set state to "playing" (set! seq '()) (set! seq (append seq (list (list-ref colours (random (length colours)))))) ;; (blink3 green) (sleep 0.5) (set! state "showSequence") ) ( (equal? state "showSequence") (printf "DEBUG: Current state is showSequence\n") ;; We show the sequence and then we enter playing (sleep 0.3) (set! state "playing") (showSeq seq) ) ( (equal? state "playing") (printf "DEBUG: Current state is playing\n") ;; We enter the main playing loop, see below (player does things) (playingLoop seq) ) ( (equal? state "wrongChoice") ;; The player has made a wrong choice: ;; we enter game over state (sleep 0.5) (set! state "gameOver") ) ( (equal? state "correctSequence") (set! seq (append seq (list (list-ref colours (random (length colours)))))) (sleep 0.5) (showSeq seq) (set! state "playing")) ) (mainLoop) ) ;; end of mainLoop ;; The playing loop: the player has to guess the sequence s, we call ourselves ;; recursively on s. (define (playingLoop s) ;; to keep track of a correct choice, used to loop at the end (define correct "") (cond ( (= (length s) 0) ;; if the list is empty, we guessed all the colours correctly! (set! state "correctSequence") (printf "DEBUG: well done, the sequence is correct!\n") ) (else ;; There are more colours to be guessed, we keep looping here ;; recording what is being pressed (cond ( (is-arduino-pin-set? in-yellow) (set! curStateYellow "DOWN")) (else (set! curStateYellow "UP"))) (cond ( (is-arduino-pin-set? in-green) (set! curStateGreen "DOWN")) (else (set! curStateGreen "UP"))) (cond ( (is-arduino-pin-set? in-red) (set! curStateRed "DOWN")) (else (set! curStateRed "UP"))) (cond ( (is-arduino-pin-set? in-blue) (set! curStateBlue "DOWN")) (else (set! curStateBlue "UP"))) ;; switch on the lights and check if it is correct when we release ;; Blue (cond ( (and (equal? curStateBlue "DOWN") (equal? previousStateBlue "UP")) (printf "DEBUG: blue pressed\n") (set-arduino-pin! blue) (play "blue") )) (cond ( (and (equal? curStateBlue "UP") (equal? previousStateBlue "DOWN")) (printf "DEBUG: blue released\n") (clear-arduino-pin! blue) (cond ( (= (first s) blue) ;; the player chose the right colour (set! correct "T") ) (else (set! correct "F")) ) ) ) ;; end of blue button released ;; Yellow (cond ( (and (equal? curStateYellow "DOWN") (equal? previousStateYellow "UP")) (printf "DEBUG: yellow pressed\n") (set-arduino-pin! yellow) (play "yellow") )) (cond ( (and (equal? curStateYellow "UP") (equal? previousStateYellow "DOWN")) (printf "DEBUG: yellow released\n") (clear-arduino-pin! yellow) (cond ( (= (first s) yellow) ;; the player chose the right colour (set! correct "T") ) (else (set! correct "F")) ) ) ) ;; end of yellow button released ;; Red (cond ( (and (equal? curStateRed "DOWN") (equal? previousStateRed "UP")) (printf "DEBUG: red pressed\n") (set-arduino-pin! red) (play "red") )) (cond ( (and (equal? curStateRed "UP") (equal? previousStateRed "DOWN")) (printf "DEBUG: red released\n") (clear-arduino-pin! red) (cond ( (= (first s) red) ;; the player chose the right colour (set! correct "T") ) (else (set! correct "F")) ) ) ) ;; end of red button released ;; Green (cond ( (and (equal? curStateGreen "DOWN") (equal? previousStateGreen "UP")) (printf "DEBUG: green pressed\n") (set-arduino-pin! green) (play "green") )) (cond ( (and (equal? curStateGreen "UP") (equal? previousStateGreen "DOWN")) (printf "DEBUG: green released\n") (clear-arduino-pin! green) (cond ( (= (first s) green) ;; the player chose the right colour (set! correct "T") ) (else (set! correct "F")) ) ) ) ;; end of green button released ;; Setting the previous states (set! previousStateBlue curStateBlue) (set! previousStateRed curStateRed) (set! previousStateGreen curStateGreen) (set! previousStateYellow curStateYellow) (cond ( (equal? correct "T") (playingLoop (rest s))) ( (equal? correct "F") (set! state "wrongChoice") (printf "DEBUG: ops, wrong choice!\n") (play "wrong")) (else (playingLoop s)) ) ) ;; end else (sequence not empty) ) ;; end cond ) ;; end playingLoop (define (start) (open-firmata "/dev/tty.usbmodem1411") (setup) (mainLoop) )