#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
int buttonPin[] = { 12, 11, 10, 9};
int ledPin[] = { 7, 6, 5, 4};
#define SPEAKER_PIN 2
const int gameTones[] = { 262, 296, 330, 349 };
byte urutan[225] = {0};
byte indexgame = 0;
byte score = 0;
uint8_t lampIcon[8] = {
0b00000, //
0b00000, //
0b01110, // 000
0b11011, // 00 00
0b11101, // 000 0
0b11101, // 00000
0b11111, // 00000
0b01010, // 0 0
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.createChar(3, lampIcon);
lcd.begin(16, 2);
pinMode(SPEAKER_PIN, OUTPUT);
for (byte i = 0; i < 4; i++) {
pinMode(buttonPin[i], INPUT_PULLUP);
pinMode(ledPin[i], OUTPUT);
}
start();
}
void start() {
tone(SPEAKER_PIN, 262, 50);
delay(50);
tone(SPEAKER_PIN, 330, 100);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("MEMORY GAMES");
lcd.setCursor(1, 1);
lcd.print("ORDER THE LAMP");
delay(1500);
tone(SPEAKER_PIN, 330, 100);
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("MADE BY");
lcd.setCursor(5, 1);
lcd.print("REAZON");
delay(1500);
tone(SPEAKER_PIN, 330, 100);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("FIND CORRECT");
lcd.setCursor(1, 1);
lcd.print("ORDER OF LAMP!");
delay(1500);
tone(SPEAKER_PIN, 330, 100);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("LETS BEGIN!");
delay(1500);
lcd.clear();
delay(700);
}
void playOrder() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCORE :");
lcd.setCursor(7, 0);
lcd.print(score);
lcd.setCursor(5, 1);
lcd.print("[____]");
for (byte i = 0; i < indexgame; i++) {
lcd.setCursor(6 + urutan[i], 1);
lcd.print("\x03");
digitalWrite(ledPin[urutan[i]], HIGH);
tone(SPEAKER_PIN, gameTones[urutan[i]], 300);
delay(300);
digitalWrite(ledPin[urutan[i]], LOW);
noTone(SPEAKER_PIN);
lcd.setCursor(6 + urutan[i], 1);
lcd.print("_");
delay(500);
}
}
byte readButtons() {
while (true) {
for (byte i = 0; i < 4; i++) {
byte button = buttonPin[i];
if (digitalRead(button) == LOW) {
return i;
}
}
delay(1);
}
}
bool isCorrect() {
for (byte u = 0; u < indexgame; u++) {
lcd.setCursor(7, 0);
lcd.print(score);
byte pressed = readButtons();
lcd.setCursor(6 + pressed, 1);
lcd.print("\x03");
tone(SPEAKER_PIN, gameTones[pressed], 300);
digitalWrite(ledPin[pressed], HIGH);
delay(300);
lcd.setCursor(6 + pressed, 1);
lcd.print("_");
digitalWrite(ledPin[pressed], LOW);
noTone(SPEAKER_PIN);
if (pressed != urutan[u]) return false;
score++;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CORRECT!! LETS");
lcd.setCursor(0, 1);
lcd.print("TO NEXT LEVEL!");
tone(SPEAKER_PIN, 349, 50);
delay(50);
tone(SPEAKER_PIN, 330, 100);
for (byte u = 4; u > 0; u--) {
digitalWrite(ledPin[u - 1], HIGH);
delay(200);
digitalWrite(ledPin[u - 1], LOW);
}
return true;
}
void gameOver() {
lcd.setCursor(0, 0);
lcd.print("NOO.. YOU FAIL!");
tone(SPEAKER_PIN, 462, 50);
delay(50);
tone(SPEAKER_PIN, 100, 500);
for (byte i = 0; i < 2; i++) {
for (byte i = 0; i < 4; i++) {
digitalWrite(ledPin[i], HIGH);
lcd.setCursor(6 + i, 1);
lcd.print("\x03");
}
delay(200);
for (byte i = 0; i < 4; i++) {
digitalWrite(ledPin[i], LOW);
lcd.setCursor(6 + i, 1);
lcd.print("_");
}
delay(200);
}
delay(500);
indexgame = 0;
score = 0;
}
void loop() {
// put your main code here, to run repeatedly:
for (byte i = 0; i < indexgame; i++) {
byte rand = random(0, 4);
urutan[i] = rand;
}
indexgame++;
playOrder();
if (!isCorrect()) {
gameOver();
}
delay(400);
}