Vergleich einer zufälligen Zahlenfolge

Guten Abend liebe Programmierbegeisterte,

ich habe mich seit neuestem entschlossen mit dem Arduino-Board ein wenig herumzuexperimentieren, weil es einfach immensen Spaß macht sich spezifische Dinge auszudenken und zum laufen zu bringen. :smiley:

Mein erstes Projekt besteht aus einem Joystick, ein paar LED's und einem Knopf. Die vorhandenen LED's sind zu einem Kreuz geformt und wenn ich den Joystick nach oben kippe, leuchtet die obere LED, bei Ausschlag nach unten die Untere, bei Druck auf dem Knopf die Mittlere usw...
Das funktioniert soweit auch alles tadellos, nun kommen wir aber zu meinem Problem:

Das Ganze soll nämlich eine Art Minispiel werden. Zu Beginn des Programms leuchten 6 LED's nacheinander willkürlich auf und das Ziel ist es, die Reihenfolge danach mit dem Joystick nachzumachen. Bei Erfolg, soll eine grüne LED dies signalisieren und bei Misserfolg eine Rote. Mit dem Knopf kann man das Spiel resetten, falls man gar nicht mehr weiter kommt o.Ä.

Also das zufällige aufleuchten der LED's habe ich mittels random(); und randomSeed(); realisieren können. Auch die Funktion des Knopfes ist gegeben.

Mein Problem ist das Vergleichen der (zufälligen) vorgegebenen Reihenfolge mit dem was man manuell mit dem Joystick macht. Ich komme absolut nicht mehr weiter. Ich habe es mit if-Schleifen probiert, mit switchcase-Schleifen. Mein Resultat des Ganzen ist, dass es so evtl. auch gehen könnte, man aber ENORM viel Code schreiben müsste, was ich auch angefangen hatte. Bin aber währenddessen immer wieder auf neue Probleme gestoßen, die mich dann zu dem Entschluss geleitet haben, dass das definitiv einfacher gehen muss.

Und ich bitte euch, mir Lösungsansätze zu geben! Ich bin ein absoluter Neuling und habe auch durch Recherche in Foren nicht allzu viel Nützliches in Erfahrung bringen können.

Danke im voraus! :slight_smile:

Rooproop:
Mein Problem ist das Vergleichen der (zufälligen) vorgegebenen Reihenfolge mit dem was man manuell mit dem Joystick macht. Ich komme absolut nicht mehr weiter. Ich habe es mit if-Schleifen probiert, mit switchcase-Schleifen. Mein Resultat des Ganzen ist, dass es so evtl. auch gehen könnte, man aber ENORM viel Code schreiben müsste, was ich auch angefangen hatte. Bin aber währenddessen immer wieder auf neue Probleme gestoßen, die mich dann zu dem Entschluss geleitet haben, dass das definitiv einfacher gehen muss.

Ein Spiel hat immer einen Algorithmus, und den musst Du zuerst in eine geeignete Datensttruktur bringen, um dafür ein Programm zu schreiben.

Deine Minispiel-Beschreibung hört sich ähnlichwie ein vereinfachtes "Senso" (engl. "Simon Says") Spiel der achtachtziger Jahre des letzten Jahrhunderts an: Der Computer hat vier Schaltflächen in vier Farben, und beim Aktivieren jeder Farbfläche wird ein kurzer Ton unterschiedlicher Tonhöhe abgespielt.

Der Spielecomputer gibt dabei eine ständig länger werdende Folge aus Farbe/Ton vor, die der Spieler nachspielen muss.

Du brauchst nun einfach zwei Byte-Arrays, von denen eines die zuletzt vom Computer generierte Zufallsfolge enthält, z.B:

byte randPlay[6]= {1, 2, 2, 5, 3, 1}; / speichert 6 Bytes in gegebener Reihenfolge (random)
und ein gleichgroßes Array, das die Züge des Spielers aufnimmt:
byte stickPlay[6]= {1, 2, 2, 5, 3, 2}; // speichert die 6 Bytes, die der Spieler nacheinander eingibt

Immer wenn der Computer am Zug ist, generierst Du dasrandPlay[] Array
Und wenn der Spieler am Zug ist, füllst Du je nach Joystickbewegungen und Knopfdrücken das stickPlay-Array und vergleichst am Ende der Spielerzugeingabe beide Arrays, z.B. mit der Standardfunktion memcmp

Willkommen im Forum.

