// Kayla Frost
// 300390878
// Arduino Final Project Phase 2
// Nov. 28, 2025
/*
I created a game on my Arduino. There are 4 LEDs set up in a square shape that will display a pattern of 5 actions for each round.
Either the top two, bottom two, left two, right two or all 4 LEDs will light up. The player must then remember the pattern and recreate it using the joystick and button.
If they succeed, they move on to the next round. If they beat the 9th round, they win.
The devices connected to my Arduino UNO R3 are the 7-segment display (connected to pins 7-13 and GND, and each LED pin has a 220ohm resistor),
the joystick (connected to pins A0, A1, and 5), and 4 LEDs: red (pin 4, top left), green (pin 2, top right), blue (pin A3, bottom left)
and yellow (pin A5, bottom right), each having a 330omn resistor.
NOTE: I consider the button on the joystick to be a separate input device from the actual joystick.
I originally had a regular button as well to use as a game restart button but I coulddn't figure out how to include it in time, so I omitted it.
*/
// 4 LEDs SETUP
//-----
// A B
// C D
//-----
// define LED pins
// KF note: I used 2 digital pins and 2 analog pins because I've run out of digital pins on my arduino for my whole project
const int aled = 4; // RED (top left) = A
const int bled = 2; // GREEN (top right) = B
const int cled = A3; // BLUE (bottom left) = C
const int dled = A5; // YELLOW (bottom right) = D
// array of LED pins in the order A B C D
int leds[4] = { aled, bled, cled, dled };
// KF note: LOW = LED on, HIGH = LED off
void ledOn(int pin) // function to turn on LED (pin number recieved by function)
{
digitalWrite(pin, LOW);
}
void ledOff(int pin) // function to turn off LED (pin number recieved by function)
{
digitalWrite(pin, HIGH);
}
// array to organize all possible LED actions
// each action will be a list of LED indexes that should turn on
// in LED array below, A = 0, B = 1, C = 2, D = 3 and -1 is a sentinel value
int patterns[5][4] = {
{0, 1, -1, -1}, // A B (top)
{2, 3, -1, -1}, // C D (bottom)
{0, 2, -1, -1}, // A C (left)
{1, 3, -1, -1}, // B D (right)
{0, 1, 2, 3} // A B C D (all)
};
// computer will randomly generate a 5-action pattern
int generated[5]; // which will be stored in this array
int player[5]; // this array will contain the 5 actions produced by the player's joystick (attempting to copy the generated pattern)
// JOYSTICK SETUP
const int xPin = A0; // horizontal (blue wire) in analog pin A0
const int yPin = A1; // vertical (green wire) in analog pin A1
const int switchPin = 5; // joystick button in digital pin 5
int xValue; // holds horizontal value of joystick's current position
int yValue; // holds vertical value of joystick's current position
int switchState; // holds state of button: pressed (LOW) or unpressed (HIGH)
//horizontal maximum constants
const int LEFT = 10; // if x is left, the min value is 10 (I tested that this is the minimum value my joystick's position holds)
const int RIGHT = 1023; // if x is right, the max value is 1023
// vertical maximum constants
const int UP = 10; // if y is up, the min value is 10 (I tested that this is the minimum value my joystick's position holds)
const int DOWN = 1023; // if y is down, the max value is 1023
// 7-SEGMENT DISPLAY SETUP
// define pins for each of the LEDs in the 7-segment display, ranging from pins 7 - 13
const int B = 13;
const int A = 12;
const int F = 11;
const int G = 10;
const int E = 9;
const int D = 8;
const int C = 7;
const int MAX_ROUNDS = 9;// maximum "round number" possible that the single digit display can show
int roundNum = 0; // holds current round number
void sevenOff() // function turns off all 7 LEDs in the 7 segment display
{
for(int x = 7; x <= 13; x++) // for each LED from pin 7 - 13
{
digitalWrite(x, LOW); // turns that LED off
}
}
void showNumber(int n) // function displays a specific number on the 7 segment display (function receives the round number player is currently on)
{
if(n == 0) // if round 0
{
// display 0
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, LOW);
}
else if(n == 1) // if round 1
{
// display 1
digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW);
}
else if(n == 2) // if round 2
{
// display 2
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, HIGH);
}
else if(n == 3) // if round 3
{
// display 3
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, HIGH);
}
else if(n == 4) // if round 4
{
// display 4
digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
}
else if(n == 5) // if round 5
{
// display 5
digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
}
else if(n == 6) // if round 6
{
// display 6
digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
}
else if(n == 7) // if round 7
{
// display 7
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW);
}
else if(n == 8) // if round 8
{
// display 8
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
}
else if(n == 9) // if round 9
{
// display 9
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
}
else if(n > MAX_ROUNDS) // if player has beat round 9 --> WINNER!
{
// flash the number 9 (x5) while simultaneously serial printing "WINNER!"
for(int x = 0; x <= 5; x++)
{
// display 9
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
Serial.println("WINNER!!!");
delay(300);
// display nothing
sevenOff();
delay(300);
}
// reset everything back to round 0 to restart the game
roundNum = 0;
showNumber(0);
}
}
void printPattern(int patternIndex) // fucntion prints the pattern onto the serial monitor
{
bool A_on = false, B_on = false, C_on = false, D_on = false; // 4 bools, each to track which LEDs should be on in the pattern
for(int x = 0; x < 4; x++)
{
int ledIndex = patterns[patternIndex][x];
if(ledIndex == -1) // -1 means that no more LEDs are on in the pattern, so exit the loop
{
break;
}
// each ledIndex value corresponds to a different LED being on
if(ledIndex == 0)
{
A_on = true; // A should be on
}
if(ledIndex == 1)
{
B_on = true; // B should be on
}
if(ledIndex == 2)
{
C_on = true; // C should be on
}
if(ledIndex == 3)
{
D_on = true; // D should be on
}
}
// KF note: should have new lines after B and D to create square effect in serial monitor
Serial.println("----");
Serial.print(A_on ? "A " : "_ "); // if A should be on, display A. if not, display a gap like (_)
Serial.println(B_on ? "B" : "_"); // if B should be on, display B. if not, display a gap like (_)
Serial.print(C_on ? "C " : "_ "); // if C should be on, display C. if not, display a gap like (_)
Serial.println(D_on ? "D" : "_"); // if D should be on, display D. if not, display a gap like (_)
Serial.println("----");
Serial.println();
}
void showPattern(int patternIndex) // function displays each action on the 4 LEDs
{
for(int x = 0; x < 4; x++)
{
int ledIndex = patterns[patternIndex][x]; // get LED index from pattern array
if(ledIndex == -1) // sentinel value indicates nomore LEDs should be turned on
{
break; // so exit the loop
}
ledOn(leds[ledIndex]); // turn on that LED
}
printPattern(patternIndex); // also print that pattern on the serial monitor
delay(1000);
for(int x = 0; x < 4; x++) // turn off all 4 LEDs before displaying the next action, but don't print this in serial monitor
{
ledOff(leds[x]);
}
delay(300);
}
int readJoystickAction() // function reads the data input from the joystick
{
while(true)
{
// read various joystick values of its current position
xValue = analogRead(xPin); // reads horizontal value
yValue = analogRead(yPin); // reads vertical value
switchState = digitalRead(switchPin); // reads the button's state
if(switchState == LOW) // if joystick button is pressed
{
return 4; // 4 indicates that ABCD LEDs should light up
}
if(xValue <= LEFT) // if joystick is pushed to the left
{
return 2; // 2 indicates that AC LEDs should light up
}
if(xValue == RIGHT) // if joystick is pushed to the right
{
return 3; // 3 indicates that BD LEDs should light up
}
if(yValue <= UP) // if joystick is pushed up
{
return 0; // 0 indicates that AB LEDs should light up
}
if(yValue == DOWN) // if joystick is pushed down
{
return 1; // 1 indicates that CD LEDs should light up
}
}
}
void resetGame() // function resets the game
{
// turn off all 4 LEDs
for(int x = 0; x < 4; x++)
{
ledOff(leds[x]);
}
roundNum = 0; // set round number back to 0
showNumber(0); // display round 0
}
void setup() {
Serial.begin(9600); // to print things in serial monitor
// set each LED pin in array as an output and turn off initially
for(int x = 0; x < 4; x++)
{
pinMode(leds[x], OUTPUT); // set LED pin as output device
ledOff(leds[x]); // turn LED off
}
// set each LED in the 7 segemnt display as an output and turn off initially
for(int x = 7; x <= 13; x++) // these LEDs go from pins 7 - 13
{
pinMode(x, OUTPUT); // set LED pin as output device
digitalWrite(x, LOW); // turn LED off
}
// define three pins in joystick as inputs
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
pinMode(switchPin, INPUT_PULLUP); // use input pullup for button
// use random seed to pick a random pattern
// read from analog pin A2, which is not connected or used for any other purpose/component!
randomSeed(analogRead(A2));
resetGame(); // call function to set up the game
// print game instructions
Serial.println("\nGAME INSTRUCTIONS\nWatch the pattern of the 4 LEDs carefully and copy it using the joystick.\nMove the joystick up, down, left and right, or click joystick button to light up all 4 at once.\n");
}
void loop() {
showNumber(roundNum); // display the round number on the 7 segment display
// Generate a random pattern, consisting of 5 actions chosen out of the 5 possible actions
Serial.println("PATTERN TO COPY:\n");
for(int i = 0; i < 5; i++) // loop for each of the 5 random actions in pattern
{
generated[i] = random(0, 5); // generate random number from 0-5, associated with a possible action
showPattern(generated[i]); // display that action on 4 LEDs
}
// Player must replicate the randomly generated pattern on the 4 LEDs by moving the joystick or pressing the joystick button
Serial.println("YOUR TURN:\n");
for(int i = 0; i < 5; i++)
{
player[i] = readJoystickAction(); // receives an action number and puts it in array to be compared with the generated action array
showPattern(player[i]); // display each current action player does witht the joystick
delay(300); // teensy delay so player can enter in their actions slowly and with precision
}
// Compare the generated pattern array witht he player's inputted pattern
bool success = true; // shows whether patterns are matching or not
for(int i = 0; i < 5; i++)
{
if(player[i] != generated[i]) // if any of the array's cells do not match with the other array
{
success = false; // then the patterns do not match
break; // so it should exit the loop early because a mismatch was found
}
}
if(success == true) // if the patterns do match, print "CORRECT" and increment round counter
{
Serial.println("CORRECT!\n");
roundNum++; // increment round number
delay(1000);
return; // restart the loop to move on to next round
}
// I fthe arrays do not match, the player has unsuccessfully copied the generated pattern and the game is over
Serial.println("WRONG! GAME OVER.\n");
for(int x = 0; x < 4; x++) // turn off all LEDs
{
ledOff(leds[x]);
}
sevenOff(); // turn off 7 segment display
delay(1500);
resetGame(); // reset the game, back to round 0
}