/*
  Simon
  
  Simula il gioco di Simon con tre led e tre interruttori
  
  The circuit:
  Vedi lo schema fatto con Fritzing
  
  
  Created 18 Gennaio 2009
  By Alessandro Bugatti
  
*/



const int debugPin 13;
const int inPin1 12;
const int outPin1 11;
const int inPin2 9;
const int outPin2 8;
const int inPin3 5;
const int outPin3 4;
const int buzzerPin 3;

int inPin[]={inPin1,9,5};
int outPin[]={11,8,4};

const int dim 3;

const int BUZZ_GIALLO 50;
const int BUZZ_VERDE 75;
const int BUZZ_ROSSO 100;

const int MAX 20;

int sequenza[MAX];

int buzz[]={BUZZ_GIALLO,BUZZ_VERDEBUZZ_ROSSO};

int tempo 1000;

int errore;
int i;

//Spegne tutti i led
void cleanOut()
{
    for (int i=0i<dim;i++)
        digitalWrite(outPin[i],LOW);
}

 // The setup() method runs once, when the sketch starts

//Legge i pulsanti
int readButton()
{
    for (int i=0i<dim;i++)
        if (digitalRead(inPin[i])==LOW)
            return i;
    return -1;
}

void crea_sequenza()
{
    for (int i=0;i<MAX;i++)
        sequenza[i]=random(0,3);
}

void esegui_sequenza(int n)
{
    for (int i=0;i<n;i++)
    {   
        digitalWrite(outPin[sequenza[i]],HIGH);
        analogWrite(buzzerPinbuzz[sequenza[i]]); 
        delay(tempo);
        digitalWrite(outPin[sequenza[i]],LOW);
        analogWrite(buzzerPin0);
        delay(tempo/2);
    }
}

bool leggi_sequenza(int n)
{
    for (int i=0;i<n;i++)
    {   
        int val readButton();
        while (val == -1)
            val readButton();
        if (val != sequenza[i]) return 1;
        digitalWrite(outPin[sequenza[i]],HIGH);
        analogWrite(buzzerPinbuzz[sequenza[i]]); 
        delay(300);
        digitalWrite(outPin[sequenza[i]],LOW);
        analogWrite(buzzerPin0);
    }
    return 0;
}

void segnala_errore()
{
    analogWrite(buzzerPin25); 
    digitalWrite(outPin[0],HIGH);
    digitalWrite(outPin[1],HIGH);
    digitalWrite(outPin[2],HIGH);
    delay(2000);
    analogWrite(buzzerPin0);
    cleanOut();
    delay(2000);
}

void segnala_vittoria()
{
    
    for (int i=0;i<3;i++)
    {
        analogWrite(buzzerPin100);
        digitalWrite(outPin[0],HIGH);
        digitalWrite(outPin[1],HIGH);
        digitalWrite(outPin[2],HIGH);
        delay(500);
        cleanOut();
        analogWrite(buzzerPin0);
        delay(200);
    }
        
}
    

 void setup()   {                
   //Inizializza i pin   
   for (int i=0i<dim;i++){
   pinMode(inPin[i], INPUT);     
   pinMode(outPin[i], OUTPUT);
  }     
    cleanOut();
    randomSeed(analogRead(0));

 }




 // the loop() method runs over and over again,
 // as long as the Arduino has power

 void loop()                     
 {

    errore 0;
    tempo 1000;
    cleanOut();
    crea_sequenza();
    int val readButton();
    while (val == -1)
        val readButton();
    while (errore == && i<MAX)
    {   
        
        esegui_sequenza(i);
        errore leggi_sequenza(i);
        if (errore == 1
        {
            0;
            segnala_errore();
        }
        else 
        {
            i++;
            delay(1000);
            tempo -= 40;
        }
    }
    if (i==MAX)
        segnala_vittoria();
 }