So ganz spontan ohne komplizierten Code fällt mir folgendes dazu ein: Die zufällige Reihenfolge der LEDs speicherst du in einem aussreichend großen Byte-Array mit betreffenden Kennwerten je LED. Mit dem Joystick machst du das gleiche in einem zweiten Byte-Array, ebenfalls vergleichbare und passende Werte. Danach brauchst du nur noch per For-Schleife jedes Byte des einen mit jedem Byte des anderen Arrays vergleichen und bekommst die Auswertung; passt alles: Grün, sind Fehler vorhanden: Rot. Ist halt nur 'ne spontane Idee die sich vielleicht ausbauen lässt.

Gruß, Rudi

PS:
Toll, Jurs war schneller :smiley:
Liefert aber eine vergleichbare Lösung

Nimm n Array, wode die Folge abspeicherst.
Schau mal hier:

https://www.arduino.cc/en/Reference/Array

Die reference-Seite mal bookmarken. Is sehr nützlich für Neueinsteiger.

for (int i=0; i<minLeds+runde; i++) feld = random(4);
füllt dir bleistiftsweise zu jeder runde das Array feld[] mit 6+runde Zahlen von 0-3
musst natürlich die Variable vorher entsprechend deklarieren.
z.B. int feld[maxRunden+6];
Werte die sich nicht ändern vorher ganz oben im Code als Konstanten deklarieren.
Da findeste se immer wieder, kannstse bei Bedarf schnell ändern und im Code benutzt du aussagekräftige Bezeichnungen.
z.B.
const int minLeds = 6;
const maxLeds = 50;
...
Beipiel feld = (1,0,3,0,2,1,3,0,2,1)
feld[0] wäre dann 1
feld[4] wäre dann 2 (also der 5te Wert)
Daran denken, daß in der Informatik immer ab 0 gezählt wird.
Danach die Joystickbewegung (0,1,2,3 = hoch, runter, rechts, links) mit feld[nummer] vergleichen.
Wenn ok dann nummer++; (kurzform für nummer=nummer+1)
nummer ist der Zähler welche feld[nummer] gerade dran ist.
Sobald nummer == minLeds+runde -> dann runde beendet -> nächte runde
runde++;
Danach is eine Led mehr zu merken.
feld[] neu befüllen.
Das Ganze von vorne.
Knopp lang drücken setzt runde=0
Knopp kurz drücken wiederholt runde.
:slight_smile:
[edit] Da war der Rudi schneller :slight_smile:
und ein byte reicht natürlich auch für die Zahlen 0-4.

Danke für die überaus schnellen Antworten!
Ihr seid eine super Community, hätte nicht erwartet, dass so schnell so hilfreiche Antworten kommen :DD

Auf jeden Fall hat alles super funktioniert! Ich habe den vorgeschlagenen memcmp-Befehl verwendet und er funktioniert tadelos. Auch die Idee von panpira fand ich super und habe sie mit in mein Programm eingebaut (:

Nachfolgend möchte ich nochmal meinen gesamten Programmcode hier posten. Eventuell hat jemand Lust sich das ein wenig genauer anzuschauen und mir Verbesserungstipps dazu zu geben.

int yAchse = 1;
int xAchse = 0;
int zAchse = 7;
int ledR = 2;
int ledO = 3;
int ledL = 4;
int ledU = 5; 
int ledM = 6;
int valX = 0;
int valY = 0;
int valZ = 0;
long randNumber;
int state = 0;
byte generiert[10];
byte eingabe[10];
int rWert;
int index = 0;
int buttonStateZ_HIGH = 0;
int buttonStateYl_HIGH = 0;
int buttonStateYr_HIGH = 0;
int buttonStateXu_HIGH = 0;
int buttonStateXo_HIGH = 0;
int durchlauf = 1;

void setup() {
  pinMode(zAchse, OUTPUT);
  pinMode(ledR, OUTPUT);
  pinMode(ledO, OUTPUT);
  pinMode(ledL, OUTPUT);
  pinMode(ledU, OUTPUT);
  pinMode(ledM, OUTPUT);
  pinMode(8, INPUT);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);

  digitalWrite(ledR,LOW);
  digitalWrite(ledO,LOW);
  digitalWrite(ledL,LOW);
  digitalWrite(ledU,LOW);
  digitalWrite(ledM,LOW);
  digitalWrite (8, HIGH);
  digitalWrite(13,LOW);
  digitalWrite(12,LOW);
  randomSeed(analogRead(0));
  Serial.begin(9600);

}

void loop() {
  
  digitalWrite(ledR,LOW);
  digitalWrite(ledO,LOW);
  digitalWrite(ledL,LOW);
  digitalWrite(ledU,LOW);
  digitalWrite(ledM,LOW);
  digitalWrite(13,LOW);
  digitalWrite(12,LOW);
  
  Zufallsgenerator();
  Steuerung();
  //Anzeige();


}

