# Simple Simon Game on Arduino

When I was a child, in 1980, I spent some time playing a fun game that asked me to watch, remember and repeat a random sequence proposed from time to time by the microcontroller in a challenge that was inexorably won by the machine! The game was invented in 1978 and was called Simon; today I read his story on Wikipedia: https://en.wikipedia.org/wiki/Simon_(game).The device creates a series of tones and lights and requires a user to repeat the sequence. If the user succeeds, the series becomes progressively longer and more complex. Once the user fails or the time limit runs out, the game is over. Here I propose a simple realization with Arduino uno that you can simulate in https://www.tinkercad.com/things/jKi6DJadMBu or realize in practice with four LEDs and four buttons, plus one for the reset of the game.

Below is the circuit and the sketch made with the students of 3AO Electronics of the school year 2020/21 at IIS Maxwell, Milan.

```/*
V1.0 - Spadaro Filippo 28 may 2021

btnNONE: nessun pulsante premuto
btnGREEN: stampa btnGREEN
btnYELLOW: stampa btnYELLOW
btnRED:   btnRED
btnBLUE: btnBLUE
btnSELECT: stampa SELECT
*/

#define btnGREEN    2
#define btnYELLOW 3
#define btnRED    4
#define btnBLUE     5
#define btnSELECT   1
#define btnNONE     0

#define pinLEDGREEN   2
#define pinLEDYELLOW  3
#define pinLEDRED     4
#define pinLEDBLUE    5

// define the button debounce
int lcd_key = btnNONE;
int lcd_key_precedente = btnNONE;
int adc_key_in  = 0;

// game variables
int sequenza[20];
int fineSequenza = 0, i, pulsantePremuto, contaPulsante;
bool indovinaSequenza = false;

// random sequence
void generaSequenza(int inizio, int fine) {
for (i=0; i<20; i++)
{
sequenza[i]=random(inizio,fine+1);
Serial.print(sequenza[i]);
Serial.print(" ");
}
Serial.println();
}

// print sequence
void stampaSequenza(int inizio, int fine) {
for (i=inizio; i<fine; i++) {
digitalWrite(sequenza[i],HIGH);
delay(500);
digitalWrite(sequenza[i],LOW);
delay(500);
}
}

// light only one LED
void illuminaUnLed(int LED1Illuminato, int LED2Spento, int LED3Spento, int LED4Spento)
{
digitalWrite(LED1Illuminato,HIGH);
digitalWrite(LED2Spento,LOW);
digitalWrite(LED3Spento,LOW);
digitalWrite(LED4Spento,LOW);
delay(300);
digitalWrite(LED1Illuminato,LOW);
digitalWrite(LED2Spento,LOW);
digitalWrite(LED3Spento,LOW);
digitalWrite(LED4Spento,LOW);
delay(300);
}

// light all LED
void illuminaTuttiLed(int LED1Illuminato, int LED2Illuminato, int LED3Illuminato, int LED4Illuminato)
{
digitalWrite(LED1Illuminato,HIGH);
digitalWrite(LED2Illuminato,HIGH);
digitalWrite(LED3Illuminato,HIGH);
digitalWrite(LED4Illuminato,HIGH);
delay(300);
digitalWrite(LED1Illuminato,LOW);
digitalWrite(LED2Illuminato,LOW);
digitalWrite(LED3Illuminato,LOW);
digitalWrite(LED4Illuminato,LOW);
delay(300);
}

void giocoDiLuciAccensione(int LED1, int LED2, int LED3, int LED4)
{
digitalWrite(LED1,HIGH);
delay(200);
digitalWrite(LED1,LOW);
digitalWrite(LED2,HIGH);
delay(200);
digitalWrite(LED2,LOW);
digitalWrite(LED3,HIGH);
delay(200);
digitalWrite(LED3,LOW);
digitalWrite(LED4,HIGH);
delay(200);
digitalWrite(LED4,LOW);
delay(200);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
digitalWrite(LED3,HIGH);
digitalWrite(LED4,HIGH);
delay(200);
digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
digitalWrite(LED4,LOW);
delay(200);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
digitalWrite(LED3,HIGH);
digitalWrite(LED4,HIGH);
delay(200);
digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
digitalWrite(LED4,LOW);
delay(2000);
}

// read the button value
{
// Serial.println(adc_key_in);     // per il debug
/* Resistori tra 5V e 0V: 2.2k - 1k - 1k - 1k - 2.2k */
if (adc_key_in > 1000) return btnNONE; // 1023 if (adc_key_in < 50) return btnGREEN; // 0 if (adc_key_in < 350) return btnYELLOW; // 320 if (adc_key_in < 500) return btnRED; // 487 if (adc_key_in < 650) return btnBLUE; // 590 if (adc_key_in < 800) return btnSELECT; // 719
return btnNONE;
}

void setup()
{
Serial.begin(9600);
Serial.println("Push start button");   // display "Push the buttons"
pinMode(pinLEDGREEN,OUTPUT);
pinMode(pinLEDYELLOW,OUTPUT);
pinMode(pinLEDRED,OUTPUT);
pinMode(pinLEDBLUE,OUTPUT);
}

void loop()
{
lcd_key = read_LCD_buttons();    // lettura pulsanti
// Serial.println(lcd_key);      // per il debug
if ((lcd_key != btnNONE) && (lcd_key_precedente == btnNONE))    // Anti-rimbalzo
{
// A seconda del pulsante premuto, esegue un'azione
switch (lcd_key)
{
case btnGREEN:
{
illuminaUnLed(pinLEDGREEN, pinLEDYELLOW, pinLEDRED, pinLEDBLUE);
pulsantePremuto= btnGREEN;
delay(200);

if (sequenza[contaPulsante]==pulsantePremuto) {
if (indovinaSequenza==true) {
if (contaPulsante<fineSequenza-1) {
contaPulsante++;
}
else {
fineSequenza++;
stampaSequenza(0, fineSequenza);
contaPulsante = 0;
}
}
else {
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}
}
else {
indovinaSequenza = false;
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}

break;
}
case btnYELLOW:
{
illuminaUnLed(pinLEDYELLOW, pinLEDGREEN, pinLEDRED, pinLEDBLUE);
pulsantePremuto= btnYELLOW;
delay(200);

if (sequenza[contaPulsante]==pulsantePremuto) {
if (indovinaSequenza==true) {
if (contaPulsante<fineSequenza-1) {
contaPulsante++;
}
else {
fineSequenza++;
stampaSequenza(0, fineSequenza);
contaPulsante = 0;
}
}
else {
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}
}
else {
indovinaSequenza = false;
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}

break;
}
case btnRED:
{
illuminaUnLed(pinLEDRED, pinLEDYELLOW, pinLEDGREEN, pinLEDBLUE);
pulsantePremuto= btnRED;
delay(200);

if (sequenza[contaPulsante]==pulsantePremuto) {
if (indovinaSequenza==true) {
if (contaPulsante<fineSequenza-1) {
contaPulsante++;
}
else {
fineSequenza++;
stampaSequenza(0, fineSequenza);
contaPulsante = 0;
}
}
else {
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}
}
else {
indovinaSequenza = false;
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}

break;
}
case btnBLUE:
{
illuminaUnLed(pinLEDBLUE, pinLEDYELLOW, pinLEDGREEN, pinLEDRED);
pulsantePremuto= btnBLUE;
delay(200);

if (sequenza[contaPulsante]==pulsantePremuto) {
if (indovinaSequenza==true) {
if (contaPulsante<fineSequenza-1) {
contaPulsante++;
}
else {
fineSequenza++;
stampaSequenza(0, fineSequenza);
contaPulsante = 0;
}
}
else {
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}
}
else {
indovinaSequenza = false;
illuminaTuttiLed(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);
}

break;
}
case btnSELECT:
{
giocoDiLuciAccensione(pinLEDBLUE, pinLEDRED, pinLEDYELLOW, pinLEDGREEN);

generaSequenza(pinLEDGREEN, pinLEDBLUE);
indovinaSequenza = true;
fineSequenza = 1;
stampaSequenza(0, fineSequenza);
contaPulsante = 0;

break;
}

case btnNONE:
{
// nulla da eseguire
break;
}
}
}
lcd_key_precedente = lcd_key;
delay(50);
}
```

In the realization of the game input, I propose to acquire the signal of the chosen button by using a single analog pin instead of using 5 digital pins, one for each button. In this way I save 5 Arduino digital pins against an alalogic one. The LEDs, on the other hand, are connected to the digital pins. To read the buttons I create a pull-up voltage divider with 5 resistors placed between 5V and 0: 2.2kOhm - 1kOhm - 1kOhm - 1kOhm - 2.2kOhm and acquire the voltage levels with analogRead() which change according to the button that is held down. The function that takes care of this is read_LCD_buttons() which returns the value of the pressed button, and the game is then handled by a switch-case.
A debounce algorithm (managed with the use of the two variables lcd_key and lcd_key_precedente) allows the correct reception of the button chosen by the player: you can see it at the beginning and at the end of the loop().