#include #define LED_PIN 6 #define LED_COUNT 8 #define BUTTON_BLUE 2 #define BUTTON_PURPLE 7 #define BUTTON_ORANGE 4 #define BUTTON_GREEN 8 #define BUZZER_PIN 9 #define MAX_SEQUENCE_LENGTH LED_COUNT Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); enum Color { BLUE, PURPLE, ORANGE, GREEN, NONE }; Color sequence[MAX_SEQUENCE_LENGTH]; int sequenceLength = 3; int playerIndex = 0; bool showingSequence = true; unsigned long lastStepTime = 0; int showIndex = 0; unsigned long reactionStartTime = 0; void setup() { pinMode(BUTTON_BLUE, INPUT_PULLUP); pinMode(BUTTON_PURPLE, INPUT_PULLUP); pinMode(BUTTON_ORANGE, INPUT_PULLUP); pinMode(BUTTON_GREEN, INPUT_PULLUP); pinMode(BUZZER_PIN, OUTPUT); // Buzzer strip.begin(); strip.show(); Serial.begin(9600); delay(1000); startupAnimation(); // ✨ animacja i dźwięk startowy Serial.println("🎮 Simon Says – klikaj po zapaleniu diod, ale nie za wcześnie!"); startNewRound(); } void loop() { // Pokazywanie sekwencji if (showingSequence) { if (millis() - lastStepTime > 600) { if (showIndex > 0) { strip.setPixelColor(showIndex - 1, 0); // zgaś poprzednią } if (showIndex < sequenceLength) { showColorOnLed(showIndex, sequence[showIndex]); lastStepTime = millis(); showIndex++; } else { strip.clear(); strip.show(); showingSequence = false; Serial.println("👉 Możesz odtwarzać sekwencję."); } } } // Obsługa kliknięć static bool buttonReleased = true; Color pressed = getPressedButton(); if (pressed == NONE) { buttonReleased = true; return; } if (buttonReleased) { buttonReleased = false; // Zbyt wcześnie (jeszcze nie pokazany kolor) if (playerIndex >= showIndex) { Serial.println("❌ Błąd! Kliknięcie przed pokazaniem koloru."); errorFeedback(); sequenceLength = 3; startNewRound(); return; } // Poprawny klik if (pressed == sequence[playerIndex]) { if (playerIndex == 0) { reactionStartTime = millis(); // start pomiaru czasu } playerIndex++; if (playerIndex == sequenceLength) { unsigned long reactionTime = millis() - reactionStartTime; Serial.print("✅ Sekwencja poprawna! Czas reakcji: "); Serial.print(reactionTime); Serial.println(" ms"); delay(1000); if (sequenceLength < MAX_SEQUENCE_LENGTH) { sequenceLength++; } startNewRound(); } } else { Serial.println("❌ Błąd! Zła sekwencja."); errorFeedback(); sequenceLength = 3; startNewRound(); } delay(250); // opóźnienie, by uniknąć szybkich powtórzeń } } void startNewRound() { strip.clear(); strip.show(); showingSequence = true; showIndex = 0; playerIndex = 0; lastStepTime = millis(); Serial.print("\n🧠 Nowa runda. Długość sekwencji: "); Serial.println(sequenceLength); for (int i = 0; i < sequenceLength; i++) { sequence[i] = static_cast(random(0, 4)); } } Color getPressedButton() { if (digitalRead(BUTTON_BLUE) == LOW) { delay(30); if (digitalRead(BUTTON_BLUE) == LOW) return BLUE; } if (digitalRead(BUTTON_PURPLE) == LOW) { delay(30); if (digitalRead(BUTTON_PURPLE) == LOW) return PURPLE; } if (digitalRead(BUTTON_ORANGE) == LOW) { delay(30); if (digitalRead(BUTTON_ORANGE) == LOW) return ORANGE; } if (digitalRead(BUTTON_GREEN) == LOW) { delay(30); if (digitalRead(BUTTON_GREEN) == LOW) return GREEN; } return NONE; } void showColorOnLed(int ledIndex, Color color) { uint32_t c; switch (color) { case BLUE: c = strip.Color(0, 0, 255); break; case PURPLE: c = strip.Color(128, 0, 128); break; case ORANGE: c = strip.Color(255, 80, 0); break; case GREEN: c = strip.Color(0, 255, 0); break; default: c = 0; } strip.setPixelColor(ledIndex, c); strip.show(); } void errorFeedback() { for (int i = 0; i < 3; i++) { analogWrite(BUZZER_PIN, 127); // Włącz buzzer for (int j = 0; j < LED_COUNT; j++) { strip.setPixelColor(j, strip.Color(255, 0, 0)); } strip.show(); delay(200); analogWrite(BUZZER_PIN, 0); // Wyłącz buzzer strip.clear(); strip.show(); delay(200); } } void startupAnimation() { // Zapalaj diody po kolei na biało for (int i = 0; i < LED_COUNT; i++) { strip.setPixelColor(i, strip.Color(255, 255, 255)); strip.show(); delay(150); } // Długi dźwięk startowy analogWrite(BUZZER_PIN, 127); delay(800); analogWrite(BUZZER_PIN, 0); strip.clear(); strip.show(); }