1#define NOTE_B0 31
2#define NOTE_C1 33
3#define NOTE_CS1 35
4#define NOTE_D1 37
5#define NOTE_DS1 39
6#define NOTE_E1 41
7#define NOTE_F1 44
8#define NOTE_FS1 46
9#define NOTE_G1 49
10#define NOTE_GS1 52
11#define NOTE_A1 55
12#define NOTE_AS1 58
13#define NOTE_B1 62
14#define NOTE_C2 65
15#define NOTE_CS2 69
16#define NOTE_D2 73
17#define NOTE_DS2 78
18#define NOTE_E2 82
19#define NOTE_F2 87
20#define NOTE_FS2 93
21#define NOTE_G2 98
22#define NOTE_GS2 104
23#define NOTE_A2 110
24#define NOTE_AS2 117
25#define NOTE_B2 123
26#define NOTE_C3 131
27#define NOTE_CS3 139
28#define NOTE_D3 147
29#define NOTE_DS3 156
30#define NOTE_E3 165
31#define NOTE_F3 175
32#define NOTE_FS3 185
33#define NOTE_G3 196
34#define NOTE_GS3 208
35#define NOTE_A3 220
36#define NOTE_AS3 233
37#define NOTE_B3 247
38#define NOTE_C4 262
39#define NOTE_CS4 277
40#define NOTE_D4 294
41#define NOTE_DS4 311
42#define NOTE_E4 330
43#define NOTE_F4 349
44#define NOTE_FS4 370
45#define NOTE_G4 392
46#define NOTE_GS4 415
47#define NOTE_A4 440
48#define NOTE_AS4 466
49#define NOTE_B4 494
50#define NOTE_C5 523
51#define NOTE_CS5 554
52#define NOTE_D5 587
53#define NOTE_DS5 622
54#define NOTE_E5 659
55#define NOTE_F5 698
56#define NOTE_FS5 740
57#define NOTE_G5 784
58#define NOTE_GS5 831
59#define NOTE_A5 880
60#define NOTE_AS5 932
61#define NOTE_B5 988
62#define NOTE_C6 1047
63#define NOTE_CS6 1109
64#define NOTE_D6 1175
65#define NOTE_DS6 1245
66#define NOTE_E6 1319
67#define NOTE_F6 1397
68#define NOTE_FS6 1480
69#define NOTE_G6 1568
70#define NOTE_GS6 1661
71#define NOTE_A6 1760
72#define NOTE_AS6 1865
73#define NOTE_B6 1976
74#define NOTE_C7 2093
75#define NOTE_CS7 2217
76#define NOTE_D7 2349
77#define NOTE_DS7 2489
78#define NOTE_E7 2637
79#define NOTE_F7 2794
80#define NOTE_FS7 2960
81#define NOTE_G7 3136
82#define NOTE_GS7 3322
83#define NOTE_A7 3520
84#define NOTE_AS7 3729
85#define NOTE_B7 3951
86#define NOTE_C8 4186
87#define NOTE_CS8 4435
88#define NOTE_D8 4699
89#define NOTE_DS8 4978
90
91#define CHOICE_OFF 0 //Used to control LEDs
92#define CHOICE_NONE 0 //Used to check buttons
93#define CHOICE_RED (1 << 0)
94#define CHOICE_GREEN (1 << 1)
95#define CHOICE_BLUE (1 << 2)
96#define CHOICE_YELLOW (1 << 3)
97
98// UPDATED: Your Custom LED Wiring
99#define LED_RED 10
100#define LED_GREEN 9
101#define LED_BLUE 8
102#define LED_YELLOW 7
103
104// UPDATED: Your Custom Button Wiring
105#define BUTTON_RED 5
106#define BUTTON_GREEN 4
107#define BUTTON_BLUE 3
108#define BUTTON_YELLOW 2
109
110// UPDATED: Your Custom Buzzer Wiring
111#define BUZZER1 10
112
113// Define game parameters
114#define ROUNDS_TO_WIN 13 //Number of rounds to succesfully remember before you win. 13 is do-able.
115#define ENTRY_TIME_LIMIT 3000 //Amount of time to press a button before game times out. 3000ms = 3 sec
116
117#define MODE_MEMORY 0
118#define MODE_BATTLE 1
119#define MODE_BEEGEES 2
120
121// Game state variables
122byte gameMode = MODE_MEMORY; //By default, let's play the memory game
123byte gameBoard[32]; //Contains the combination of buttons as we advance
124byte gameRound = 0; //Counts the number of succesful rounds the player has made it through
125
126void setup()
127{
128 //Enable pull ups on inputs
129 pinMode(BUTTON_RED, INPUT_PULLUP);
130 pinMode(BUTTON_GREEN, INPUT_PULLUP);
131 pinMode(BUTTON_BLUE, INPUT_PULLUP);
132 pinMode(BUTTON_YELLOW, INPUT_PULLUP);
133
134 pinMode(LED_RED, OUTPUT);
135 pinMode(LED_GREEN, OUTPUT);
136 pinMode(LED_BLUE, OUTPUT);
137 pinMode(LED_YELLOW, OUTPUT);
138
139 pinMode(BUZZER1, OUTPUT);
140
141 //Mode checking
142 gameMode = MODE_MEMORY;
143
144 if (checkButton() == CHOICE_YELLOW) play_beegees();
145
146 if (checkButton() == CHOICE_GREEN)
147 {
148 gameMode = MODE_BATTLE;
149
150 setLEDs(CHOICE_GREEN);
151 toner(CHOICE_GREEN, 150);
152
153 setLEDs(CHOICE_RED | CHOICE_BLUE | CHOICE_YELLOW);
154
155 while(checkButton() != CHOICE_NONE) ;
156 }
157
158 play_winner();
159}
160
161void loop()
162{
163 attractMode();
164
165 // UPDATED: Fast 3x blink to start the game
166 for(int i = 0; i < 3; i++) {
167 setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE | CHOICE_YELLOW);
168 buzz_sound(100, 1136);
169 setLEDs(CHOICE_OFF);
170 delay(100);
171 }
172 delay(300); // Short pause before game starts
173
174 if (gameMode == MODE_MEMORY)
175 {
176 if (play_memory() == true)
177 play_winner();
178 else
179 play_loser();
180 }
181
182 if (gameMode == MODE_BATTLE)
183 {
184 play_battle();
185 play_loser();
186 }
187}
188
189//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
190
191boolean play_memory(void)
192{
193 randomSeed(millis());
194 gameRound = 0;
195
196 while (gameRound < ROUNDS_TO_WIN)
197 {
198 add_to_moves();
199 playMoves();
200
201 for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
202 {
203 byte choice = wait_for_button();
204
205 if (choice == 0) return false;
206 if (choice != gameBoard[currentMove]) return false;
207 }
208
209 delay(500); // Kept fast for pacing
210 }
211 return true;
212}
213
214boolean play_battle(void)
215{
216 gameRound = 0;
217
218 while (1)
219 {
220 byte newButton = wait_for_button();
221 gameBoard[gameRound++] = newButton;
222
223 for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
224 {
225 byte choice = wait_for_button();
226
227 if (choice == 0) return false;
228 if (choice != gameBoard[currentMove]) return false;
229 }
230
231 delay(100);
232 }
233 return true;
234}
235
236void playMoves(void)
237{
238 for (byte currentMove = 0 ; currentMove < gameRound ; currentMove++)
239 {
240 toner(gameBoard[currentMove], 150);
241 delay(150);
242 }
243}
244
245void add_to_moves(void)
246{
247 byte newButton = random(0, 4);
248
249 if(newButton == 0) newButton = CHOICE_RED;
250 else if(newButton == 1) newButton = CHOICE_GREEN;
251 else if(newButton == 2) newButton = CHOICE_BLUE;
252 else if(newButton == 3) newButton = CHOICE_YELLOW;
253
254 gameBoard[gameRound++] = newButton;
255}
256
257//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
258
259// UPDATED: Brightness set to 200 using analogWrite
260void setLEDs(byte leds)
261{
262 if ((leds & CHOICE_RED) != 0) analogWrite(LED_RED, 200);
263 else digitalWrite(LED_RED, LOW);
264
265 if ((leds & CHOICE_GREEN) != 0) analogWrite(LED_GREEN, 200);
266 else digitalWrite(LED_GREEN, LOW);
267
268 if ((leds & CHOICE_BLUE) != 0) analogWrite(LED_BLUE, 200);
269 else digitalWrite(LED_BLUE, LOW);
270
271 if ((leds & CHOICE_YELLOW) != 0) analogWrite(LED_YELLOW, 200);
272 else digitalWrite(LED_YELLOW, LOW);
273}
274
275byte wait_for_button(void)
276{
277 long startTime = millis();
278
279 while ( (millis() - startTime) < ENTRY_TIME_LIMIT)
280 {
281 byte button = checkButton();
282
283 if (button != CHOICE_NONE)
284 {
285 toner(button, 150);
286 while(checkButton() != CHOICE_NONE) ;
287 delay(10);
288 return button;
289 }
290 }
291 return CHOICE_NONE;
292}
293
294byte checkButton(void)
295{
296 if (digitalRead(BUTTON_RED) == 0) return(CHOICE_RED);
297 else if (digitalRead(BUTTON_GREEN) == 0) return(CHOICE_GREEN);
298 else if (digitalRead(BUTTON_BLUE) == 0) return(CHOICE_BLUE);
299 else if (digitalRead(BUTTON_YELLOW) == 0) return(CHOICE_YELLOW);
300
301 return(CHOICE_NONE);
302}
303
304void toner(byte which, int buzz_length_ms)
305{
306 setLEDs(which);
307
308 switch(which)
309 {
310 case CHOICE_RED: buzz_sound(buzz_length_ms, 1136); break;
311 case CHOICE_GREEN: buzz_sound(buzz_length_ms, 568); break;
312 case CHOICE_BLUE: buzz_sound(buzz_length_ms, 851); break;
313 case CHOICE_YELLOW: buzz_sound(buzz_length_ms, 638); break;
314 }
315
316 setLEDs(CHOICE_OFF);
317}
318
319// UPDATED: Modified for a single buzzer pin
320void buzz_sound(int buzz_length_ms, int buzz_delay_us)
321{
322 long buzz_length_us = buzz_length_ms * (long)1000;
323
324 while (buzz_length_us > (buzz_delay_us * 2))
325 {
326 buzz_length_us -= buzz_delay_us * 2;
327
328 digitalWrite(BUZZER1, HIGH);
329 delayMicroseconds(buzz_delay_us);
330
331 digitalWrite(BUZZER1, LOW);
332 delayMicroseconds(buzz_delay_us);
333 }
334}
335
336void play_winner(void)
337{
338 setLEDs(CHOICE_GREEN | CHOICE_BLUE);
339 winner_sound();
340 setLEDs(CHOICE_RED | CHOICE_YELLOW);
341 winner_sound();
342 setLEDs(CHOICE_GREEN | CHOICE_BLUE);
343 winner_sound();
344 setLEDs(CHOICE_RED | CHOICE_YELLOW);
345 winner_sound();
346
347 // UPDATED: 3x blink at the end
348 delay(300);
349 for(int i = 0; i < 3; i++) {
350 setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE | CHOICE_YELLOW);
351 buzz_sound(150, 800);
352 setLEDs(CHOICE_OFF);
353 delay(150);
354 }
355}
356
357// UPDATED: Modified for single buzzer pin
358void winner_sound(void)
359{
360 for (byte x = 250 ; x > 70 ; x--)
361 {
362 for (byte y = 0 ; y < 3 ; y++)
363 {
364 digitalWrite(BUZZER1, HIGH);
365 delayMicroseconds(x);
366
367 digitalWrite(BUZZER1, LOW);
368 delayMicroseconds(x);
369 }
370 }
371}
372
373void play_loser(void)
374{
375 setLEDs(CHOICE_RED | CHOICE_GREEN);
376 buzz_sound(255, 1500);
377
378 setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
379 buzz_sound(255, 1500);
380
381 setLEDs(CHOICE_RED | CHOICE_GREEN);
382 buzz_sound(255, 1500);
383
384 setLEDs(CHOICE_BLUE | CHOICE_YELLOW);
385 buzz_sound(255, 1500);
386
387 // UPDATED: 3x blink at the end
388 delay(300);
389 for(int i = 0; i < 3; i++) {
390 setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE | CHOICE_YELLOW);
391 buzz_sound(150, 1500);
392 setLEDs(CHOICE_OFF);
393 delay(150);
394 }
395}
396
397void attractMode(void)
398{
399 while(1)
400 {
401 setLEDs(CHOICE_RED);
402 delay(100);
403 if (checkButton() != CHOICE_NONE) return;
404
405 setLEDs(CHOICE_BLUE);
406 delay(100);
407 if (checkButton() != CHOICE_NONE) return;
408
409 setLEDs(CHOICE_GREEN);
410 delay(100);
411 if (checkButton() != CHOICE_NONE) return;
412
413 setLEDs(CHOICE_YELLOW);
414 delay(100);
415 if (checkButton() != CHOICE_NONE) return;
416 }
417}
418
419//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
420
421int melody[] = {
422 NOTE_G4, NOTE_A4, 0, NOTE_C5, 0, 0, NOTE_G4, 0, 0, 0,
423 NOTE_E4, 0, NOTE_D4, NOTE_E4, NOTE_G4, 0,
424 NOTE_D4, NOTE_E4, 0, NOTE_G4, 0, 0,
425 NOTE_D4, 0, NOTE_E4, 0, NOTE_G4, 0, NOTE_A4, 0, NOTE_C5, 0};
426
427int noteDuration = 115;
428int LEDnumber = 0;
429
430void play_beegees()
431{
432 setLEDs(CHOICE_YELLOW);
433 toner(CHOICE_YELLOW, 150);
434 setLEDs(CHOICE_RED | CHOICE_GREEN | CHOICE_BLUE);
435 while(checkButton() != CHOICE_NONE) ;
436
437 setLEDs(CHOICE_NONE);
438 delay(1000);
439
440 while(checkButton() == CHOICE_NONE)
441 {
442 for (int thisNote = 0; thisNote < 32; thisNote++) {
443 changeLED();
444 tone(BUZZER1, melody[thisNote],noteDuration); // UPDATED: Changed to BUZZER1
445 int pauseBetweenNotes = noteDuration * 1.30;
446 delay(pauseBetweenNotes);
447 noTone(BUZZER1); // UPDATED: Changed to BUZZER1
448 }
449 }
450}
451
452void changeLED(void)
453{
454 setLEDs(1 << LEDnumber);
455 LEDnumber++;
456 if(LEDnumber > 3) LEDnumber = 0;
457}