Catch The White!
#include <Adafruit_NeoPixel.h>

// Common constants and variables
const int buttonPin = D1;
const int ledPins[] = {26, D6, D7}; // Update these pin numbers based on your actual GPIO pins used for LEDs
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]);
const int targetLedIndex = 0; // Index of the target green LED in ledPins
const int neoPixelPower = 11;
const int neoPixelPin = 12;
const int numPixels = 1;
Adafruit_NeoPixel pixels(numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800);
int level = 1; // Starting level
const int baseDelay = 1000; // Base delay time for level 1
const int neoPixelBrightness = 50; // Set brightness level (0-255)

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(neoPixelPower, OUTPUT);
  digitalWrite(neoPixelPower, HIGH); // Ensure the NeoPixel strip is powered
  
  for (int i = 0; i < numLeds; i++) {
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], LOW); // Ensure all LEDs are off initially
  }

  pixels.begin();
  pixels.setBrightness(neoPixelBrightness);
  showNeoPixelColor(pixels.Color(0, 0, 255)); // Start with blue color indicating game start
  delay(1000); // Initial delay before the game starts
}

void loop() {
  bool correctPressDetected = false;
  int displayTime = baseDelay / level; // Adjust display time based on level
  int ledDisplayDuration = displayTime / 2;
  int ledToShow = -1;

  for (int i = 0; i < level; i++) {
    ledToShow = random(numLeds);
    digitalWrite(ledPins[ledToShow], HIGH);
    unsigned long startTime = millis();
    while (millis() - startTime < ledDisplayDuration) {
      if (digitalRead(buttonPin) == LOW) { // Active LOW button
        correctPressDetected = (ledToShow == targetLedIndex);
        delay(50); // Debounce delay
        while (digitalRead(buttonPin) == LOW); // Wait for button release
        break; // Exit the loop if button is pressed
      }
    }
    digitalWrite(ledPins[ledToShow], LOW); // Turn off LED after showing or button press
    if (correctPressDetected) break; // If correct button was pressed, no need to show more LEDs
  }

  // Game logic for correct or incorrect press
  if (correctPressDetected) {
    // Show rainbow colors on successful level completion
    for (int color = 0; color < 256; color++) {
      pixels.setPixelColor(0, Wheel(color));
      pixels.show();
      delay(5);
    }
    level++; // Advance to the next level
    delay(2000); // Longer delay for level transition
  } else {
    showNeoPixelColor(pixels.Color(255, 0, 0)); // Red color for incorrect press or no press
    level = 1; // Reset to level 1
    delay(2000); // Delay before restarting the game
  }
}

void showNeoPixelColor(uint32_t color) {
  pixels.clear();
  pixels.setPixelColor(0, color);
  pixels.show();
}

uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
    return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}