/* Rubal sidhu
January, 24, 2023
Description: This project is a LED chaser game. The way this game works is by pressing the pushbutton
the same time the colour given to you passes over. Through the usage of a 555 timer and
a decade counter, you can create a LED chaser. This modified version of the classic circuit
takes the output from the decade counter and compares that to the pulse of the pushbutton.
If both the pulses match, then the 4 digit 7 segment display adds one to the counter. If the
pulses do not match, the display removes one from the counter. Once the score reaches either 
10 and -10, the game ends and resets back to 0. This game is also made so that you can change
the difficulty through the usage of a potentiometer that changes the speed. 
*/
//Variables
//Here contains all the global variables used in the project

/*Variables for the pins connecting to the LED outputs*/
int led1 = 7;
int led2 = 11;
int led3 = 12;
int led4 = 10;
int led5 = 13;
int led6 = 9;
int led7 = 8;

/*Variables for the pins connecting to the 4 digit Seven segment display*/
int a = A5;
int b = A4;
int c = 4;
int d = A0;
int e = A1;
int f = 3;
int g = 2;

/*Variable for the pin connecting to the pushbutton*/
const int button = A2;

/*Variables for the score, the random colour, the initial message, and the print colour message(x)*/
int score = 0;
long randColour;
int x=0;
int initialMessage=0;


//------------------------------------------------------------------------------------------------------
//Setup function
//Function that initializes all the pins to either input or output
void setup()
{
  Serial.begin(9600);
  pinMode(led1, INPUT);
  pinMode(led2, INPUT);
  pinMode(led3, INPUT);
  pinMode(led4, INPUT);
  pinMode(led5, INPUT);
  pinMode(led6, INPUT);
  pinMode(led7, INPUT);
  pinMode(button, INPUT);



  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);

 
  randomSeed(analogRead(0));//Allows the random function to randomize the number
}

//------------------------------------------------------------------------------------------------------
//Loop function
//Here is where the main code is run, loops once the code is finished
void loop()
{
  while (initialMessage==0)/*While loop for the inital message, only displays once on the serial monitor*/
  {
    Serial.println("Welcome to my LED chaser game. In this game, a color will be displayed on the serial monitor.");
    Serial.println("Your job is click the button when the LED chaser passes over that light.");
    Serial.println("You win this game when you get 10 points. You lose when you reach -10 points.");
    Serial.println("Each correct gets one point and each wrong takes away one point.");
    Serial.println("Beware, the easy difficulty is already hard itself and you can make the game even harder with the potentiometer. Good Luck ");
    Serial.println();
    initialMessage++;/*Adds one to the variable so that the while loop cannot be open again*/
  }
 
  randColour = random(0,3);/*Generates a random number from 1-3 (including those) and sets that as the value for randColour*/

  if (randColour == 1)/*If randColour equals 1, runs the code for the colour red*/
  {
    while(x==0)/*Conditional Loop so that the colour is only displayed once on the serial monitor*/
    {
      Serial.println("The number Led you need to stop on is Red");
      x++;    
    }
   
    int buttonState = digitalRead(button);/*Sets button state to read the value of the pin connected to the button*/
    if ((buttonState==HIGH)&&((digitalRead(led1)==HIGH)||(digitalRead(led4)==HIGH)||(digitalRead(led7)==HIGH)))/*If the button is pressed and either Led 1,4, and 7 are on, adds one to the score*/
    {
      delay(500);/*Add a delay so that you only get one pulse from the button*/
      score = score+1;/*Adds one to the score*/
      displayScore(score);/*Runs the displayScore function with the score as the parameter*/
      Serial.print("Your score is ");
      Serial.println(score);/*Prints the Score on the serial monitor*/
      x=0;/*Sets x to 0 so that a new colour can be given*/
    }
    else if ((buttonState==HIGH)&&((digitalRead(led1)==LOW)||(digitalRead(led2)==HIGH)||(digitalRead(led3)==HIGH)||(digitalRead(led4)==LOW)||(digitalRead(led5)==HIGH)||(digitalRead(led6)==HIGH)||(digitalRead(led7)==LOW)))
    {         /*If any of the other LEDs are on, or if the listed ones off, then it subtracts one from the score*/
      score = score==0;/*Subtracts one from the score*/
      displayScore(score);
      Serial.print("Your score is ");
      Serial.println(score);
      x=0;
    }
  }

  else if (randColour == 2)/*If randColour equals 2, runs the code for the colour yellow*/
  {
    while (x==0)
    {
      Serial.println("The colour you need to stop on is Yellow");
      x++;
    }
    int buttonState = digitalRead(button);
    if ((buttonState==(HIGH))&&((digitalRead(led2)==HIGH)||(digitalRead(led5)==HIGH)))/*If the button is pressed and either Led 2 or 5 are on, adds one to the score*/
    {
      delay(500);
      score = score+1;
      displayScore(score);
      Serial.print("Your score is ");
      Serial.println(score);
      x=0;
    }
    else if ((buttonState==HIGH)&&((digitalRead(led1)==HIGH)||(digitalRead(led2)==LOW)||(digitalRead(led3)==HIGH)||(digitalRead(led4)==HIGH)||(digitalRead(led5)== LOW)||(digitalRead(led6)==HIGH)||(digitalRead(led7)==HIGH)))
    {        /*If any of the other LEDs are on, or if the listed ones off, then it subtracts one from the score*/
      score = score==0;
      displayScore(score);
      Serial.print("Your score is ");
      Serial.println(score);
      x=0;
    }
  }

  else if (randColour == 3)/*If randColour equals 3, runs the code for the colour green*/
  {
    while(x==0)
    {
      Serial.println("The colour you need to stop on is Green");
      x++;
    }
    int buttonState = digitalRead(button);
    if ((buttonState==(HIGH))&&((digitalRead(led3)==HIGH)||(digitalRead(led6)==HIGH)))/*If the button is pressed and either led 3 or 6 are on, adds one to the score*/
    {
      delay(500);
      score = score+1;
      displayScore(score);
      Serial.print("Your score is ");
      Serial.println(score);
      x=0;
    }
    else if ((buttonState==HIGH)&&((digitalRead(led1)==HIGH)||(digitalRead(led2)==HIGH)||(digitalRead(led3)==LOW)||(digitalRead(led4)==HIGH)||(digitalRead(led5)==HIGH)||(digitalRead(led6)==LOW)||(digitalRead(led7)==HIGH)))
    {         /*If any of the other LEDs are on, or if the listed ones off, then it subtracts one from the score*/
      score = score==0;
      displayScore(score);
      Serial.print("Your score is ");
      Serial.println(score);
      x=0;
    }
  }  
 
  if ((score==10)||(score==0))/*If the score equals either 10 or -10, sets the score back to 0*/
  {
    score=0;
  }
}

