// FULLY COMMENTED VERSION OF THE GAME CODE
// ------------------------------------------------------------
// This code implements a 4‑LED pattern memory game using:
// - 4 LEDs arranged as a square (A B on top, C D on bottom)
// - A joystick with a clickable button
// - A pushbutton used to restart the game after mistakes
// - A 7‑segment display used to show the current round number
//
// The game works like Simon Says:
// - Round = 1 to 9
// - Each round the game shows a pattern of LED actions
// - The pattern length increases each round
// - Player must copy the pattern using the joystick
// - If correct → next round
// - If incorrect → display shows "0" flashing, LEDs off, and player must press reset button to restart
// ------------------------------------------------------------
// LED SETUP (ACTIVE LOW)
// ------------------------------------------------------------
// LEDs are arranged physically like this:
// A B
// C D
//
// They are wired from 5V → LED → resistor → Arduino pin
// This means: digitalWrite(pin, LOW) = LED ON
// digitalWrite(pin, HIGH) = LED OFF
const int aled = 4; // LED A (top left)
const int bled = 2; // LED B (top right)
const int cled = A3; // LED C (bottom left)
const int dled = A5; // LED D (bottom right)
// Put the LED pins into an array so patterns can refer to them by index
// (0=A, 1=B, 2=C, 3=D)
int leds[4] = { aled, bled, cled, dled };
// Helper function to turn an LED ON (active low)
void ledOn(int pin) {
digitalWrite(pin, LOW);
}
// Helper function to turn an LED OFF (active low)
void ledOff(int pin) {
digitalWrite(pin, HIGH);
}
// ------------------------------------------------------------
// PATTERN DEFINITIONS
// ------------------------------------------------------------
// We define 5 patterns (A B), (C D), (A C), (B D), and (A B C D)
// Each pattern is stored as LED indexes. -1 marks the end of that pattern.
int patterns[5][4] = {
{0, 1, -1, -1}, // A B
{2, 3, -1, -1}, // C D
{0, 2, -1, -1}, // A C
{1, 3, -1, -1}, // B D
{0, 1, 2, 3} // A B C D
};
// ------------------------------------------------------------
// 7‑SEGMENT DISPLAY SETUP
// ------------------------------------------------------------
// (Assumes your wiring matches your original test code logic)
// Segments a-g connected to pins you previously used.
const int segA = 12;
const int segB = 13;
const int segC = 7;
const int segD = 8;
const int segE = 9;
const int segF = 11;
const int segG = 10;
// Array for selecting digits 0-9 (common cathode assumed)
int digits[10][7] = {
//a b c d e f g
{1,1,1,1,1,1,0}, // 0
{0,1,1,0,0,0,0}, // 1
{1,1,0,1,1,0,1}, // 2
{1,1,1,1,0,0,1}, // 3
{0,1,1,0,0,1,1}, // 4
{1,0,1,1,0,1,1}, // 5
{1,0,1,1,1,1,1}, // 6
{1,1,1,0,0,0,0}, // 7
{1,1,1,1,1,1,1}, // 8
{1,1,1,1,0,1,1} // 9
};
// Function to show a single digit (0–9) on the 7‑segment
void showDigit(int n) {
digitalWrite(segA, digits[n][0]);
digitalWrite(segB, digits[n][1]);
digitalWrite(segC, digits[n][2]);
digitalWrite(segD, digits[n][3]);
digitalWrite(segE, digits[n][4]);
digitalWrite(segF, digits[n][5]);
digitalWrite(segG, digits[n][6]);
}
// Flash the current round number 3 times before each new round begins
void flashRound(int r) {
for (int i = 0; i < 3; i++) {
showDigit(r);
delay(300);
showDigit(0); // display off
delay(200);
}
showDigit(r); // keep final number shown
}
// ------------------------------------------------------------
// RESET BUTTON
// ------------------------------------------------------------
// Player presses this only after they make a mistake
const int resetButton = 6; // or whichever pin your test code used
// ------------------------------------------------------------
// JOYSTICK INPUT SETUP
// ------------------------------------------------------------
const int xPin = A0;
const int yPin = A1;
const int joyPress = 5; // joystick button
// Thresholds for interpreting joystick movement
const int LEFT = 0;
const int RIGHT = 1023;
const int UP = 0;
const int DOWN = 1023;
// Function converts joystick actions into pattern indexes
// Returns: 0=A+B, 1=C+D, 2=A+C, 3=B+D, 4=ALL
// Or returns -1 if no valid action was made.
int readPlayerAction() {
int xVal = analogRead(xPin);
int yVal = analogRead(yPin);
int press = digitalRead(joyPress);
if (press == LOW) return 4; // ALL LEDs
if (xVal == LEFT) return 2; // A C
if (xVal == RIGHT) return 3; // B D
if (yVal == UP) return 0; // A B
if (yVal == DOWN) return 1; // C D
return -1; // no action yet
}
// ------------------------------------------------------------
// DISPLAYING PATTERNS
// ------------------------------------------------------------
// Prints a nice visual of the pattern to Serial Monitor
void printPatternVisual(int p) {
bool A = false, B = false, C = false, D = false;
for (int i = 0; i < 4; i++) {
int idx = patterns[p][i];
if (idx == -1) break;
if (idx == 0) A = true;
if (idx == 1) B = true;
if (idx == 2) C = true;
if (idx == 3) D = true;
}
Serial.println("---------------");
Serial.print(A ? "A " : "_ ");
Serial.println(B ? "B" : "_");
Serial.print(C ? "C " : "_ ");
Serial.println(D ? "D" : "_");
Serial.println("---------------");
Serial.println();
}
// Turns on LEDs for the selected pattern, displays them, then turns them off
void showPattern(int p) {
// turn on appropriate LEDs
for (int i = 0; i < 4; i++) {
int idx = patterns[p][i];
if (idx == -1) break;
ledOn(leds[idx]);
}
printPatternVisual(p);
delay(1000);
// Turn off all LEDs
for (int i = 0; i < 4; i++) ledOff(leds[i]);
delay(300);
}
// ------------------------------------------------------------
// GAME LOGIC
// ------------------------------------------------------------
// The game has 9 rounds.
// Each round shows a sequence of patterns that increases in length.
// Player must match them exactly.
void setup() {
Serial.begin(9600);
// initialize LEDs
for (int i = 0; i < 4; i++) {
pinMode(leds[i], OUTPUT);
ledOff(leds[i]);
}
// initialize joystick
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
pinMode(joyPress, INPUT_PULLUP);
// initialize reset button
pinMode(resetButton, INPUT_PULLUP);
// initialize 7‑segment pins
pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);
// random seed from unused/noisy analog pin
randomSeed(analogRead(A2));
Serial.println("Game ready!");
}
void flashZero() {
for (int i = 0; i < 6; i++) {
showDigit(0);
delay(200);
showDigit(8); // display all segments off
delay(200);
}
}
void waitForResetButton() {
Serial.println("Waiting for reset button...");
while (digitalRead(resetButton) == HIGH) {
delay(10);
}
}
void loop() {
int sequence[9]; // holds pattern sequence for entire game
// Generate all 9 required random patterns at start
for (int i = 0; i < 9; i++) {
sequence[i] = random(0, 5);
}
// MAIN GAME ROUNDS
for (int round = 1; round <= 9; round++) {
// Flash round number
flashRound(round);
Serial.print("ROUND "); Serial.println(round);
// Show the pattern up to current round number
for (int i = 0; i < round; i++) {
showPattern(sequence[i]);
}
Serial.println("-- PLAYER'S TURN --");
// Player must enter round actions
for (int i = 0; i < round; i++) {
int action = -1;
// Wait until player makes a joystick move
while (action == -1) {
action = readPlayerAction();
delay(30);
}
Serial.print("Player selected pattern index: ");
Serial.println(action);
// If wrong input, game over
if (action != sequence[i]) {
Serial.println("WRONG! GAME OVER.");
flashZero();
// LEDs all off
for (int j = 0; j < 4; j++) ledOff(leds[j]);
waitForResetButton();
return; // restart whole game
}
}
Serial.println("Correct! Next round...");
delay(800);
}
// Victory!
Serial.println("YOU WIN!");
showDigit(8); // show 8 as victory (all segments)
delay(2000);
}