A simple Simon Says game using a Grove Base Shield, 3 Grove LED Bars, 1 Grove Buzzer, and 3 Grove Buttons.

Dependencies:   LED_Bar mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "LED_Bar.h"
00003 
00004 LED_Bar mid(D6, D5);
00005 LED_Bar right(D8, D7);
00006 LED_Bar left(D4, D3);
00007 InterruptIn button_left(A2);
00008 InterruptIn button_mid(A1);
00009 InterruptIn button_right(A0);
00010 DigitalOut buzzer(D2);
00011 /*  due to the type of InterruptIn .rise function call I am using (callback to
00012     a void function), the input array has to be global since you can't use 
00013     input parameters (to my knowledge) to the interrupted void function */
00014 int input_index;
00015 int input[100];
00016 bool start_flag = false;
00017 
00018 /*  start the game: animation/buzzer sounds */
00019 void start_level() {  
00020     for(int i = 0; i < 3; i++) {
00021         right.setLevel(10);
00022         mid.setLevel(10);
00023         left.setLevel(10);
00024         buzzer = 1;
00025         wait(0.4 - i*0.1);
00026         right.setLevel(0);
00027         mid.setLevel(0);
00028         left.setLevel(0);
00029         buzzer = 0;
00030         wait(0.4 - i*0.1);
00031     }   
00032     start_flag = true;
00033 }
00034 
00035 /*  generate random simon says sequence:
00036     level 1 will have a 3 LED blink combination, with each subsequent level
00037     having 1 more LED blink, so level 2 has a 4 blink combination, etc. */
00038 int level(int level_index, int sequence_size, int* sequence) {
00039     for(int i = 0; i < sequence_size; i++) {
00040         sequence[i] = rand() % 3 + 1;
00041     }
00042     button_right.rise(&start_level);
00043     button_mid.rise(&start_level);
00044     button_left.rise(&start_level);
00045     while(!start_flag) {
00046         wait(0.1);
00047     }
00048     return level_index++;
00049 }
00050 
00051 /*  simon says loop: turn on corresponding LED Bars according to the # 
00052     in the sequence array (1=right, 2=mid, 3=left) */
00053 void simon_loop(int sequence_size, int* sequence) { 
00054     for(int i = 0; i < sequence_size; i++) {  
00055         if (sequence[i] == 1) {
00056             right.setLevel(10);
00057             wait(0.4);
00058             right.setLevel(0);
00059         } else if (sequence[i] == 2) {
00060             mid.setLevel(10);
00061             wait(0.4);
00062             mid.setLevel(0);
00063         } else {
00064             left.setLevel(10);
00065             wait(0.4);
00066             left.setLevel(0);
00067         }
00068         wait(0.4);
00069     }
00070 }
00071 
00072 /*  void callback functions for the InterruptIn buttons - write a button index
00073     to the input global array depending on which button was pressed */
00074 void right_input() {
00075     input[input_index] = 1;
00076     input_index++;
00077     while(button_right) {
00078         right.setLevel(10);
00079     }
00080     right.setLevel(0);
00081 }
00082 
00083 void mid_input() {
00084     input[input_index] = 2;
00085     input_index++;
00086     while(button_mid) {
00087         mid.setLevel(10);
00088     }
00089     mid.setLevel(0);
00090 }
00091 
00092 void left_input() {
00093     input[input_index] = 3;
00094     input_index++;
00095     while(button_left) {
00096         left.setLevel(10);
00097     }
00098     left.setLevel(0);
00099 }
00100 
00101 /*  gather user input based on buttons pressed, then store button index into
00102     the input array (1=button_right, 2=button_mid, 3=button_left) */
00103 void input_loop(int sequence_size) {
00104     button_right.rise(&right_input);
00105     button_mid.rise(&mid_input);
00106     button_left.rise(&left_input);
00107     while(input_index < sequence_size) {
00108         wait(0.2);
00109     }
00110     input_index = 0;
00111 }
00112 
00113 /*  compare input array to simon says sequence array, if they are a match
00114     return true, if they are not a match return false */
00115 bool win_or_lose(int sequence_size, int* sequence) {
00116     for(int k = 0; k < sequence_size; k++) { 
00117         if (input[k] == sequence[k]) { continue; }
00118         else { return false; }
00119     }
00120     return true;
00121 }
00122 
00123 /*  display a happy LED animation for winning (LED levels 0 to 10 fast) */
00124 void success() {
00125     for(int i = 0; i < 2; i ++){
00126         for(int h = 0; h <=10; h++){
00127             mid.setLevel(h);
00128             right.setLevel(h);
00129             left.setLevel(h);
00130             wait(0.05);
00131         } 
00132     }
00133 }
00134 
00135 /*  display a sad LED animation for losing (LED levels 10 to 0 slow) */
00136 void failure() {
00137     for(int g = 0; g <= 10; g++){
00138         mid.setLevel(10-g);
00139         right.setLevel(10-g);
00140         left.setLevel(10-g);
00141         wait(0.1);
00142     }
00143 }
00144 
00145 int main() {
00146     int win_count = 0;
00147     int lose_count = 0;
00148     int level_index = 1;
00149     int sequence_size = 2;
00150     int sequence[100];
00151     while(1) {
00152         input_index = 0;
00153         mid.setLevel(0);
00154         right.setLevel(0);
00155         left.setLevel(0);
00156         sequence_size++;
00157         level_index = level(level_index, sequence_size, sequence);
00158         simon_loop(sequence_size, sequence);
00159         input_loop(sequence_size);
00160         wait(0.3);
00161         bool winner = win_or_lose(sequence_size, sequence);
00162         if (winner == true) { 
00163             win_count++; 
00164             success(); 
00165         } else { 
00166             lose_count++; 
00167             failure(); 
00168         }
00169         if (lose_count > 0) { // user lost so reset counter/level variables
00170             start_flag = false;
00171             win_count = 0;
00172             lose_count = 0;
00173             level_index = 1;
00174             sequence_size = 2;
00175         }
00176     }
00177 }