Simon says - Arduino Uno code


#define NOTE_A4  440
#define NOTE_F4  349
#define NOTE_C5  523
#define NOTE_E5  659
#define NOTE_F3  175
#define NOTE_E3  165
#define NOTE_B2  123
#define NOTE_B4  494
#define NOTE_F5  698

#define startbutton 12
#define mic 13

  int buttons[] = {0,1,2,3};
  int segment7[]  = {4,5,6,7};
  int leds[] ={8,9,10,11};
  int button_notes[] = {NOTE_A4,NOTE_F4,NOTE_C5,NOTE_E5};
  
  int starttune[] = {NOTE_A4, NOTE_A4, NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_E5, NOTE_E5,
NOTE_E5, NOTE_F5, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4}; 
  // Array with the note durations: a quarter note has a duration of 4, half note 2 etc.
  int startdurations[]  = {4, 4, 4, 5, 16, 4, 5, 16, 2, 4, 4, 4, 5, 16, 4, 5, 16, 2};
  int startleds[] = {8,8,8,9,10,8,8,9,8,11,11,11,9,10,8,9,10,8 };
//  int starttempo = 120;
  int failtune[] = {  NOTE_F3, NOTE_E3, NOTE_F3, NOTE_E3, NOTE_B2};
  int faildurations[] = {  8, 8, 4, 4, 1};
  int failleds[] = { 11,10,11,10,8 };
//    
  int wintune[] = {  NOTE_B4, NOTE_E5, NOTE_F5, NOTE_B4, NOTE_E5, NOTE_F5};
  int windurations[] = {  8, 8, 8, 4, 4, 1};
  int winleds[] = { 8,10,11,8,10,11 };

    
int turn;  // 0 = first turn  
long old = 5;
int random_array[10]; 
int input_array[10];  
boolean failed = false;

void setup() 
{

  for (int i=0; i < 4; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], HIGH);  // 20K pull-up    
    pinMode(segment7[i], OUTPUT);
    digitalWrite(segment7[i],LOW);
    pinMode(leds[i], OUTPUT);
  }

  pinMode(mic, OUTPUT);
  pinMode(startbutton, INPUT);
  digitalWrite(startbutton, HIGH);
      
   
  playTune(starttune,startdurations,startleds, 18);
  delay(1000);
}

void playTune(int notes[], int durations[], int _leds[], int _size) {

     for (int thisNote = 0; thisNote < _size; thisNote++) {
     int _duration = 1000 / durations[thisNote];     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
     digitalWrite(_leds[thisNote], HIGH);
     tone(mic, notes[thisNote], _duration);
     int pauseBetweenNotes = _duration * 0.65;   // to distinguish the notes, set a minimum time between them.
     delay(pauseBetweenNotes);
     digitalWrite(_leds[thisNote], LOW);
     delay(pauseBetweenNotes);
     // stop the tone playing:
     noTone(mic);
   } 
}

void show_random(int act) {  // 0 1 2 3 4 5 
  long val;
  // show what has been recorded so far
  for (int i=0; i < act; i++) {
    val = random_array[i];
    digitalWrite(leds[val],HIGH);
    tone(mic,button_notes[val], 500);    
    delay(700);
    digitalWrite(leds[val],LOW);
    delay(500);
  }
  // add one memory to the array
    val = random(0,4);  // I don't like too many doubles
    if (val == old) {
      val = random(0,4);
    } else {
      old = val;
    }
    random_array[act] = val;
    digitalWrite(leds[val],HIGH);
    tone(mic,button_notes[val], 500);    
    delay(500);
    digitalWrite(leds[val],LOW);
  
  delay(500);
}

void update_7seg(int round) {
  round++;
  for (int i=0; i<4; i++) {
    digitalWrite(segment7[i], LOW);
  }
  switch (round) {
  case 1:
    digitalWrite(segment7[0], HIGH);
    break;
  case 2:
   digitalWrite(segment7[1], HIGH);
    break;
  case 3:
    digitalWrite(segment7[0], HIGH);
    digitalWrite(segment7[1], HIGH);    
    break;
  case 4:
   digitalWrite(segment7[2], HIGH);
    break;
  case 5:
   digitalWrite(segment7[0], HIGH);
   digitalWrite(segment7[2], HIGH);   
    break;
  case 6:
    digitalWrite(segment7[1], HIGH);  
    digitalWrite(segment7[2], HIGH);
    break;
  case 7:
   digitalWrite(segment7[0], HIGH);
   digitalWrite(segment7[1], HIGH);  
   digitalWrite(segment7[2], HIGH);
    break;
  case 8:
    digitalWrite(segment7[3], HIGH);
    break;
  case 9:
   digitalWrite(segment7[0], HIGH);
   digitalWrite(segment7[3], HIGH);
    break;
  default:
    break;
	}
}

void get_input(int act) {

  //   act = 0 1 2 3 4 5
  //   from 0 to 0 or from 0 to 1
  for (int i=0; i <= act; i++) {
    int k = 0;
    boolean button_pressed = false;
  
    while (button_pressed == false) {
      if (digitalRead(buttons[k]) == LOW) {

           button_pressed = true;
            if (random_array[i] == k) {
              digitalWrite(leds[k],HIGH);
              tone(mic,button_notes[k], 300);    
              delay(500);
              digitalWrite(leds[k],LOW);

            } else {
              user_failed();
              return;
              
            }
            while (digitalRead(buttons[k]) == LOW) { 
            //  wait for the release of this button
           }                     
      }
      k++;
      if (k == 4) k=0;
    } // while
  } // for loop
  update_7seg(act); 
}

void user_failed() {
  failed = true;
  playTune(failtune, faildurations, failleds, 5);
}

 
void loop() {   
  update_7seg(10);
  randomSeed(analogRead(0));  
  turn = 0;
  failed = false;
  while(digitalRead(startbutton) == HIGH) {
      // wait
    }
  while (failed == false) {
    delay(2000);
    show_random(turn);
    get_input(turn);
    
    turn++;
    if (turn == 10) {     
      if (failed == false) {
        playTune(wintune, windurations, winleds, 6);
      }
      failed = true; // actually it's a win
    }
  }
}