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

Committer:
nikola_cancer
Date:
Wed Dec 01 13:17:00 2021 +0000
Revision:
0:f1138da8bd35
v1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nikola_cancer 0:f1138da8bd35 1 /* mbed Microcontroller Library
nikola_cancer 0:f1138da8bd35 2 * Copyright (c) 2019 ARM Limited
nikola_cancer 0:f1138da8bd35 3 * SPDX-License-Identifier: Apache-2.0
nikola_cancer 0:f1138da8bd35 4 */
nikola_cancer 0:f1138da8bd35 5
nikola_cancer 0:f1138da8bd35 6 #include "mbed.h"
nikola_cancer 0:f1138da8bd35 7 #include "zvucniEfekti.h"
nikola_cancer 0:f1138da8bd35 8
nikola_cancer 0:f1138da8bd35 9 #define MAX_BROJ_SEKVENCE 10
nikola_cancer 0:f1138da8bd35 10 #define SAMPLEFREQ 8000
nikola_cancer 0:f1138da8bd35 11
nikola_cancer 0:f1138da8bd35 12 InterruptIn tipkaloFlipLED(D12);
nikola_cancer 0:f1138da8bd35 13 DigitalOut ledZaProvjeru(D6);
nikola_cancer 0:f1138da8bd35 14
nikola_cancer 0:f1138da8bd35 15 Ticker sampleRate;
nikola_cancer 0:f1138da8bd35 16 AnalogOut zvucnik(PA_5);
nikola_cancer 0:f1138da8bd35 17 AnalogIn potenciometar(A0);
nikola_cancer 0:f1138da8bd35 18 DigitalIn tipkalo(D9);
nikola_cancer 0:f1138da8bd35 19
nikola_cancer 0:f1138da8bd35 20 int kontrolaZvuka; // globalna varijabla za odabir koji zvuk se pušta (u
nikola_cancer 0:f1138da8bd35 21 // funkciji sviraj) na piezo
nikola_cancer 0:f1138da8bd35 22
nikola_cancer 0:f1138da8bd35 23 class Igra {
nikola_cancer 0:f1138da8bd35 24 private:
nikola_cancer 0:f1138da8bd35 25 int brojLedica;
nikola_cancer 0:f1138da8bd35 26 DigitalOut *ledice;
nikola_cancer 0:f1138da8bd35 27 float vrijednostiZaPotenciometar[10];
nikola_cancer 0:f1138da8bd35 28
nikola_cancer 0:f1138da8bd35 29 public:
nikola_cancer 0:f1138da8bd35 30 Igra(DigitalOut *led, int brLED) {
nikola_cancer 0:f1138da8bd35 31 ledice = led;
nikola_cancer 0:f1138da8bd35 32 brojLedica = brLED;
nikola_cancer 0:f1138da8bd35 33
nikola_cancer 0:f1138da8bd35 34 float korak = 1. / brojLedica;
nikola_cancer 0:f1138da8bd35 35 for (int i = 0; i < brojLedica + 1; i++) {
nikola_cancer 0:f1138da8bd35 36 if (i == 0) {
nikola_cancer 0:f1138da8bd35 37 vrijednostiZaPotenciometar[i] = 0;
nikola_cancer 0:f1138da8bd35 38 } else {
nikola_cancer 0:f1138da8bd35 39 vrijednostiZaPotenciometar[i] =
nikola_cancer 0:f1138da8bd35 40 vrijednostiZaPotenciometar[i - 1] + korak;
nikola_cancer 0:f1138da8bd35 41 }
nikola_cancer 0:f1138da8bd35 42 }
nikola_cancer 0:f1138da8bd35 43
nikola_cancer 0:f1138da8bd35 44 tipkalo.mode(PullUp);
nikola_cancer 0:f1138da8bd35 45
nikola_cancer 0:f1138da8bd35 46 srand(time(0));
nikola_cancer 0:f1138da8bd35 47 }
nikola_cancer 0:f1138da8bd35 48
nikola_cancer 0:f1138da8bd35 49 /*
nikola_cancer 0:f1138da8bd35 50 globalna varijabla kontrolaZvuka:
nikola_cancer 0:f1138da8bd35 51 0 -> gameStart
nikola_cancer 0:f1138da8bd35 52 1 -> nextLevel
nikola_cancer 0:f1138da8bd35 53 2 -> finalLevel
nikola_cancer 0:f1138da8bd35 54 3 -> gameWon
nikola_cancer 0:f1138da8bd35 55 4 -> gameOver
nikola_cancer 0:f1138da8bd35 56 */
nikola_cancer 0:f1138da8bd35 57 void sviraj() {
nikola_cancer 0:f1138da8bd35 58 static int i = 0;
nikola_cancer 0:f1138da8bd35 59
nikola_cancer 0:f1138da8bd35 60 switch (kontrolaZvuka) {
nikola_cancer 0:f1138da8bd35 61 case 0:
nikola_cancer 0:f1138da8bd35 62 zvucnik.write_u16(zvukGameStart[i] << 8);
nikola_cancer 0:f1138da8bd35 63 i++;
nikola_cancer 0:f1138da8bd35 64 if (i == brojSamplovaZvukGameStart) {
nikola_cancer 0:f1138da8bd35 65 i = 0;
nikola_cancer 0:f1138da8bd35 66 zvucnik.write_u16(0);
nikola_cancer 0:f1138da8bd35 67 sampleRate.detach();
nikola_cancer 0:f1138da8bd35 68 }
nikola_cancer 0:f1138da8bd35 69 break;
nikola_cancer 0:f1138da8bd35 70
nikola_cancer 0:f1138da8bd35 71 case 1:
nikola_cancer 0:f1138da8bd35 72 zvucnik.write_u16(zvukNextLevel[i] << 8);
nikola_cancer 0:f1138da8bd35 73 i++;
nikola_cancer 0:f1138da8bd35 74 if (i == brojSamplovaZvukNextLevel) {
nikola_cancer 0:f1138da8bd35 75 i = 0;
nikola_cancer 0:f1138da8bd35 76 zvucnik.write_u16(0);
nikola_cancer 0:f1138da8bd35 77 sampleRate.detach();
nikola_cancer 0:f1138da8bd35 78 }
nikola_cancer 0:f1138da8bd35 79 break;
nikola_cancer 0:f1138da8bd35 80
nikola_cancer 0:f1138da8bd35 81 case 2:
nikola_cancer 0:f1138da8bd35 82 zvucnik.write_u16(zvukFinalLevel[i] << 8);
nikola_cancer 0:f1138da8bd35 83 i++;
nikola_cancer 0:f1138da8bd35 84 if (i == brojSamplovaZvukFinalLevel) {
nikola_cancer 0:f1138da8bd35 85 i = 0;
nikola_cancer 0:f1138da8bd35 86 zvucnik.write_u16(0);
nikola_cancer 0:f1138da8bd35 87 sampleRate.detach();
nikola_cancer 0:f1138da8bd35 88 }
nikola_cancer 0:f1138da8bd35 89 break;
nikola_cancer 0:f1138da8bd35 90
nikola_cancer 0:f1138da8bd35 91 case 3:
nikola_cancer 0:f1138da8bd35 92 zvucnik.write_u16(zvukGameWon[i] << 8);
nikola_cancer 0:f1138da8bd35 93 i++;
nikola_cancer 0:f1138da8bd35 94 if (i == brojSamplovaZvukGameWon) {
nikola_cancer 0:f1138da8bd35 95 i = 0;
nikola_cancer 0:f1138da8bd35 96 zvucnik.write_u16(0);
nikola_cancer 0:f1138da8bd35 97 sampleRate.detach();
nikola_cancer 0:f1138da8bd35 98 }
nikola_cancer 0:f1138da8bd35 99 break;
nikola_cancer 0:f1138da8bd35 100
nikola_cancer 0:f1138da8bd35 101 case 4:
nikola_cancer 0:f1138da8bd35 102 zvucnik.write_u16(zvukGameOver[i] << 8);
nikola_cancer 0:f1138da8bd35 103 i++;
nikola_cancer 0:f1138da8bd35 104 if (i == brojSamplovaZvukGameOver) {
nikola_cancer 0:f1138da8bd35 105 i = 0;
nikola_cancer 0:f1138da8bd35 106 zvucnik.write_u16(0);
nikola_cancer 0:f1138da8bd35 107 sampleRate.detach();
nikola_cancer 0:f1138da8bd35 108 }
nikola_cancer 0:f1138da8bd35 109 break;
nikola_cancer 0:f1138da8bd35 110 }
nikola_cancer 0:f1138da8bd35 111 }
nikola_cancer 0:f1138da8bd35 112
nikola_cancer 0:f1138da8bd35 113 void generirajRandomSekvencu(int brojUzoraka, int *sekvenca) {
nikola_cancer 0:f1138da8bd35 114 ugasiSveLED();
nikola_cancer 0:f1138da8bd35 115 for (int i = 0; i < brojUzoraka; i++) {
nikola_cancer 0:f1138da8bd35 116 int num = (rand() % brojLedica); // random broj između 0 i brLED
nikola_cancer 0:f1138da8bd35 117 sekvenca[i] = num; // spremi u sekvencu zbog kasnije usporedbe generiranog
nikola_cancer 0:f1138da8bd35 118 // i pogađanog
nikola_cancer 0:f1138da8bd35 119
nikola_cancer 0:f1138da8bd35 120 // upali i ugasi random LED
nikola_cancer 0:f1138da8bd35 121 wait_ms(500);
nikola_cancer 0:f1138da8bd35 122 ledice[num] = 1;
nikola_cancer 0:f1138da8bd35 123 wait_ms(500);
nikola_cancer 0:f1138da8bd35 124 ledice[num] = 0;
nikola_cancer 0:f1138da8bd35 125 wait_ms(500);
nikola_cancer 0:f1138da8bd35 126 }
nikola_cancer 0:f1138da8bd35 127 wait(2);
nikola_cancer 0:f1138da8bd35 128 }
nikola_cancer 0:f1138da8bd35 129
nikola_cancer 0:f1138da8bd35 130 void spremiUnosKorisnika(int brojUzoraka, int *sekvenca) {
nikola_cancer 0:f1138da8bd35 131 for (int k = 0; k < brojUzoraka; k++) {
nikola_cancer 0:f1138da8bd35 132 for (;;) {
nikola_cancer 0:f1138da8bd35 133 for (int i = 0; i < brojLedica; i++) {
nikola_cancer 0:f1138da8bd35 134 if (potenciometar >= vrijednostiZaPotenciometar[i] &&
nikola_cancer 0:f1138da8bd35 135 potenciometar < vrijednostiZaPotenciometar[i + 1]) {
nikola_cancer 0:f1138da8bd35 136 ledice[i] = 1;
nikola_cancer 0:f1138da8bd35 137 } else {
nikola_cancer 0:f1138da8bd35 138 ledice[i] = 0;
nikola_cancer 0:f1138da8bd35 139 }
nikola_cancer 0:f1138da8bd35 140 }
nikola_cancer 0:f1138da8bd35 141
nikola_cancer 0:f1138da8bd35 142 if (tipkalo == 0) {
nikola_cancer 0:f1138da8bd35 143 wait_ms(50); // debounce
nikola_cancer 0:f1138da8bd35 144 if (tipkalo == 0) {
nikola_cancer 0:f1138da8bd35 145 for (int j = 0; j < brojLedica; j++) {
nikola_cancer 0:f1138da8bd35 146 if (ledice[j].read() == 1) {
nikola_cancer 0:f1138da8bd35 147 sekvenca[k] = j;
nikola_cancer 0:f1138da8bd35 148
nikola_cancer 0:f1138da8bd35 149 // da korisnih ima feedback da je ucitan njegov odabir
nikola_cancer 0:f1138da8bd35 150 ledice[j] = 0;
nikola_cancer 0:f1138da8bd35 151 wait_ms(500);
nikola_cancer 0:f1138da8bd35 152 ledice[j] = 1;
nikola_cancer 0:f1138da8bd35 153 }
nikola_cancer 0:f1138da8bd35 154 }
nikola_cancer 0:f1138da8bd35 155 // cekaj dok tipkalo ne ode u jedan (radi ko rising edge)
nikola_cancer 0:f1138da8bd35 156 // da ove beskonacne petlje nema bi spremil 4x istu vrijednost u
nikola_cancer 0:f1138da8bd35 157 // array (jer radi brzo)
nikola_cancer 0:f1138da8bd35 158 do {
nikola_cancer 0:f1138da8bd35 159 } while (tipkalo.read() == 0);
nikola_cancer 0:f1138da8bd35 160 break;
nikola_cancer 0:f1138da8bd35 161 }
nikola_cancer 0:f1138da8bd35 162 }
nikola_cancer 0:f1138da8bd35 163 }
nikola_cancer 0:f1138da8bd35 164 }
nikola_cancer 0:f1138da8bd35 165 }
nikola_cancer 0:f1138da8bd35 166 /*
nikola_cancer 0:f1138da8bd35 167 funkcija vraca 0 za razlicite arraye, a 1 za iste
nikola_cancer 0:f1138da8bd35 168 */
nikola_cancer 0:f1138da8bd35 169 int provjeriSekvence(int *generiranaSekvenca, int *unesenaSekvenca,
nikola_cancer 0:f1138da8bd35 170 int brojUzorakaSekvence) {
nikola_cancer 0:f1138da8bd35 171 int i = 0;
nikola_cancer 0:f1138da8bd35 172 for (i = 0; i < brojUzorakaSekvence; i++) {
nikola_cancer 0:f1138da8bd35 173 if (generiranaSekvenca[i] != unesenaSekvenca[i]) {
nikola_cancer 0:f1138da8bd35 174 return 0; // poraz
nikola_cancer 0:f1138da8bd35 175 }
nikola_cancer 0:f1138da8bd35 176 }
nikola_cancer 0:f1138da8bd35 177 return 1; // sljedeca razina/pobjeda
nikola_cancer 0:f1138da8bd35 178 }
nikola_cancer 0:f1138da8bd35 179
nikola_cancer 0:f1138da8bd35 180 void ugasiSveLED() {
nikola_cancer 0:f1138da8bd35 181 for (int i = 0; i < brojLedica; i++) {
nikola_cancer 0:f1138da8bd35 182 ledice[i] = 0;
nikola_cancer 0:f1138da8bd35 183 }
nikola_cancer 0:f1138da8bd35 184 }
nikola_cancer 0:f1138da8bd35 185
nikola_cancer 0:f1138da8bd35 186 void sljedecaRazina(int finalniLevel) {
nikola_cancer 0:f1138da8bd35 187 ugasiSveLED();
nikola_cancer 0:f1138da8bd35 188 if (finalniLevel != 0) {
nikola_cancer 0:f1138da8bd35 189 kontrolaZvuka = 2;
nikola_cancer 0:f1138da8bd35 190 } else {
nikola_cancer 0:f1138da8bd35 191 kontrolaZvuka = 1;
nikola_cancer 0:f1138da8bd35 192 }
nikola_cancer 0:f1138da8bd35 193 sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
nikola_cancer 0:f1138da8bd35 194 for (int i = 0; i < brojLedica; i++) {
nikola_cancer 0:f1138da8bd35 195 ledice[i] = 1;
nikola_cancer 0:f1138da8bd35 196 wait_us(100000);
nikola_cancer 0:f1138da8bd35 197 ledice[i] = 0;
nikola_cancer 0:f1138da8bd35 198 }
nikola_cancer 0:f1138da8bd35 199 wait_us(100000);
nikola_cancer 0:f1138da8bd35 200 }
nikola_cancer 0:f1138da8bd35 201
nikola_cancer 0:f1138da8bd35 202 void novaIgra() {
nikola_cancer 0:f1138da8bd35 203 kontrolaZvuka = 0;
nikola_cancer 0:f1138da8bd35 204 sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
nikola_cancer 0:f1138da8bd35 205 wait(2);
nikola_cancer 0:f1138da8bd35 206 }
nikola_cancer 0:f1138da8bd35 207
nikola_cancer 0:f1138da8bd35 208 void pobjeda() {
nikola_cancer 0:f1138da8bd35 209 ugasiSveLED();
nikola_cancer 0:f1138da8bd35 210 kontrolaZvuka = 3;
nikola_cancer 0:f1138da8bd35 211 sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
nikola_cancer 0:f1138da8bd35 212
nikola_cancer 0:f1138da8bd35 213 // chaser effekt 5x sim tam
nikola_cancer 0:f1138da8bd35 214 int i = 0;
nikola_cancer 0:f1138da8bd35 215 do {
nikola_cancer 0:f1138da8bd35 216
nikola_cancer 0:f1138da8bd35 217 for (int j = 0; j < brojLedica; j++) {
nikola_cancer 0:f1138da8bd35 218 ledice[j] = 1;
nikola_cancer 0:f1138da8bd35 219 wait_us(60000);
nikola_cancer 0:f1138da8bd35 220 ledice[j] = 0;
nikola_cancer 0:f1138da8bd35 221 }
nikola_cancer 0:f1138da8bd35 222
nikola_cancer 0:f1138da8bd35 223 for (int j = brojLedica - 1; j >= 0;
nikola_cancer 0:f1138da8bd35 224 j--) // -1 jer sizeof(arr) za arr[20] npr daje 20 a zadnji element je
nikola_cancer 0:f1138da8bd35 225 // 19
nikola_cancer 0:f1138da8bd35 226 {
nikola_cancer 0:f1138da8bd35 227 ledice[j] = 1;
nikola_cancer 0:f1138da8bd35 228 wait_us(60000);
nikola_cancer 0:f1138da8bd35 229 ledice[j] = 0;
nikola_cancer 0:f1138da8bd35 230 }
nikola_cancer 0:f1138da8bd35 231
nikola_cancer 0:f1138da8bd35 232 i++;
nikola_cancer 0:f1138da8bd35 233 } while (i < 10);
nikola_cancer 0:f1138da8bd35 234 wait(2);
nikola_cancer 0:f1138da8bd35 235 }
nikola_cancer 0:f1138da8bd35 236
nikola_cancer 0:f1138da8bd35 237 void poraz() {
nikola_cancer 0:f1138da8bd35 238 ugasiSveLED();
nikola_cancer 0:f1138da8bd35 239 kontrolaZvuka = 4;
nikola_cancer 0:f1138da8bd35 240 sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ);
nikola_cancer 0:f1138da8bd35 241 int i = 0;
nikola_cancer 0:f1138da8bd35 242 do {
nikola_cancer 0:f1138da8bd35 243
nikola_cancer 0:f1138da8bd35 244 for (int j = 0; j < brojLedica; j++) {
nikola_cancer 0:f1138da8bd35 245 ledice[j] = 1;
nikola_cancer 0:f1138da8bd35 246 }
nikola_cancer 0:f1138da8bd35 247 wait_us(500000);
nikola_cancer 0:f1138da8bd35 248
nikola_cancer 0:f1138da8bd35 249 ugasiSveLED();
nikola_cancer 0:f1138da8bd35 250 wait_us(500000);
nikola_cancer 0:f1138da8bd35 251
nikola_cancer 0:f1138da8bd35 252 i++;
nikola_cancer 0:f1138da8bd35 253 } while (i < 3);
nikola_cancer 0:f1138da8bd35 254 wait(2);
nikola_cancer 0:f1138da8bd35 255 }
nikola_cancer 0:f1138da8bd35 256 };
nikola_cancer 0:f1138da8bd35 257
nikola_cancer 0:f1138da8bd35 258 void flipLED() { ledZaProvjeru = !ledZaProvjeru; }
nikola_cancer 0:f1138da8bd35 259
nikola_cancer 0:f1138da8bd35 260 int main() {
nikola_cancer 0:f1138da8bd35 261 wait(1);
nikola_cancer 0:f1138da8bd35 262 tipkaloFlipLED.mode(PullUp);
nikola_cancer 0:f1138da8bd35 263 tipkaloFlipLED.rise(&flipLED);
nikola_cancer 0:f1138da8bd35 264 // inicijalizacija pinova za igru
nikola_cancer 0:f1138da8bd35 265 DigitalOut led[] = {D2, D4, D7, D8, D10, D11};
nikola_cancer 0:f1138da8bd35 266 int brojLedica = sizeof(led) / sizeof(led[0]);
nikola_cancer 0:f1138da8bd35 267
nikola_cancer 0:f1138da8bd35 268 // spremanje generiranih i unesenih vrijednosti
nikola_cancer 0:f1138da8bd35 269 int generiranaSekvenca[MAX_BROJ_SEKVENCE] = {0};
nikola_cancer 0:f1138da8bd35 270 int unosKorisnika[MAX_BROJ_SEKVENCE] = {0};
nikola_cancer 0:f1138da8bd35 271
nikola_cancer 0:f1138da8bd35 272 // postavke i logika igre
nikola_cancer 0:f1138da8bd35 273 int brojUzorakaSekvence = 3; // kolko puta se LED pale/gase
nikola_cancer 0:f1138da8bd35 274 int pobjedaPorazZastavica;
nikola_cancer 0:f1138da8bd35 275 int trenutniLevel = 0;
nikola_cancer 0:f1138da8bd35 276 int finalniLevel = 2;
nikola_cancer 0:f1138da8bd35 277
nikola_cancer 0:f1138da8bd35 278 Igra igra(led, brojLedica);
nikola_cancer 0:f1138da8bd35 279
nikola_cancer 0:f1138da8bd35 280 while (true) {
nikola_cancer 0:f1138da8bd35 281 if (trenutniLevel == 0) {
nikola_cancer 0:f1138da8bd35 282 igra.novaIgra();
nikola_cancer 0:f1138da8bd35 283 }
nikola_cancer 0:f1138da8bd35 284 igra.generirajRandomSekvencu(brojUzorakaSekvence, generiranaSekvenca);
nikola_cancer 0:f1138da8bd35 285 igra.spremiUnosKorisnika(brojUzorakaSekvence, unosKorisnika);
nikola_cancer 0:f1138da8bd35 286 pobjedaPorazZastavica = igra.provjeriSekvence(
nikola_cancer 0:f1138da8bd35 287 generiranaSekvenca, unosKorisnika, brojUzorakaSekvence);
nikola_cancer 0:f1138da8bd35 288
nikola_cancer 0:f1138da8bd35 289 switch (pobjedaPorazZastavica) {
nikola_cancer 0:f1138da8bd35 290 case 0:
nikola_cancer 0:f1138da8bd35 291 igra.poraz();
nikola_cancer 0:f1138da8bd35 292 brojUzorakaSekvence = 3;
nikola_cancer 0:f1138da8bd35 293 trenutniLevel = 0;
nikola_cancer 0:f1138da8bd35 294 break;
nikola_cancer 0:f1138da8bd35 295 case 1:
nikola_cancer 0:f1138da8bd35 296 if (trenutniLevel == finalniLevel - 1) {
nikola_cancer 0:f1138da8bd35 297 igra.sljedecaRazina(1); // 1 -> šalji zvuk finalLevel
nikola_cancer 0:f1138da8bd35 298 brojUzorakaSekvence++;
nikola_cancer 0:f1138da8bd35 299 trenutniLevel++;
nikola_cancer 0:f1138da8bd35 300 } else if (trenutniLevel == finalniLevel) {
nikola_cancer 0:f1138da8bd35 301 igra.pobjeda();
nikola_cancer 0:f1138da8bd35 302 brojUzorakaSekvence = 3;
nikola_cancer 0:f1138da8bd35 303 trenutniLevel = 0;
nikola_cancer 0:f1138da8bd35 304 } else {
nikola_cancer 0:f1138da8bd35 305 igra.sljedecaRazina(0); // 0 -> šalji zvuk nextLevel
nikola_cancer 0:f1138da8bd35 306 brojUzorakaSekvence++;
nikola_cancer 0:f1138da8bd35 307 trenutniLevel++;
nikola_cancer 0:f1138da8bd35 308 }
nikola_cancer 0:f1138da8bd35 309 break;
nikola_cancer 0:f1138da8bd35 310 }
nikola_cancer 0:f1138da8bd35 311 }
nikola_cancer 0:f1138da8bd35 312 }