#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
/************ TFT ************/
#define TFT_CS 22
#define TFT_RST 23
#define TFT_DC 24
#define TFT_MOSI 25
#define TFT_SCK 26
Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);
/************ PINLER ************/
#define PIN_DOGRU 9
#define PIN_YANLIS 10
#define PIN_START 11
#define PIN_WIN 12
#define PIN_BUZZER 8
/************ OYUN ************/
const byte STAGES[4] = {3,4,5,6};
const unsigned long STAGE_TIME[4] = {5000,7000,10000,12000};
const byte ledPins[16] = {
30,31,32,33, 34,35,36,37,
38,39,40,41, 42,43,44,45
};
const byte buttonPins[16] = {
46,47,48,49, 50,51,52,53,
A0,A1,A2,A3, A4,A5,A6,A7
};
/************ GLOBAL ************/
byte sequence[6];
byte stageIndex = 0;
byte inputIndex = 0;
bool playing = false;
bool startLastState = HIGH;
unsigned long stageStart;
unsigned long lastBeep = 0;
unsigned long lastIdleLed = 0;
byte idleLedIndex = 0;
/************ PIN PULSE ************/
void pulsePin(byte pin){
digitalWrite(PIN_DOGRU,LOW);
digitalWrite(PIN_YANLIS,LOW);
digitalWrite(PIN_START,LOW);
digitalWrite(PIN_WIN,LOW);
delay(10);
digitalWrite(pin,HIGH);
delay(120);
digitalWrite(pin,LOW);
}
/************ BUZZER ************/
void beep(){ tone(PIN_BUZZER, 2000, 40); }
void wrongBeep(){ tone(PIN_BUZZER, 600, 2000); }
/************ KAZANMA MUZIĞI ************/
void winMusic(){
int melody[] = {
1319,1568,1760,2093,
1760,2093,2637,
2093,1760,1568,
2093,2637
};
int duration[] = {
150,150,150,250,
200,200,400,
200,200,300,
300,700
};
for(byte i=0;i<12;i++){
tone(PIN_BUZZER, melody[i], duration[i]);
delay(duration[i] + 40);
}
}
/************ GERİ SAYIM ************/
void countdownBeep(){
for(byte i=0;i<3;i++){
tone(PIN_BUZZER, 700, 800);
delay(1400);
}
tone(PIN_BUZZER, 1000, 1500);
delay(2000);
}
/************ YAZI ************/
void drawCentered(const char* txt, int y, uint16_t c, byte s){
int16_t x1,y1; uint16_t w,h;
tft.setTextSize(s);
tft.getTextBounds(txt,0,y,&x1,&y1,&w,&h);
tft.setCursor((320-w)/2,y);
tft.setTextColor(c);
tft.print(txt);
}
/************ KALIN YAZI ************/
void drawCenteredBold(const char* txt, int y, uint16_t c, byte s){
int16_t x1,y1; uint16_t w,h;
tft.setTextSize(s);
tft.getTextBounds(txt,0,y,&x1,&y1,&w,&h);
int x = (320 - w) / 2;
tft.setTextColor(c);
tft.setCursor(x, y); tft.print(txt);
tft.setCursor(x+1, y); tft.print(txt);
tft.setCursor(x, y+1); tft.print(txt);
}
/************ EKRANLAR ************/
void drawIdle(){
tft.fillScreen(ILI9341_BLACK);
drawCentered("HAFIZANA", 50, ILI9341_ORANGE, 5);
drawCentered("GUVENIYORSAN", 110, ILI9341_YELLOW, 4);
drawCentered("GEL!", 165, ILI9341_GREEN, 5);
}
void drawFailScreen(){
tft.fillScreen(ILI9341_BLACK);
drawCentered("LUTFEN", 55, ILI9341_YELLOW, 5);
drawCentered("TEKRAR DENEYINIZ!", 150, ILI9341_WHITE, 3);
}
void drawWinScreen(){
tft.fillScreen(ILI9341_GREEN);
drawCenteredBold("TEBRIKLER!", 100, ILI9341_RED, 5);
}
/************ KARTLAR ************/
void drawCards(byte count){
tft.fillScreen(ILI9341_BLACK);
int x=25,y=40;
for(byte i=0;i<6;i++){
tft.fillRoundRect(x,y,70,70,8,ILI9341_DARKGREY);
if(i<count){
tft.setTextSize(4);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(x+22,y+18);
tft.print("?");
}
x+=95;
if(i==2){x=25;y=130;}
}
}
void markCard(byte idx, uint16_t color){
int x = 25 + (idx % 3) * 95;
int y = (idx < 3) ? 40 : 130;
tft.fillRoundRect(x, y, 70, 70, 8, color);
}
/************ TUR ARASI ************/
void stageSuccessAnimation(){
for(byte k=0;k<3;k++){
for(byte i=0;i<STAGES[stageIndex];i++) markCard(i, ILI9341_GREEN);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],HIGH);
delay(250);
for(byte i=0;i<STAGES[stageIndex];i++) markCard(i, ILI9341_DARKGREY);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],LOW);
delay(250);
}
}
/************ YANLIŞ ************/
void wrongAnimation(byte idx){
for(byte k=0;k<15;k++){
markCard(idx, ILI9341_RED);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],HIGH);
delay(150);
markCard(idx, ILI9341_DARKGREY);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],LOW);
delay(150);
}
}
/************ SEKANS ************/
void playSequence(byte c){
for(byte i=0;i<c;i++){
sequence[i]=random(16);
digitalWrite(ledPins[sequence[i]],HIGH);
delay(2000);
digitalWrite(ledPins[sequence[i]],LOW);
delay(300);
}
}
/************ SETUP ************/
void setup(){
randomSeed(analogRead(A15));
for(byte i=0;i<16;i++){
pinMode(ledPins[i],OUTPUT);
pinMode(buttonPins[i],INPUT_PULLUP);
}
pinMode(PIN_DOGRU,OUTPUT);
pinMode(PIN_YANLIS,OUTPUT);
pinMode(PIN_START,OUTPUT);
pinMode(PIN_WIN,OUTPUT);
pinMode(PIN_BUZZER,OUTPUT);
tft.begin();
tft.setRotation(1);
drawIdle();
}
/************ LOOP ************/
void loop(){
if(!playing && millis()-lastIdleLed>120){
digitalWrite(ledPins[idleLedIndex],LOW);
idleLedIndex=(idleLedIndex+1)%16;
digitalWrite(ledPins[idleLedIndex],HIGH);
lastIdleLed=millis();
}
bool startNow=digitalRead(buttonPins[0]);
if(!playing && startLastState==HIGH && startNow==LOW){
pulsePin(PIN_START);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],LOW);
countdownBeep();
playing=true;
stageIndex=0;
}
startLastState=startNow;
if(!playing) return;
drawCards(STAGES[stageIndex]);
delay(400);
playSequence(STAGES[stageIndex]);
inputIndex=0;
stageStart=millis();
lastBeep=0;
while(millis()-stageStart<STAGE_TIME[stageIndex]){
if(millis()-lastBeep>500){ beep(); lastBeep=millis(); }
for(byte i=0;i<16;i++){
if(digitalRead(buttonPins[i])==LOW){
if(i==sequence[inputIndex]){
pulsePin(PIN_DOGRU);
markCard(inputIndex, ILI9341_GREEN);
inputIndex++;
if(inputIndex==STAGES[stageIndex]){
pulsePin(PIN_WIN);
if(stageIndex<3){
stageSuccessAnimation();
stageIndex++;
return;
}
winMusic();
drawWinScreen();
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],HIGH);
delay(3000);
for(byte i=0;i<16;i++) digitalWrite(ledPins[i],LOW);
playing=false;
drawIdle();
return;
}
}else{
pulsePin(PIN_YANLIS);
wrongBeep();
wrongAnimation(inputIndex);
drawFailScreen();
delay(5000);
playing=false;
drawIdle();
return;
}
while(digitalRead(buttonPins[i])==LOW);
delay(150);
}
}
}
wrongBeep();
drawFailScreen();
delay(5000);
playing=false;
drawIdle();
}