/*void Anzeige()
{

  Serial.print("X:");
  Serial.print(valX, DEC);

 
  Serial.print(" | Y:");
  Serial.print(valY, DEC);

  
  Serial.print(" | Z: ");
  Serial.println(valZ, DEC);

  delay(100);
}*/

void Steuerung()
{
 
for (int x = 7; x > 6; x++)
{

  state = digitalRead(8);
  valX = analogRead(xAchse);
  valY = analogRead(yAchse);
  valZ = digitalRead(zAchse);
    
  if (valZ == 1)
  {
    digitalWrite (ledM, HIGH);
  }

  else
  {
    digitalWrite (ledM, LOW);
  }
  if (valY > 750)
  {
    digitalWrite (ledL, HIGH);
  }

  else
  {
    digitalWrite (ledL, LOW);
  }

  if (valY > 250)
  {
    digitalWrite (ledR, LOW);
  }

  else
  {
    digitalWrite (ledR, HIGH);
  }

    if (valX > 750)
  {
    digitalWrite (ledU, HIGH);
  }

  else
  {
    digitalWrite (ledU, LOW);
  }

  if (valX > 250)
  {
    digitalWrite (ledO, LOW);
  }

  else
  {
    digitalWrite (ledO, HIGH);
  }

  if(state == LOW)
  {
    index = 0;
    durchlauf = 1;
    break;
  }
   
   ZaehlfunktionM();
   ZaehlfunktionL();
   ZaehlfunktionR();
   ZaehlfunktionU();
   ZaehlfunktionO();


  if (index == durchlauf)
  {
    rWert = memcmp(generiert, eingabe, durchlauf);
    if (rWert == 0)
    {
    digitalWrite(13,HIGH);
    delay(2000);
    digitalWrite(13, LOW);
    durchlauf++;
    index = 0;
    break;
    }
    if (rWert != 0)
    {
    digitalWrite(12, HIGH);
    delay (2000);
    digitalWrite(12,LOW);
    index = 0;
    //break;
    }
  }
}
}

void Zufallsgenerator()
{
  for (int i = 0; i < durchlauf; i++)
{
  randNumber = random(2, 7);
  generiert[i] = randNumber;
  Serial.println(randNumber);
  digitalWrite(randNumber, HIGH);
  delay(500);
  digitalWrite(randNumber, LOW);
  delay(500);
}
}

void ZaehlfunktionM()
{
 valZ = digitalRead(zAchse);
 
 if (valZ == HIGH)
 {    
   buttonStateZ_HIGH = 1;
 }
 if (valZ == LOW && buttonStateZ_HIGH == 1)
 {
   eingabe[index] = 6;
   index++;
   buttonStateZ_HIGH = 0;
 }
 //Serial.println(index);
}

void ZaehlfunktionL()
{
 valY = analogRead(yAchse);
 
 if (valY > 750)
 {    
   buttonStateYl_HIGH = 1;
 }
 if (valY < 750 && buttonStateYl_HIGH == 1)
 {
   eingabe[index] = 4;
   index++;
   buttonStateYl_HIGH = 0;
 }
 //Serial.println(index);
}

void ZaehlfunktionR()
{
 valY = analogRead(yAchse);
 
 if (valY < 250)
 {    
   buttonStateYr_HIGH = 1;
 }
 if (valY > 250 && buttonStateYr_HIGH == 1)
 {
   eingabe[index] = 2;
   index++;
   buttonStateYr_HIGH = 0;
 }
 //Serial.println(index);
}

void ZaehlfunktionU()
{
 valX = analogRead(xAchse);
 
 if (valX > 750)
 {    
   buttonStateXu_HIGH = 1;
 }
 if (valX < 750 && buttonStateXu_HIGH == 1)
 {
   eingabe[index] = 5;
   index++;
   buttonStateXu_HIGH = 0;
 }
 //Serial.println(index);
}

void ZaehlfunktionO()
{
 valX = analogRead(xAchse);
 
 if (valX < 250)
 {    
   buttonStateXo_HIGH = 1;
 }
 if (valX > 250 && buttonStateXo_HIGH == 1)
 {
   eingabe[index] = 3;
   index++;
   buttonStateXo_HIGH = 0;
 }
 //Serial.println(index);
}

Der Code darf ebenfalls gerne von Anderen weiter verwendet werden, wenn Bedarf besteht! Bei Fragen könnt ihr euch auch gerne an mich wenden um genauere Informationen zu bekommen. Ich habe leider keine Kommentare geschrieben...

Du kannst dir das Speichern sparen. Wenn du die Zufallszahlenfolge ein zweites mal mit dem gleichen Seed startest, erhälst du die gleiche Folge noch einmal