Igra u kojoj se nasumično uključuju i isključuju LED, a korisnik mora ponoviti redoslijed kojim su se uključivale. Redoslijed paljenja bira se preko potenciometra za označavanje željene LED i tipkala za potvrdu odabira. Povratne informacije o igri (poraz/nova razina/pobjeda) su napravljene uz pomoć prikladnih svjetlosnih i zvučnih efekata.

Dependencies:   mbed zvucniEfekti

https://os.mbed.com/media/uploads/nikola_cancer/igra_memory.png

Files at this revision

API Documentation at this revision

Comitter:
nikola_cancer
Date:
Wed Dec 01 13:17:00 2021 +0000
Commit message:
v1

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
zvucniEfekti.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f1138da8bd35 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Dec 01 13:17:00 2021 +0000
@@ -0,0 +1,312 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2019 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "mbed.h"
+#include "zvucniEfekti.h"
+
+#define MAX_BROJ_SEKVENCE 10
+#define SAMPLEFREQ 8000
+
+InterruptIn tipkaloFlipLED(D12);
+DigitalOut ledZaProvjeru(D6);
+
+Ticker sampleRate;
+AnalogOut zvucnik(PA_5);
+AnalogIn potenciometar(A0);
+DigitalIn tipkalo(D9);
+
+int kontrolaZvuka; // globalna varijabla za odabir koji zvuk se pušta (u
+                   // funkciji sviraj) na piezo
+
+class Igra {
+private:
+  int brojLedica;
+  DigitalOut *ledice;
+  float vrijednostiZaPotenciometar[10];
+
+public:
+  Igra(DigitalOut *led, int brLED) {
+    ledice = led;
+    brojLedica = brLED;
+
+    float korak = 1. / brojLedica;
+    for (int i = 0; i < brojLedica + 1; i++) {
+      if (i == 0) {
+        vrijednostiZaPotenciometar[i] = 0;
+      } else {
+        vrijednostiZaPotenciometar[i] =
+            vrijednostiZaPotenciometar[i - 1] + korak;
+      }
+    }
+
+    tipkalo.mode(PullUp);
+
+    srand(time(0));
+  }
+
+  /*
+      globalna varijabla kontrolaZvuka:
+      0 -> gameStart
+      1 -> nextLevel
+      2 -> finalLevel
+      3 -> gameWon
+      4 -> gameOver
+  */
+  void sviraj() {
+    static int i = 0;
+
+    switch (kontrolaZvuka) {
+    case 0:
+      zvucnik.write_u16(zvukGameStart[i] << 8);
+      i++;
+      if (i == brojSamplovaZvukGameStart) {
+        i = 0;
+        zvucnik.write_u16(0);
+        sampleRate.detach();
+      }
+      break;
+
+    case 1:
+      zvucnik.write_u16(zvukNextLevel[i] << 8);
+      i++;
+      if (i == brojSamplovaZvukNextLevel) {
+        i = 0;
+        zvucnik.write_u16(0);
+        sampleRate.detach();
+      }
+      break;
+
+    case 2:
+      zvucnik.write_u16(zvukFinalLevel[i] << 8);
+      i++;
+      if (i == brojSamplovaZvukFinalLevel) {
+        i = 0;
+        zvucnik.write_u16(0);
+        sampleRate.detach();
+      }
+      break;
+
+    case 3:
+      zvucnik.write_u16(zvukGameWon[i] << 8);
+      i++;
+      if (i == brojSamplovaZvukGameWon) {
+        i = 0;
+        zvucnik.write_u16(0);
+        sampleRate.detach();
+      }
+      break;
+
+    case 4:
+      zvucnik.write_u16(zvukGameOver[i] << 8);
+      i++;
+      if (i == brojSamplovaZvukGameOver) {
+        i = 0;
+        zvucnik.write_u16(0);
+        sampleRate.detach();
+      }
+      break;
+    }
+  }
+
+  void generirajRandomSekvencu(int brojUzoraka, int *sekvenca) {
+    ugasiSveLED();
+    for (int i = 0; i < brojUzoraka; i++) {
+      int num = (rand() % brojLedica); // random broj između 0 i brLED
+      sekvenca[i] = num; // spremi u sekvencu zbog kasnije usporedbe generiranog
+      // i pogađanog
+
+      // upali i ugasi random LED
+      wait_ms(500);
+      ledice[num] = 1;
+      wait_ms(500);
+      ledice[num] = 0;
+      wait_ms(500);
+    }
+    wait(2);
+  }
+
+  void spremiUnosKorisnika(int brojUzoraka, int *sekvenca) {
+    for (int k = 0; k < brojUzoraka; k++) {
+      for (;;) {
+        for (int i = 0; i < brojLedica; i++) {
+          if (potenciometar >= vrijednostiZaPotenciometar[i] &&
+              potenciometar < vrijednostiZaPotenciometar[i + 1]) {
+            ledice[i] = 1;
+          } else {
+            ledice[i] = 0;
+          }
+        }
+
+        if (tipkalo == 0) {
+          wait_ms(50); // debounce
+          if (tipkalo == 0) {
+            for (int j = 0; j < brojLedica; j++) {
+              if (ledice[j].read() == 1) {
+                sekvenca[k] = j;
+
+                // da korisnih ima feedback da je ucitan njegov odabir
+                ledice[j] = 0;
+                wait_ms(500);
+                ledice[j] = 1;
+              }
+            }
+            // cekaj dok tipkalo ne ode u jedan (radi ko rising edge)
+            // da ove beskonacne petlje nema bi spremil 4x istu vrijednost u
+            // array (jer radi brzo)
+            do {
+            } while (tipkalo.read() == 0);
+            break;
+          }
+        }
+      }
+    }
+  }
+  /*
+      funkcija vraca 0 za razlicite arraye, a 1 za iste
+  */
+  int provjeriSekvence(int *generiranaSekvenca, int *unesenaSekvenca,
+                       int brojUzorakaSekvence) {
+    int i = 0;
+    for (i = 0; i < brojUzorakaSekvence; i++) {
+      if (generiranaSekvenca[i] != unesenaSekvenca[i]) {
+        return 0; // poraz
+      }
+    }
+    return 1; // sljedeca razina/pobjeda
+  }
+
+  void ugasiSveLED() {
+    for (int i = 0; i < brojLedica; i++) {
+      ledice[i] = 0;
+    }
+  }
+
+  void sljedecaRazina(int finalniLevel) {
+    ugasiSveLED();
+    if (finalniLevel != 0) {
+      kontrolaZvuka = 2;
+    } else {
+      kontrolaZvuka = 1;
+    }
+    sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
+    for (int i = 0; i < brojLedica; i++) {
+      ledice[i] = 1;
+      wait_us(100000);
+      ledice[i] = 0;
+    }
+    wait_us(100000);
+  }
+
+  void novaIgra() {
+    kontrolaZvuka = 0;
+    sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
+    wait(2);
+  }
+
+  void pobjeda() {
+    ugasiSveLED();
+    kontrolaZvuka = 3;
+    sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
+
+    // chaser effekt 5x sim tam
+    int i = 0;
+    do {
+
+      for (int j = 0; j < brojLedica; j++) {
+        ledice[j] = 1;
+        wait_us(60000);
+        ledice[j] = 0;
+      }
+
+      for (int j = brojLedica - 1; j >= 0;
+           j--) // -1 jer sizeof(arr) za arr[20] npr daje 20 a zadnji element je
+                // 19
+      {
+        ledice[j] = 1;
+        wait_us(60000);
+        ledice[j] = 0;
+      }
+
+      i++;
+    } while (i < 10);
+    wait(2);
+  }
+
+  void poraz() {
+    ugasiSveLED();
+    kontrolaZvuka = 4;
+    sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
+    int i = 0;
+    do {
+
+      for (int j = 0; j < brojLedica; j++) {
+        ledice[j] = 1;
+      }
+      wait_us(500000);
+
+      ugasiSveLED();
+      wait_us(500000);
+
+      i++;
+    } while (i < 3);
+    wait(2);
+  }
+};
+
+void flipLED() { ledZaProvjeru = !ledZaProvjeru; }
+
+int main() {
+  wait(1);
+  tipkaloFlipLED.mode(PullUp);
+  tipkaloFlipLED.rise(&flipLED);
+  // inicijalizacija pinova za igru
+  DigitalOut led[] = {D2, D4, D7, D8, D10, D11};
+  int brojLedica = sizeof(led) / sizeof(led[0]);
+
+  // spremanje generiranih i unesenih vrijednosti
+  int generiranaSekvenca[MAX_BROJ_SEKVENCE] = {0};
+  int unosKorisnika[MAX_BROJ_SEKVENCE] = {0};
+
+  // postavke i logika igre
+  int brojUzorakaSekvence = 3; // kolko puta se LED pale/gase
+  int pobjedaPorazZastavica;
+  int trenutniLevel = 0;
+  int finalniLevel = 2;
+
+  Igra igra(led, brojLedica);
+
+  while (true) {
+    if (trenutniLevel == 0) {
+      igra.novaIgra();
+    }
+    igra.generirajRandomSekvencu(brojUzorakaSekvence, generiranaSekvenca);
+    igra.spremiUnosKorisnika(brojUzorakaSekvence, unosKorisnika);
+    pobjedaPorazZastavica = igra.provjeriSekvence(
+        generiranaSekvenca, unosKorisnika, brojUzorakaSekvence);
+
+    switch (pobjedaPorazZastavica) {
+    case 0:
+      igra.poraz();
+      brojUzorakaSekvence = 3;
+      trenutniLevel = 0;
+      break;
+    case 1:
+      if (trenutniLevel == finalniLevel - 1) {
+        igra.sljedecaRazina(1); // 1 -> šalji zvuk finalLevel
+        brojUzorakaSekvence++;
+        trenutniLevel++;
+      } else if (trenutniLevel == finalniLevel) {
+        igra.pobjeda();
+        brojUzorakaSekvence = 3;
+        trenutniLevel = 0;
+      } else {
+        igra.sljedecaRazina(0); // 0 -> šalji zvuk nextLevel
+        brojUzorakaSekvence++;
+        trenutniLevel++;
+      }
+      break;
+    }
+  }
+}
diff -r 000000000000 -r f1138da8bd35 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Dec 01 13:17:00 2021 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file
diff -r 000000000000 -r f1138da8bd35 zvucniEfekti.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zvucniEfekti.lib	Wed Dec 01 13:17:00 2021 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/nikola_cancer/code/zvucniEfekti/#ec7fdcf8f0da