Memory game with the Arduino

FunduinoLast updated on

Farbfolgen merken und nachspielen

Vier farbige LEDs leuchten in zufälliger Reihenfolge auf, und du musst diese Reihenfolge über vier Taster wiederholen. Mit jeder bestandenen Runde kommt eine Farbe dazu.

Das Projekt ist ein guter Einstieg in Arrays: Die gewürfelte Farbfolge und deine Eingabe werden in zwei Zahlenreihen gespeichert und anschließend verglichen. Der Sketch erklärt das Schritt für Schritt am Bild eines Regals mit nummerierten Fächern.

Alle Bauteile stecken in den Lernsets von Funduino.

Steckbrettaufbau des Farbmemory mit sieben LEDs und fünf Tastern
Der Aufbau auf dem Steckbrett

Die Aufgabe

Vier farbige LEDs leuchten in zufälliger Reihenfolge auf, und du musst diese Reihenfolge über vier Taster wiederholen. Stimmt alles, wird die Folge eine Farbe länger.

Weiße LEDs geben den Takt vor: Sie leuchten, wenn das Spiel startet, wenn du mit der Eingabe beginnen darfst und wenn deine Eingabe ausgewertet wird. Schaffst du Level 10, leuchten alle LEDs und das Spiel beginnt von vorn. Machst du einen Fehler, blinken die weißen LEDs fünfmal.

Benötigtes Material

  • Arduino UNO und Steckbrett
  • LEDs: je 1x rot, gelb, grün und blau sowie 3x weiß
  • Widerstände: 2x 200 Ohm, 5x 100 Ohm, 5x 1000 Ohm
  • Fünf Taster
  • Rund 21 Steckbrettkabel

Alles davon steckt in den Lernsets von Funduino.

Die Materialliste des Artikels enthält keinen einzigen Produktlink.

Aufbau und Pinbelegung

  • Pin 2 – weiße LEDs
  • Pin 3 – blaue LED, Pin 4 – blauer Taster
  • Pin 5 – grüne LED, Pin 6 – grüner Taster
  • Pin 7 – gelbe LED, Pin 8 – gelber Taster
  • Pin 9 – rote LED, Pin 10 – roter Taster
  • Pin 11 – Start-Taster
Steckbrettaufbau des Farbmemory mit sieben LEDs und fünf Tastern
Der Aufbau auf dem Steckbrett

Das Programm

Das Programm ist in vier Funktionen aufgeteilt: RandomArray() würfelt die Farbfolge aus, Random() spielt sie ab, PlayerInput() nimmt deine Eingabe entgegen und WinCondition() vergleicht beides.

Die Farbfolge wird als Array gespeichert – der Sketch erklärt das ausführlich am Bild eines Regals mit nummerierten Fächern.

Die vier Funktionen rufen sich gegenseitig auf, ohne je zurückzukehren: Random() ruft PlayerInput(), PlayerInput() ruft WinCondition(), WinCondition() ruft wieder Random(). Der Stack wächst mit jeder Runde. Auf einem UNO mit 2 KB Arbeitsspeicher endet das nach genügend Runden im Absturz. Die Kommentare im Sketch behaupten das Gegenteil.