//------------------------------------------------------------------------------
//displayScore function
//Gets the score as a parameter and depending on if the score is positive or negative, displays a dash
void displayScore(int y)
{
  pickDigit(0);/*Calls on the pickDigit function to control the first digit*/
  if (y<0)/*If the score is less than 0, calls the dash function to light up the first digit*/
  {
  }
  else/*If the score is positive, displays a 0 instead of a dash*/
  {
    zero();
  }
  delay(500);/*Adds a delay*/
 
  pickDigit(1);/*Calls on pickDigit function to control the second digit*/
  pickNumber(abs(y));/*Sends the absolute value of the score as the parameter to the pickNumber function, to light up the second digit*/
  delay(100);/*Adds a delay*/
}

//------------------------------------------------------------------------------
//pickDigit Functions
//Chooses the digit on the display to be changed
void pickDigit(int x)
{
  /*The 7-segment LED display is a common-cathode so all the digits are set to HIGH to turn off*/


  switch(x)/*A switch based on which parameter is recieved, so that not all LED's are changed at once*/
  {
    case 0: /*If the parameter is 0, lights up the first digit*/

    break;
    case 1: /*If the parameter is 1, lights up the second digit*/
    break;
  }
}

//------------------------------------------------------------------------------
//pickNumber Function
//Using the parameter from the loop function, the pickNumber functions sets the parameter as the number for the specific digit selected
void pickNumber(int x)
{
  switch(x)
  {
    default: /*If the parameter is 0, 0 is displayed*/
    zero();
    break;
   
    case 1: /*If the parameter is 1, 1 is displayed*/
    one();
    break;
   
    case 2: /*If the parameter is 2, 2 is displayed*/
    two();
    break;
   
    case 3: /*If the parameter is 3, 3 is displayed*/
    three();
    break;
   
    case 4: /*If the parameter is 4, 4 is displayed*/
    four();
    break;
   
    case 5: /*If the parameter is 5, 5 is displayed*/
    five();
    break;
   
    case 6: /*If the parameter is 6, 6 is displayed*/
    six();
    break;
   
    case 7: /*If the parameter is 7, 7 is displayed*/
    seven();
    break;
   
    case 8: /*If the parameter is 8, 8 is displayed*/
    eight();
    break;
   
    case 9: /*If the parameter is 9, 9 is displayed*/
    nine();
    break;
  }
}

//------------------------------------------------------------------------------
//Functions to display each of the numbers
void zero() /*the 7-segment led display 0*/
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}

void one() /*the 7-segment led display 1*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void two() /*the 7-segment led display 2*/
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void three() /*the 7-segment led display 3*/
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void four() /*the 7-segment led display 4*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void five() /*the 7-segment led display 5*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void six() /*the 7-segment led display 6*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void seven() /*the 7-segment led display 7*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void eight() /*the 7-segment led display 8*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void nine() /*the 7-segment led display 9*/
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
