/*
  Arduino | general-help
  ecz. — 1/13/25 at 12:50 PM

  heres my idea right

  Interactive potentiometer game.
  The tilt switch controls the status of the entire Arduino,
  it turns on or off the game. The potentiometer decides the servo's
  position, and the push button is used to score a point and turn off
  an LED. The game will function as one of 4 LEDs will light up
  randomly and we need to position the servo using the potentiometer
  to point towards the LED that is lit up. When it is positioned
  correctly we will press the push button, it will play a sound and
  will display 1 representing a point on the LCD. The score will
  increment by one every time you score a successful point.
  If the button is pushed when the servo isn't pointing toward the
  lit-up LED, Incorrect will be displayed on the same LCD, and the score
  will reset as a sign of losing the game.
*/

#include <Servo.h>
#include <LiquidCrystal.h>

// pin constants for the parallel LCD
const int RS = 12, EN = 11, D4 = 10, D5 = 9, D6 = 8, D7 = 7;
// other pin constants
const int tiltPin = 6;        // Tilt switch to turn the game on/off
const int potPin = A5;        // Potentiometer to control servo position
const int buttonPin = 4;      // Push button to score a point
const int buzzerPin = 5;      // Buzzer to play sound on successful point
const int ledPin1 = A3;        // Pin for LED 1
const int ledPin2 = A2;       // Pin for LED 2
const int ledPin3 = A1;       // Pin for LED 3
const int ledPin4 = A0;       // Pin for LED 4 (using analog pin A1)
const int servoPin = A4;      // Pin for servo control

// Create servo object
Servo pointerServo;
// create a parallel LCD object called "lcd"
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);

// global variables
int score = 0;                // Score counter
int currentLED = -1;          // Current lit LED
int servoPosition = 0;        // Servo position from potentiometer

// Function to reset all LEDs
void resetLEDs() {
  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin4, LOW);
}

// Function to light up the correct LED based on the random value
void lightUpLED(int led) {
  switch (led) {
    case 0:
      digitalWrite(ledPin1, HIGH);
      break;
    case 1:
      digitalWrite(ledPin2, HIGH);
      break;
    case 2:
      digitalWrite(ledPin3, HIGH);
      break;
    case 3:
      digitalWrite(ledPin4, HIGH);
      break;
  }
}

// Function to check if the servo is pointing at the correct LED
bool isCorrectPosition() {
  int servoThreshold = 15;  // Allowable range of deviation in servo angle
  int targetLEDPosition = 0;

  // Define target positions for each LED (mapped to servo angle)
  switch (currentLED) {
    case 0:
      targetLEDPosition = 45;
      break;
    case 1:
      targetLEDPosition = 90;
      break;
    case 2:
      targetLEDPosition = 135;
      break;
    case 3:
      targetLEDPosition = 180;
      break;
  }

  // Check if the servo is within a reasonable range of the target position
  if (abs(servoPosition - targetLEDPosition) <= servoThreshold) {
    return true;
  } else {
    return false;
  }
}

void setup() {
  // Initialize pins
  pinMode(tiltPin, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);

  // Initialize the servo
  pointerServo.attach(servoPin);

  // Initialize LCD
  lcd.begin(16, 2);
  lcd.print("Score: 0");

  // Display instructions
  lcd.setCursor(0, 1);
  lcd.print("Tilt to Start!");

  delay(2000);  // Show instructions for 2 seconds
}

void loop() {
  // Check if tilt switch is active (game is on)
  if (digitalRead(tiltPin) == LOW) {
    // Game is on, wait for potentiometer value
    servoPosition = map(analogRead(potPin), 0, 1023, 0, 180);  // Read potentiometer and map to servo range
    pointerServo.write(servoPosition);  // Move servo to the position based on potentiometer
    
    // Randomly light up one of the LEDs
    if (random(0, 4) != currentLED) {
      resetLEDs();
      currentLED = random(0, 4);
      lightUpLED(currentLED);
      delay(1000);  // LED stays on for 1 second
    }

    // Wait for button press to score
    if (digitalRead(buttonPin) == LOW) {
      // Check if the servo is pointing at the correct LED
      if (isCorrectPosition()) {
        score++;
        lcd.clear();
        lcd.print("Score: " + String(score));
        tone(buzzerPin, 1000, 200);  // Play sound for correct answer
      } else {
        score = 0;
        lcd.clear();
        lcd.print("Incorrect!");
        delay(1000);
        lcd.clear();
        lcd.print("Score: 0");
      }
      delay(1000);  // Debounce delay for the button press
    }
  } else {
    // Game is off (tilt switch is low)
    lcd.clear();
    lcd.print("Game Off");
    resetLEDs();
  }
}




$abcdeabcde151015202530354045505560fghijfghij
$abcdeabcde151015202530fghijfghij
Tilt
Game