Das komplette Farbmemory
//Teilt den Namen der LEDs jeweils eine Zahl/Pin zu.
int LEDweis = 2;
int LEDblau = 3;
int LEDgruen = 5;
int LEDgelb = 7;
int LEDrot = 9;
//Teilt den Namen der Taster jeweils eine Zahl/Pin zu.
int TASTERblau = 4;
int TASTERgruen = 6;
int TASTERgelb = 8;
int TASTERrot = 10;
int TASTERstart = 11;
//Speichert ob ein Taster ein- oder ausgeschaltet ist.
int STATUSblau = 0;
int STATUSgruen = 0;
int STATUSgelb = 0;
int STATUSrot = 0;
int STATUSstart = 0;
int iNumber = 0;  //Platzhaltter für eine Zahl.
int iLevel = 3;   //Speichert welches Level abgespielt werden soll.
int iLEDs[] = {3, 5, 7, 9};   //Speichert die von LEDs belegten Pins.
/*
 int iLEDs[] erstellt ein Regal in dem Daten vom Typ int(Zahlen) gespeichet werden können.
 Die leehre Klammer [] gibt dabei an, dass die größe des Regals noch nicht festgelegt ist.
 Der Teil {3, 5, 7, 9} erstellt jetzt jeweils ein Fach für die Nummer 3, 5, 7 und 9.
 Die Fächer werden in der Reihenfolge ihrer erstellung nummeriert beginnent mit der Ziffer 0.
 Im Fach0 wäre also die Nummer 3, im Fach1 die Nummer 5, im Fach2 die Nummer 7 und so weiter.
*/
int iRandom[10];    //Speichert die zufällig generierte Farbfolge.
int iPlayer[10];    //Speichert die vom Spieler eingegebene Farbfolge.
/*
 int iRandom[10] erstellt ein Regal in dem Daten vom Typ int(Zahlen) gespeichert werden können.
 Die [10] gibt an, dass das Regal 10 Fächer hat, die mit den Ziffern von 0 bis 9 markiert sind.
 Da keine weiteren Daten angegeben sind bleiben diese Fächer zunächst leehr.
*/
void setup() {
  //Gibt die LED Pins als ausgabe Pins an. Hier müssen Signale ausgegeben werden.
  pinMode(LEDweis, OUTPUT);
  pinMode(LEDblau, OUTPUT);
  pinMode(LEDgruen, OUTPUT);
  pinMode(LEDgelb, OUTPUT);
  pinMode(LEDrot, OUTPUT);
  //Gibt die Taster Pins als eingabe Pins an. Hier müssen Siegnale emfangen werden.
  pinMode(TASTERblau, INPUT);
  pinMode(TASTERgruen, INPUT);
  pinMode(TASTERgelb, INPUT);
  pinMode(TASTERrot, INPUT);
  pinMode(TASTERstart, INPUT);
  RandomArray();    //Springt in die Methode RandomArray(), zur Erstellung der Farbfolge, und kehrt nach dessen Durchlauf hierhin zurück.
}
void loop()   //Diese Methode wiederholt den Code bis eine andere Methode aufgerufen wird.
{
  STATUSstart = digitalRead(TASTERstart);   //Überprüft ob die Starttaste ein- oder ausgeschaltet ist.
  if (STATUSstart == HIGH)    //Der Code wird nur ausgeführt wenn die Starttaste gedrückt wird.
  {
    digitalWrite(LEDweis, HIGH);    //Schaltet die weißen LEDs ein.
    delay(500);   //Wartet 500ms.
    digitalWrite(LEDweis, LOW);   //Schalted die weißen LEDs aus.
    delay(500);   //Wartet 500ms.
    Random();   //Springt in die Methode Random(),um die Farfolge ab zu spielen, und kehrt nach dessen Durchlauf hierhin zurück.
  }
}
void RandomArray()    //Generiert eine zufällige Reienfolge der von LEDs belegten Pins die dann von anderen Methoden verwendet werden kann.
{
  randomSeed(analogRead(0));    //Versucht einen Wert von einem nicht belegten Pin auszulesen um eine zufällige Startposition für die random Funktion zu generieren.
  for (int i = 0; i < 10; i++)    //Wiederholt den Code bis i = 10 ist und erhöt i um 1 nach jedem Durchlauf.
  {
    iNumber = random(4);    //Generiert eine 'zufällige' Zahl von 0 bis 3.
    iRandom[i] = iLEDs[iNumber];    //Benutzt die Zufallszahl um ein Fach aus dem iLEDs Array zu wählen und packt dessen Inhalt in das i-te Fach im iRandom Array.
  }
}
void Random()   //Spielt die zufällig generierte LED Farbfolge ab.
{
  for (int i = 0; i < iLevel; i++)    //Wiederholt den Code bis i = iLevel ist und erhöt i um 1 nach jedem Durchlauf.
  {
    digitalWrite(iRandom[i], HIGH);   //Schaltet die im i-ten Fach des iRandom Array gespeicherte LED ein.
    delay(500);   //Wartet 500ms.
    digitalWrite(iRandom[i], LOW);    //Schalted die im i-ten Fach des iRandom Array gespeicherte LED aus.
    delay(500);   //Wartet 500ms.
  }
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, HIGH);    //Schaltet die weiße LED ein.
  delay(300);   //Wartet 300ms.
  digitalWrite(LEDweis, LOW);   //Schaltet die weiße LED aus.
  delay(500);   //Wartet 500ms.
  PlayerInput();
  /*
   Startet die Methode PlayerInput(), und verhindert zugleich den volständigen durlauf der Random() Methode.
   Erst nach Durchlauf der PlayerInput() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von Random().
   Nach vollendung von Random() springt das Programm zurück in die Metode loop().
  */
}
void PlayerInput()    //Speichert die vom Spieler eingegebene Farbfolge.
{
  for (int i = 0; i < iLevel;)    //Wiederholt den Code bis i = iLevel ist.
  {
    while(digitalRead(4) != HIGH && digitalRead(6) != HIGH && digitalRead(8) != HIGH && digitalRead(10) != HIGH)    //Wartet so lange wie keine Tasten gedrückt werden.
    {
      //do Nothing;
    }
    //Überprüft ob die Taster ein- oder ausgeschaltet sind.
    STATUSblau = digitalRead(TASTERblau);
    STATUSgruen = digitalRead(TASTERgruen);
    STATUSgelb = digitalRead(TASTERgelb);
    STATUSrot = digitalRead(TASTERrot);
    if (STATUSblau == HIGH)   //Der Code wir nur nach druck des blauen Tasters ausgeführt.
    {
      digitalWrite(LEDblau, HIGH);    //Schaltet die blaue LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDblau, LOW);   //Schalted die blaue LED aus.
      iPlayer[i] = 3;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    if (STATUSgruen == HIGH)    //Der Code wir nur nach druck des grünen Tasters ausgeführt.
    {
      digitalWrite(LEDgruen, HIGH);   //Schaltet die grüne LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDgruen, LOW);    //Schalted die grüne LED aus.
      iPlayer[i] = 5;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    if (STATUSgelb == HIGH)   //Der Code wir nur nach druck des gelben Tasters ausgeführt.
    {
      digitalWrite(LEDgelb, HIGH);    //Schaltet die gelbe LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDgelb, LOW);   //Schalted die gelbe LED aus.
      iPlayer[i] = 7;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    if (STATUSrot == HIGH)    //Der Code wir nur nach druck des roten Tasters ausgeführt.
    {
      digitalWrite(LEDrot, HIGH);   //Schaltet die rote LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDrot, LOW);    //Schalted die rote LED aus.
      iPlayer[i] = 9;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
  }
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, HIGH);    //Schaltet die weiße LED ein.
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, LOW);   //Schaltet die weiße LED aus.
  delay(500);   //Wartet 500ms.
  WinCondition();
  /*
   Startet die Methode WinCondition(), und verhindert zugleich den volständigen durlauf der PlayerInput() Methode.
   Erst nach Durchlauf der WinCondition() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von PlayerInput().
   Nach vollendung von PlayerInput() springt das Programm zurück in die Metode Random().
  */
}
void WinCondition()   //Überprüft ob der spieler die richtige Farbfolge eingegeben hat und zum nächsten Level übergeht.
{
  for (int i = 0; i < iLevel; i++)    // Wiederholt den Code bis i = iLevel und erhöt i um 1 nach jedem Durchlauf.
  {
    if (iRandom[i] == iPlayer[i])   //Der Code wird nur ausgeführt wenn, das mit i makierte Fach im iRandom[10] Regal und das mit i makierte Fach im iPlayer[10] Regal, den gleichen Inhalt haben.
    {
      //do nothing
    }
    else    //Der Code wird nur ausgeführt wenn die vorherige if-Bedingung nicht zutraf.
    {
      for (int j = 0; j < 5; j++)   //Wiederholt den Code bis j = 5 und erhöt j um 1 nach jedem Durchlauf.
      {
        delay(500);   //Wartet 500ms.
        digitalWrite(LEDweis, HIGH);    //Schaltet die Weißen LEDs ein.
        delay(500);   //Wartet 500ms.
        digitalWrite(LEDweis, LOW);   //Schaltet die weißen LEDs aus.
      }
      RandomArray();    //Startet die Methode RandomArray().
      iLevel = 3;   //Sezt das Level auf 3 zurück.
      return;   //Verlässt die WinCondition() Methode und kehrt zur PlayerInput() Methode zurück.
    }
  }
  if (iLevel < 10)    //Der Code wird nur ausgeführt wenn iLevel kleiner als 10 ist.
  {
    iLevel++;   //Erhöt iLevel um 1.
  }
  else if (iLevel == 10)    //Der Code wird nur ausgeführt wenn die forherige if-Bedingung nicht zutraf und iLevel = 10 ist.
  {
    digitalWrite(LEDweis, HIGH);    //Schaltet die weißen LEDs ein.
    for(int n = 0; n < 5; n++)  //Widerholt den Code bis n = 5 ist und erhöt n um 1 nach jedem Durchlauf.
    {
      digitalWrite(LEDgruen, LOW);    //Schaltet die grüne LED aus.
      digitalWrite(LEDrot, HIGH);   //Schaltet die rote LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDblau, LOW);   //Schaltet die blaue LED aus.
      digitalWrite(LEDgelb, HIGH);    //Schaltet die gelbe LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDrot, LOW);    //Schaltet die rote LED aus.
      digitalWrite(LEDgruen, HIGH);   //Schaltet die grüne LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDgelb, LOW);   //Schaltet die gelbe LED aus.
      digitalWrite(LEDblau, HIGH);    //Schaltet die blaue LED ein.
      delay(300);   //Wartet 300ms.
    }
    digitalWrite(LEDgruen, LOW);    //Schaltet die grüne LED aus.
    delay(300);   //Wartet 300ms.
    digitalWrite(LEDblau, LOW);   //Schaltet die blaur LED aus.
    digitalWrite(LEDweis, LOW);   //Schaltet die weißen LEDs aus.
    iLevel = 3;   //Sezt das Level auf 3 zurück.
    RandomArray();    //Startet die Methode RandomArray() und kehrt nach dessen Durchlauf hierhin zurück.
    return;   //Verlässt die WinCondition() Methode und kehrt zur PlayerInput() Methode zurück.
  }
  Random();
  /*
   Startet die Methode Random(), und verhindert zugleich den volständigen durlauf der WinCondition() Methode.
   Erst nach Durchlauf der Random() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von WinCondition().
   Nach vollendung von Wincondition() springt das Programm zurück in die Metode PlayerInput().
  */
}
Rate the instructions

Comments

Ask a question or share an experience

Contact us if something doesn’t work. Please include your board and the error message.

We review every comment before publication. Your email address remains with us.