#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
// Pin definitions for RGB lamps (PWM capable pins)
const int middleRGB[] = {9, 10, 11}; // Red, Green, Blue for the middle lamp
const int playerRGB[4][3] = {
{2, 3, 4}, // Player 1 RGB
{5, 6, 7}, // Player 2 RGB
{8, A0, A1}, // Player 3 RGB
{A2, A3, A4} // Player 4 RGB
};
// Button pins for each player
const int buttons[4][3] = {
{22, 23, 24}, // Player 1: Red, Green, Blue buttons
{25, 26, 27}, // Player 2: Red, Green, Blue buttons
{28, 29, 30}, // Player 3: Red, Green, Blue buttons
{31, 32, 33} // Player 4: Red, Green, Blue buttons
};
const int numberOfPlayers = 4; // Define the number of players
bool activePlayers[numberOfPlayers]; // Array to track active players
unsigned long levelStartTime; // Start time of the level
const unsigned long level0TimeLimit = 20000; // Set time limit for each level (e.g., 30 seconds)
const unsigned long level1TimeLimit = 15000; // Set time limit for each level (e.g., 30 seconds)
const unsigned long level2TimeLimit = 15000; // Set time limit for each level (e.g., 30 seconds)
const unsigned long level3TimeLimit = 15000; // Set time limit for each level (e.g., 30 seconds)
const unsigned long level4TimeLimit = 15000; // Set time limit for each level (e.g., 30 seconds)
// Game settings
const int level0PatternLength = 4; // Fixed pattern length for Level 0
const int level1PatternLength = 4; // Fixed pattern length for Level 1
const int level2PatternLength = 6; // Fixed pattern length for Level 2
const int level3PatternLength = 6; // Fixed pattern length for Level 3
const int level4PatternLength = 6; // Fixed pattern length for Level 4
int level0Pattern[level0PatternLength]; // Array to hold random pattern for Level 0
int level1Pattern[level1PatternLength]; // Array to hold random pattern for Level 1
int level2Pattern[level2PatternLength]; // Array to hold random pattern for Level 2
int level3Pattern[level3PatternLength]; // Array to hold random pattern for Level 3
int level4Pattern[level4PatternLength]; // Array to hold random pattern for Level 4
bool gameWon = false; // Tracks if a player has won
int playerPressCount[4] = {0, 0, 0, 0}; // Track number of presses for each player
int playerInput[4][level4PatternLength]; // Store inputs for each player
bool playerFinished[4] = {false, false, false, false}; // Track if each player has finished
// Delays for showing patterns for hardness control
const int level0Delay = 700; // Delay for Level 0 pattern display
const int level1Delay = 600; // Delay for Level 1 pattern display
const int level2Delay = 600; // Delay for Level 2 pattern display
const int level3Delay = 500; // Delay for Level 3 pattern display
const int level4Delay = 400; // Delay for Level 4 pattern display
void setup() {
Serial.begin(9600); // Initialize serial communication
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
lcd.clear(); // Clear the display
randomSeed(analogRead(0)); // Seed the random number generator
// Set up RGB lamps and buttons as outputs and inputs
for (int i = 0; i < 3; i++) {
pinMode(middleRGB[i], OUTPUT);
for (int j = 0; j < 4; j++) {
pinMode(playerRGB[j][i], OUTPUT);
pinMode(buttons[j][i], INPUT_PULLUP); // Buttons for each player
}
}
showPurple();
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(3, 0); // Set cursor to the first row, first column
lcd.print("Welcome To");
lcd.setCursor(5, 1);
lcd.print("NEXUS");
delay(3000);
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(2, 0); // Set cursor to the first row, first column
lcd.print("MADE BY THE");
lcd.setCursor(4, 1);
lcd.print("MAVRIKS");
delay(3000);
Serial.println("Start of Level 0 (Tutorial)"); // Indicate start of Level 0
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("start of Level 0");
lcd.setCursor(0, 1);
lcd.print("(Tutorial)");
delay(3000);
lcd.clear();
runLevel0();
}
void loop() {
// Code that runs repeatedly goes here
}
// Generates a random pattern of colors for Level 0 (Red and Green)
void generateRandomPatternLevel0() {
for (int i = 0; i < level0PatternLength; i++) {
level0Pattern[i] = random(0, 2); // Randomly select 0 (Red) or 1 (Green)
}
}
// Displays the pattern using the middle RGB lamp for Level 0
void showPatternLevel0() {
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Tutorial");
lcd.setCursor(0, 1); // Set cursor to the first row, first column
lcd.print("Showing Battern");
Serial.println("Level 0 Pattern:"); // Print header to Serial Monitor
for (int i = 0; i < level0PatternLength; i++) {
if (level0Pattern[i] == 0) {
Serial.println("Red"); // Print "Red" if 0
} else {
Serial.println("Green"); // Print "Green" if 1
}
setMiddleRGB(level0Pattern[i]); // Display the color for Level 0
delay(level0Delay); // Display color for Level 0 pattern delay
setMiddleRGB(-1); // Turn off
delay(200); // Delay before showing the next color
}
Serial.println("Pattern display completed."); // Indicate end of pattern
lcd.clear();
}
// Generates a random pattern of colors for Level 1 (RGB)
void generateRandomPatternLevel1() {
for (int i = 0; i < level1PatternLength; i++) {
level1Pattern[i] = random(0, 3); // Randomly select 0 (Red), 1 (Green), or 2 (Blue)
}
}
// Displays the pattern using the middle RGB lamp for Level 1
void showPatternLevel1() {
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Level 1");
lcd.setCursor(0, 1); // Set cursor to the first row, first column
lcd.print("Showing Pattern");
Serial.println("Level 1 Pattern:"); // Print header to Serial Monitor
for (int i = 0; i < level1PatternLength; i++) {
if (level1Pattern[i] == 0) {
Serial.println("Red"); // Print "Red" if 0
} else if (level1Pattern[i] == 1) {
Serial.println("Green"); // Print "Green" if 1
} else {
Serial.println("Blue"); // Print "Blue" if 2
}
setMiddleRGB(level1Pattern[i]); // Display the color for Level 1
delay(level1Delay); // Display color for Level 1 pattern delay
setMiddleRGB(-1); // Turn off
delay(200); // Delay before showing the next color
}
Serial.println("Pattern display completed."); // Indicate end of pattern
lcd.clear();
}
// Generates a random pattern of colors for Level 2 (RGB)
void generateRandomPatternLevel2() {
for (int i = 0; i < level2PatternLength; i++) {
level2Pattern[i] = random(0, 3); // Randomly select 0 (Red), 1 (Green), or 2 (Blue)
}
}
// Displays the pattern using the middle RGB lamp for Level 2
void showPatternLevel2() {
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Level 2");
lcd.setCursor(0, 1); // Set cursor to the first row, first column
lcd.print("Showing Pattern");
Serial.println("Level 2 Pattern:"); // Print header to Serial Monitor
for (int i = 0; i < level2PatternLength; i++) {
if (level2Pattern[i] == 0) {
Serial.println("Red"); // Print "Red" if 0
} else if (level2Pattern[i] == 1) {
Serial.println("Green"); // Print "Green" if 1
} else {
Serial.println("Blue"); // Print "Blue" if 2
}
setMiddleRGB(level2Pattern[i]); // Display the color for Level 2
delay(level2Delay); // Display color for Level 2 pattern delay
setMiddleRGB(-1); // Turn off
delay(200); // Delay before showing the next color
}
Serial.println("Pattern display completed."); // Indicate end of pattern
lcd.clear();
}
// Generates a random pattern of colors for Level 3 (RGB)
void generateRandomPatternLevel3() {
for (int i = 0; i < level3PatternLength; i++) {
level3Pattern[i] = random(0, 3); // Randomly select 0 (Red), 1 (Green), or 2 (Blue)
}
}
// Displays the pattern using the middle RGB lamp for Level 3
void showPatternLevel3() {
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Level 3");
lcd.setCursor(0, 1); // Set cursor to the first row, first column
lcd.print("Showing Pattern");
Serial.println("Level 3 Pattern:"); // Print header to Serial Monitor
for (int i = 0; i < level3PatternLength; i++) {
if (level3Pattern[i] == 0) {
Serial.println("Red"); // Print "Red" if 0
} else if (level3Pattern[i] == 1) {
Serial.println("Green"); // Print "Green" if 1
} else {
Serial.println("Blue"); // Print "Blue" if 2
}
setMiddleRGB(level3Pattern[i]); // Display the color for Level 3
delay(level3Delay); // Display color for Level 3 pattern delay
setMiddleRGB(-1); // Turn off
delay(200); // Delay before showing the next color
}
Serial.println("Pattern display completed."); // Indicate end of pattern
lcd.clear();
}
// Generates a random pattern of colors for Level 4 (RGB)
void generateRandomPatternLevel4() {
for (int i = 0; i < level4PatternLength; i++) {
level4Pattern[i] = random(0, 3); // Randomly select 0 (Red), 1 (Green), or 2 (Blue)
}
}
// Displays the pattern using the middle RGB lamp for Level 4
void showPatternLevel4() {
// Display on the LCD
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Level 4");
lcd.setCursor(0, 1); // Set cursor to the first row, first column
lcd.print("Showing Pattern");
Serial.println("Level 4 Pattern:"); // Print header to Serial Monitor
for (int i = 0; i < level4PatternLength; i++) {
if (level4Pattern[i] == 0) {
Serial.println("Red"); // Print "Red" if 0
} else if (level4Pattern[i] == 1) {
Serial.println("Green"); // Print "Green" if 1
} else {
Serial.println("Blue"); // Print "Blue" if 2
}
setMiddleRGB(level4Pattern[i]); // Display the color for Level 4
delay(level4Delay); // Display color for Level 4 pattern delay
setMiddleRGB(-1); // Turn off
delay(200); // Delay before showing the next color
}
Serial.println("Pattern display completed."); // Indicate end of pattern
lcd.clear();
}
// Run Level 0 (Tutorial)
void runLevel0() {
// Define a variable to track the timing of your pattern display
unsigned long previousMillis = 0; // Store the last time pattern was updated
const long interval = 100; // Interval for checking player presses
// Ensure all players are active before starting Level 0
for (int player = 0; player < 4; player++) {
activePlayers[player] = true; // Mark all players as active at the start of the tutorial
}
resetAllLamps(); // Reset lamps for Level 0
generateRandomPatternLevel0(); // Generate random pattern for Level 0
showwhite(); // Show white on all lamps
showPatternLevel0(); // Display the pattern for Level 0
delay(1000); // Give some time to view the pattern
levelStartTime = millis(); // Start the timer for this level
resetAllLamps(); // Reset lamps again
resetPlayerPresses(); // Reset player press counts for Level 0
gameWon = false; // Reset game state for Level 0
unsigned long previousPrintMillis = 0; // For controlling how often to print to the Serial Plotter
while (!gameWon) {
unsigned long currentMillis = millis(); // Get the current time
// Check if the time limit has been exceeded
if (currentMillis - levelStartTime >= level0TimeLimit) {
Serial.println("Time's up! Checking players' status.");
bool allInactive = true; // Flag to check if all players are inactive
// Mark any player who hasn't finished as inactive
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
setPlayerRGB(player, 255, 255, 0); // Set this player's lamp to yellow for inactive
activePlayers[player] = false; // Mark this player as inactive
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive due to time out.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print("Inactive");
delay(2000);
lcd.clear();
} else {
allInactive = false; // At least one player is still active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early
}
// If there are still active players, proceed to determine winners and losers
break; // Exit the loop to avoid checking presses further
}
// Print the remaining time to the Serial Plotter every second
if (currentMillis - previousPrintMillis >= 1000) {
previousPrintMillis = currentMillis; // Update the last print time
unsigned long remainingTime = (level0TimeLimit - (currentMillis - levelStartTime)) / 1000; // Remaining time in seconds
// Ensure remaining time is not negative (in case time exceeds the limit)
if (remainingTime < 0) {
remainingTime = 0;
}
Serial.print("Remaining Time: ");
Serial.println(remainingTime); // Print the remaining time
// Display on the LCD
if(remainingTime == 9){
lcd.clear(); // Clear the LCD before printing
}
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Remaining Time:");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(remainingTime); // Show the remaining time
}
// Check player button presses frequently
checkPlayerButtonslvl0(); // Check button presses for all players
// Check if any active players have completed their presses
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && playerPressCount[player] >= level0PatternLength) {
playerFinished[player] = true; // Mark this player as finished
// Optional: Set the lamp color to indicate completion
showwhite(player); // Turn this player's lamp white if they finish their presses
}
}
// *** New Condition to End Game Early if All Players Have Finished ***
bool allFinished = true; // Assume all players have finished
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
allFinished = false; // At least one player hasn't finished
break;
}
}
// If all players are finished, end the game early
if (allFinished) {
Serial.println("All players have finished their presses.");
gameWon = true; // Set the flag to indicate Level 0 is finished
break; // Exit the loop
}
}
// After exiting the loop, determine the winners and losers
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("LEVEL ENDED");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("showing results"); // Show the remaining time
delay(2000);
determineWinnerslvl0(); // Ensure winners and losers are determined after the game ends
transitionToLevel1(); // Handle the transition to the next level
resetAllLamps(); // Reset lamps before Level 1
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 1 started");
delay(1500);
Serial.println("Level 1 started ..."); // Indicate transition to Level 1
runLevel1(); // Start Level 1
}
// Run Level 1
void runLevel1() {
// Define a variable to track the timing of your pattern display
unsigned long previousMillis = 0; // Store the last time pattern was updated
const long interval = 100; // Interval for checking player presses
resetAllLamps(); // Reset lamps for Level 1
generateRandomPatternLevel1(); // Generate random pattern for Level 1
showwhite(); // Show white on all lamps
showPatternLevel1(); // Display the pattern for Level 1
delay(1000); // Give some time to view the pattern
levelStartTime = millis(); // Start the timer for this level
resetAllLamps(); // Reset lamps again
setInactiveLampsyellow();
resetPlayerPresses(); // Reset player press counts for Level 1
gameWon = false; // Reset game state for Level 1
unsigned long previousPrintMillis = 0; // For controlling how often to print to the Serial Plotter
while (!gameWon) {
unsigned long currentMillis = millis(); // Get the current time
// Check if the time limit has been exceeded
if (currentMillis - levelStartTime >= level1TimeLimit) {
Serial.println("Time's up! Checking players' status.");
bool allInactive = true; // Flag to check if all players are inactive
// Mark any player who hasn't finished as inactive
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
setPlayerRGB(player, 255, 255, 0); // Set this player's lamp to yellow for inactive
activePlayers[player] = false; // Mark this player as inactive
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive due to time out.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Player");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print("inactive");
delay(2000);
} else {
allInactive = false; // At least one player is still active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early
}
}
// Print the remaining time to the Serial Plotter every second
if (currentMillis - previousPrintMillis >= 1000) {
previousPrintMillis = currentMillis; // Update the last print time
unsigned long remainingTime = (level1TimeLimit - (currentMillis - levelStartTime)) / 1000; // Remaining time in seconds
// Ensure remaining time is not negative (in case time exceeds the limit)
if (remainingTime < 0) {
remainingTime = 0;
}
Serial.print("Remaining Time: ");
Serial.println(remainingTime); // Print the remaining time
// Display on the LCD
if(remainingTime == 9){
lcd.clear(); // Clear the LCD before printing
}
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Remaining Time:");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(remainingTime); // Show the remaining time
}
// Check player button presses frequently
checkPlayerButtonslvl1(); // Check button presses for all players
// Check if any active players have completed their presses
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && playerPressCount[player] >= level1PatternLength) {
playerFinished[player] = true; // Mark this player as finished
showwhite(player); // Turn this player's lamp white if they finish their presses
}
}
// Check if all active players have finished
bool allActiveFinished = true; // Flag to check if all active players are finished
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && !playerFinished[player]) {
allActiveFinished = false; // At least one active player hasn't finished
break;
}
}
// If all active players have finished, determine the winners
if (allActiveFinished) {
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("LEVEL ENDED");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("showing results"); // Show the remaining time
delay(2000);
determineWinnerslvl1();
Serial.println("All active players have finished their presses.");
gameWon = true; // Set the flag to indicate Level 1 is finished
break; // Exit the loop
}
}
// Check if any players are still active after finishing
if (checkAllInactive()) {
Serial.println("All players inactive. Game Over.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early if all players are inactive
} else {
// Continue to Level 2 if there are active players
transitionToLevel2(); // Handle the transition to the next level
resetAllLamps(); // Reset lamps before Level 2
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 2 started");
delay(1500);
Serial.println("Level 2 started ..."); // Indicate transition to Level 2
runLevel2(); // Start Level 2
}
}
// Run Level 2
void runLevel2() {
// Define a variable to track the timing of your pattern display
unsigned long previousMillis = 0; // Store the last time pattern was updated
const long interval = 100; // Interval for checking player presses
resetAllLamps(); // Reset lamps for Level 2
generateRandomPatternLevel2(); // Generate random pattern for Level 2
showwhite(); // Show white on all lamps
showPatternLevel2(); // Display the pattern for Level 2
delay(1000); // Give some time to view the pattern
levelStartTime = millis(); // Start the timer for this level
resetAllLamps(); // Reset lamps again
setInactiveLampsyellow();
resetPlayerPresses(); // Reset player press counts for Level 2
gameWon = false; // Reset game state for Level 2
unsigned long previousPrintMillis = 0; // For controlling how often to print to the Serial Plotter
while (!gameWon) {
unsigned long currentMillis = millis(); // Get the current time
// Check if the time limit has been exceeded
if (currentMillis - levelStartTime >= level2TimeLimit) {
Serial.println("Time's up! Checking players' status.");
bool allInactive = true; // Flag to check if all players are inactive
// Mark any player who hasn't finished as inactive
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
setPlayerRGB(player, 255, 255, 0); // Set this player's lamp to yellow for inactive
activePlayers[player] = false; // Mark this player as inactive
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive due to time out.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Player");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print("inactive");
delay(2000);
} else {
allInactive = false; // At least one player is still active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early
}
}
// Print the remaining time to the Serial Plotter every second
if (currentMillis - previousPrintMillis >= 1000) {
previousPrintMillis = currentMillis; // Update the last print time
unsigned long remainingTime = (level2TimeLimit - (currentMillis - levelStartTime)) / 1000; // Remaining time in seconds
// Ensure remaining time is not negative (in case time exceeds the limit)
if (remainingTime < 0) {
remainingTime = 0;
}
Serial.print("Remaining Time: ");
Serial.println(remainingTime); // Print the remaining time
// Display on the LCD
if(remainingTime == 9){
lcd.clear(); // Clear the LCD before printing
}
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Remaining Time:");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(remainingTime); // Show the remaining time
}
// Check player button presses frequently
checkPlayerButtonslvl2(); // Check button presses for all players
// Check if any active players have completed their presses
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && playerPressCount[player] >= level2PatternLength) {
playerFinished[player] = true; // Mark this player as finished
showwhite(player); // Turn this player's lamp white if they finish their presses
}
}
// Check if all active players have finished
bool allActiveFinished = true; // Flag to check if all active players are finished
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && !playerFinished[player]) {
allActiveFinished = false; // At least one active player hasn't finished
break;
}
}
// If all active players have finished, determine the winners
if (allActiveFinished) {
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("LEVEL ENDED");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("showing results"); // Show the remaining time
delay(2000);
determineWinnerslvl2();
Serial.println("All active players have finished their presses.");
gameWon = true; // Set the flag to indicate Level 2 is finished
break; // Exit the loop
}
}
// After exiting the loop, determine the winners and losers
bool allInactive = true; // Flag to check if all players are inactive
// Check the status of each player
for (int player = 0; player < 4; player++) {
if (activePlayers[player]) {
allInactive = false; // At least one player is still active
break; // No need to check further if one player is active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("Game Over.");
delay(3000); // Display message for 3 seconds
gameWon = true; // Set game state to indicate the game is over
return; // Exit the function
}
// Check if any players are still active after finishing
if (checkAllInactive()) {
Serial.println("All players inactive. Game Over.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early if all players are inactive
} else {
// Continue to Level 2 if there are active players
transitionToLevel3(); // Handle the transition to the next level
resetAllLamps(); // Reset lamps before Level 3
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 3 started");
delay(1500);
Serial.println("Level 3 started ..."); // Indicate transition to Level 3
runLevel3(); // Start Level 3
}
}
// Run Level 3
void runLevel3() {
// Define a variable to track the timing of your pattern display
unsigned long previousMillis = 0; // Store the last time pattern was updated
const long interval = 100; // Interval for checking player presses
resetAllLamps(); // Reset lamps for Level 3
generateRandomPatternLevel3(); // Generate random pattern for Level 3
showwhite(); // Show white on all lamps
showPatternLevel3(); // Display the pattern for Level 3
delay(1000); // Give some time to view the pattern
levelStartTime = millis(); // Start the timer for this level
resetAllLamps(); // Reset lamps again
setInactiveLampsyellow();
resetPlayerPresses(); // Reset player press counts for Level 3
gameWon = false; // Reset game state for Level 3
unsigned long previousPrintMillis = 0; // For controlling how often to print to the Serial Plotter
while (!gameWon) {
unsigned long currentMillis = millis(); // Get the current time
// Check if the time limit has been exceeded
if (currentMillis - levelStartTime >= level3TimeLimit) {
Serial.println("Time's up! Checking players' status.");
bool allInactive = true; // Flag to check if all players are inactive
// Mark any player who hasn't finished as inactive
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
setPlayerRGB(player, 255, 255, 0); // Set this player's lamp to yellow for inactive
activePlayers[player] = false; // Mark this player as inactive
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive due to time out.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Player");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print("inactive");
delay(2000);
} else {
allInactive = false; // At least one player is still active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early
}
}
// Print the remaining time to the Serial Plotter every second
if (currentMillis - previousPrintMillis >= 1000) {
previousPrintMillis = currentMillis; // Update the last print time
unsigned long remainingTime = (level3TimeLimit - (currentMillis - levelStartTime)) / 1000; // Remaining time in seconds
// Ensure remaining time is not negative (in case time exceeds the limit)
if (remainingTime < 0) {
remainingTime = 0;
}
Serial.print("Remaining Time: ");
Serial.println(remainingTime); // Print the remaining time
// Display on the LCD
if(remainingTime == 9){
lcd.clear(); // Clear the LCD before printing
}
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Remaining Time:");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(remainingTime); // Show the remaining time
}
// Check player button presses frequently
checkPlayerButtonslvl3(); // Check button presses for all players
// Check if any active players have completed their presses
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && playerPressCount[player] >= level3PatternLength) {
playerFinished[player] = true; // Mark this player as finished
showwhite(player); // Turn this player's lamp white if they finish their presses
}
}
// Check if all active players have finished
bool allActiveFinished = true; // Flag to check if all active players are finished
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && !playerFinished[player]) {
allActiveFinished = false; // At least one active player hasn't finished
break;
}
}
// If all active players have finished, determine the winners
if (allActiveFinished) {
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("LEVEL ENDED");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("showing results"); // Show the remaining time
delay(2000);
determineWinnerslvl3();
Serial.println("All active players have finished their presses.");
gameWon = true; // Set the flag to indicate Level 3 is finished
break; // Exit the loop
}
}
{ bool allInactive = true; // Flag to check if all players are inactive
// Check the status of each player
for (int player = 0; player < 4; player++) {
if (activePlayers[player]) {
allInactive = false; // At least one player is still active
break; // No need to check further if one player is active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(" Game Over.");
delay(3000); // Display message for 3 seconds
gameWon = true; // Set game state to indicate the game is over
return; // Exit the function
}
}
// Check if any players are still active after finishing
if (checkAllInactive()) {
Serial.println("All players inactive. Game Over.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early if all players are inactive
} else {
// Continue to Level 2 if there are active players
transitionToLevel4(); // Handle the transition to the next level
resetAllLamps(); // Reset lamps before Level 4
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 4 started");
delay(1500);
Serial.println("Level 4 started ..."); // Indicate transition to Level 4
runLevel4(); // Start Level 4
}
}
// Run Level 4
void runLevel4() {
// Define a variable to track the timing of your pattern display
unsigned long previousMillis = 0; // Store the last time pattern was updated
const long interval = 100; // Interval for checking player presses
resetAllLamps(); // Reset lamps for Level 4
generateRandomPatternLevel4(); // Generate random pattern for Level 4
showwhite(); // Show white on all lamps
showPatternLevel4(); // Display the pattern for Level 4
delay(1000); // Give some time to view the pattern
levelStartTime = millis(); // Start the timer for this level
resetAllLamps(); // Reset lamps again
setInactiveLampsyellow();
resetPlayerPresses(); // Reset player press counts for Level 4
gameWon = false; // Reset game state for Level 4
unsigned long previousPrintMillis = 0; // For controlling how often to print to the Serial Plotter
while (!gameWon) {
unsigned long currentMillis = millis(); // Get the current time
// Check if the time limit has been exceeded
if (currentMillis - levelStartTime >= level4TimeLimit) {
Serial.println("Time's up! Checking players' status.");
bool allInactive = true; // Flag to check if all players are inactive
// Mark any player who hasn't finished as inactive
for (int player = 0; player < 4; player++) {
if (!playerFinished[player]) {
setPlayerRGB(player, 255, 255, 0); // Set this player's lamp to yellow for inactive
activePlayers[player] = false; // Mark this player as inactive
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive due to time out.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Player");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print("inactive");
delay(2000);
} else {
allInactive = false; // At least one player is still active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1);
lcd.print(" Game Over.");
delay(3000);
return; // Exit the function early
}
}
// Print the remaining time to the Serial Plotter every second
if (currentMillis - previousPrintMillis >= 1000) {
previousPrintMillis = currentMillis; // Update the last print time
unsigned long remainingTime = (level4TimeLimit - (currentMillis - levelStartTime)) / 1000; // Remaining time in seconds
// Ensure remaining time is not negative (in case time exceeds the limit)
if (remainingTime < 0) {
remainingTime = 0;
}
Serial.print("Remaining Time: ");
Serial.println(remainingTime); // Print the remaining time
// Display on the LCD
if(remainingTime == 9){
lcd.clear(); // Clear the LCD before printing
}
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("Remaining Time:");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(remainingTime); // Show the remaining time
}
// Check player button presses frequently
checkPlayerButtonslvl4(); // Check button presses for all players
// Check if any active players have completed their presses
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && playerPressCount[player] >= level4PatternLength) {
playerFinished[player] = true; // Mark this player as finished
showwhite(player); // Turn this player's lamp white if they finish their presses
}
}
// Check if all active players have finished
bool allActiveFinished = true; // Flag to check if all active players are finished
for (int player = 0; player < 4; player++) {
if (activePlayers[player] && !playerFinished[player]) {
allActiveFinished = false; // At least one active player hasn't finished
break;
}
}
// If all active players have finished, determine the winners
if (allActiveFinished) {
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("LEVEL ENDED");
lcd.setCursor(0, 1); // Move to the second row
lcd.print("showing results"); // Show the remaining time
delay(2000);
determineWinnerslvl4();
Serial.println("All active players have finished their presses.");
gameWon = true; // Set the flag to indicate Level 4 is finished
break; // Exit the loop
}
}
// After exiting the loop, determine the winners and losers
bool allInactive = true; // Flag to check if all players are inactive
// Check the status of each player
for (int player = 0; player < 4; player++) {
if (activePlayers[player]) {
allInactive = false; // At least one player is still active
break; // No need to check further if one player is active
}
}
// If all players are inactive, end the game
if (allInactive) {
Serial.println("All players are inactive. Game Over.");
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0); // Set cursor to the first row, first column
lcd.print("ALL Inactive");
lcd.setCursor(0, 1); // Move to the second row
lcd.print(" Game Over.");
delay(3000); // Display message for 3 seconds
gameWon = true; // Set game state to indicate the game is over
return; // Exit the function
}
resetAllLamps(); // Reset lamps after the game is over
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("GAME ENDED");
lcd.setCursor(0, 1);
lcd.print("congratulations");
Serial.println("GAME ENDED"); // End the game after Level 4
}
// Resets the players' presses
void resetPlayerPresses() {
for (int i = 0; i < 4; i++) {
playerPressCount[i] = 0; // Reset the count for each player
playerFinished[i] = false; // Reset the finished status
}
}
bool previousButtonState[4][3] = { { HIGH, HIGH, HIGH }, { HIGH, HIGH, HIGH }, { HIGH, HIGH, HIGH }, { HIGH, HIGH, HIGH } };
void checkPlayerButtonslvl0() {
for (int player = 0; player < 4; player++) {
// Only check for active players and players who haven't finished
if (activePlayers[player] && !playerFinished[player]) {
for (int i = 0; i < 3; i++) {
int currentButtonState = digitalRead(buttons[player][i]);
// Only count the press if the button was released before being pressed again
if (currentButtonState == LOW && previousButtonState[player][i] == HIGH) { // Button is pressed
// Light up player's lamp with pressed color
int red = (i == 0) ? 255 : 0; // Red if button 1 pressed
int green = (i == 1) ? 255 : 0; // Green if button 2 pressed
int blue = (i == 2) ? 255 : 0; // Blue if button 3 pressed
Serial.print("Player ");
Serial.print(player + 1);
Serial.print(" pressed ");
Serial.print((i == 0) ? "Red" : (i == 1) ? "Green" : "Blue");
Serial.println();
setPlayerRGB(player, red, green, blue); // Use direct color values for player lamps
delay(100); // Keep the lamp lit for 100 milliseconds
setPlayerRGB(player, 0, 0, 0); // Turn off player's lamp after delay
// Store the pressed button
if (playerPressCount[player] < level0PatternLength) {
playerInput[player][playerPressCount[player]] = i; // Store the pressed button index
playerPressCount[player]++; // Increment the press count
delay(50); // Small delay between presses
}
}
// Update the previous state to the current state for the next loop
previousButtonState[player][i] = currentButtonState;
}
// Check if the player has completed the required presses
if (playerPressCount[player] >= level0PatternLength) {
playerFinished[player] = true; // Mark player as finished
}
}
}
}
void checkPlayerButtonslvl1() {
for (int player = 0; player < 4; player++) {
// Only check for active players and players who haven't finished
if (activePlayers[player] && !playerFinished[player]) {
for (int i = 0; i < 3; i++) {
int currentButtonState = digitalRead(buttons[player][i]);
// Only count the press if the button was released before being pressed again
if (currentButtonState == LOW && previousButtonState[player][i] == HIGH) { // Button is pressed
// Light up player's lamp with pressed color
int red = (i == 0) ? 255 : 0; // Red if button 1 pressed
int green = (i == 1) ? 255 : 0; // Green if button 2 pressed
int blue = (i == 2) ? 255 : 0; // Blue if button 3 pressed
Serial.print("Player ");
Serial.print(player + 1);
Serial.print(" pressed ");
Serial.print((i == 0) ? "Red" : (i == 1) ? "Green" : "Blue");
Serial.println();
setPlayerRGB(player, red, green, blue); // Use direct color values for player lamps
delay(100); // Keep the lamp lit for 100 milliseconds
setPlayerRGB(player, 0, 0, 0); // Turn off player's lamp after delay
// Store the pressed button
if (playerPressCount[player] < level1PatternLength) {
playerInput[player][playerPressCount[player]] = i; // Store the pressed button index
playerPressCount[player]++; // Increment the press count
delay(50); // Small delay between presses
}
}
// Update the previous state to the current state for the next loop
previousButtonState[player][i] = currentButtonState;
}
// Check if the player has completed the required presses
if (playerPressCount[player] >= level1PatternLength) {
playerFinished[player] = true; // Mark player as finished
}
}
}
}
void checkPlayerButtonslvl2() {
for (int player = 0; player < 4; player++) {
// Only check for active players and players who haven't finished
if (activePlayers[player] && !playerFinished[player]) {
for (int i = 0; i < 3; i++) {
int currentButtonState = digitalRead(buttons[player][i]);
// Only count the press if the button was released before being pressed again
if (currentButtonState == LOW && previousButtonState[player][i] == HIGH) { // Button is pressed
// Light up player's lamp with pressed color
int red = (i == 0) ? 255 : 0; // Red if button 1 pressed
int green = (i == 1) ? 255 : 0; // Green if button 2 pressed
int blue = (i == 2) ? 255 : 0; // Blue if button 3 pressed
Serial.print("Player ");
Serial.print(player + 1);
Serial.print(" pressed ");
Serial.print((i == 0) ? "Red" : (i == 1) ? "Green" : "Blue");
Serial.println();
setPlayerRGB(player, red, green, blue); // Use direct color values for player lamps
delay(100); // Keep the lamp lit for 100 milliseconds
setPlayerRGB(player, 0, 0, 0); // Turn off player's lamp after delay
// Store the pressed button
if (playerPressCount[player] < level2PatternLength) {
playerInput[player][playerPressCount[player]] = i; // Store the pressed button index
playerPressCount[player]++; // Increment the press count
delay(50); // Small delay between presses
}
}
// Update the previous state to the current state for the next loop
previousButtonState[player][i] = currentButtonState;
}
// Check if the player has completed the required presses
if (playerPressCount[player] >= level2PatternLength) {
playerFinished[player] = true; // Mark player as finished
}
}
}
}
void checkPlayerButtonslvl3() {
for (int player = 0; player < 4; player++) {
// Only check for active players and players who haven't finished
if (activePlayers[player] && !playerFinished[player]) {
for (int i = 0; i < 3; i++) {
int currentButtonState = digitalRead(buttons[player][i]);
// Only count the press if the button was released before being pressed again
if (currentButtonState == LOW && previousButtonState[player][i] == HIGH) { // Button is pressed
// Light up player's lamp with pressed color
int red = (i == 0) ? 255 : 0; // Red if button 1 pressed
int green = (i == 1) ? 255 : 0; // Green if button 2 pressed
int blue = (i == 2) ? 255 : 0; // Blue if button 3 pressed
Serial.print("Player ");
Serial.print(player + 1);
Serial.print(" pressed ");
Serial.print((i == 0) ? "Red" : (i == 1) ? "Green" : "Blue");
Serial.println();
setPlayerRGB(player, red, green, blue); // Use direct color values for player lamps
delay(100); // Keep the lamp lit for 100 milliseconds
setPlayerRGB(player, 0, 0, 0); // Turn off player's lamp after delay
// Store the pressed button
if (playerPressCount[player] < level3PatternLength) {
playerInput[player][playerPressCount[player]] = i; // Store the pressed button index
playerPressCount[player]++; // Increment the press count
delay(50); // Small delay between presses
}
}
// Update the previous state to the current state for the next loop
previousButtonState[player][i] = currentButtonState;
}
// Check if the player has completed the required presses
if (playerPressCount[player] >= level3PatternLength) {
playerFinished[player] = true; // Mark player as finished
}
}
}
}
void checkPlayerButtonslvl4() {
for (int player = 0; player < 4; player++) {
// Only check for active players and players who haven't finished
if (activePlayers[player] && !playerFinished[player]) {
for (int i = 0; i < 3; i++) {
int currentButtonState = digitalRead(buttons[player][i]);
// Only count the press if the button was released before being pressed again
if (currentButtonState == LOW && previousButtonState[player][i] == HIGH) { // Button is pressed
// Light up player's lamp with pressed color
int red = (i == 0) ? 255 : 0; // Red if button 1 pressed
int green = (i == 1) ? 255 : 0; // Green if button 2 pressed
int blue = (i == 2) ? 255 : 0; // Blue if button 3 pressed
Serial.print("Player ");
Serial.print(player + 1);
Serial.print(" pressed ");
Serial.print((i == 0) ? "Red" : (i == 1) ? "Green" : "Blue");
Serial.println();
setPlayerRGB(player, red, green, blue); // Use direct color values for player lamps
delay(100); // Keep the lamp lit for 100 milliseconds
setPlayerRGB(player, 0, 0, 0); // Turn off player's lamp after delay
// Store the pressed button
if (playerPressCount[player] < level4PatternLength) {
playerInput[player][playerPressCount[player]] = i; // Store the pressed button index
playerPressCount[player]++; // Increment the press count
delay(50); // Small delay between presses
}
}
// Update the previous state to the current state for the next loop
previousButtonState[player][i] = currentButtonState;
}
// Check if the player has completed the required presses
if (playerPressCount[player] >= level4PatternLength) {
playerFinished[player] = true; // Mark player as finished
}
}
}
}
// Determine winners for lvl 0 based on player inputs
void determineWinnerslvl0() {
for (int player = 0; player < 4; player++) {
// Skip displaying result for inactive players
if (!activePlayers[player]) {
continue; // Move to the next player if the player is inactive
}
bool correct = true; // Assume the player's input is correct
for (int i = 0; i < level0PatternLength; i++) {
if (playerInput[player][i] != level0Pattern[i]) {
correct = false; // Found an incorrect input
break;
}
}
// Show result for each player
if (correct) {
setPlayerRGB(player, 0, 255, 0); // Green for correct
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" wins!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" wins!");
delay(1500);
activePlayers[player] = true; // Keep player active for the next level
} else {
setPlayerRGB(player, 255, 0, 0); // Red for incorrect
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" loses!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" loses!");
delay(1500);
// Keep all players active for the next level in the tutorial (Level 0)
}
}
Serial.println("LEVEL 0 ENDED");
// Display on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tutorial Ended");
delay(3000); // Show the message for 3 seconds
lcd.clear();
}
// Determine winners for lvl 1 based on player inputs
void determineWinnerslvl1() {
for (int player = 0; player < 4; player++) {
// Skip displaying result for inactive players
if (!activePlayers[player]) {
continue; // Move to the next player if the player is inactive
}
bool correct = true; // Assume the player's input is correct
for (int i = 0; i < level1PatternLength; i++) {
if (playerInput[player][i] != level1Pattern[i]) {
correct = false; // Found an incorrect input
break;
}
}
// Show result for each player
if (correct) {
setPlayerRGB(player, 0, 255, 0); // Green for correct
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" wins!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" wins!");
delay(1500);
activePlayers[player] = true; // Keep player active for the next level
} else {
setPlayerRGB(player, 255, 0, 0); // Red for incorrect
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" loses!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" loses!");
delay(1500);
activePlayers[player] = false; // Mark this player as inactive (loser)
}
}
Serial.println("LEVEL 1 ENDED");
// Display on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 1 Ended");
delay(3000); // Show the message for 3 seconds
lcd.clear();
}
// Determine winners for lvl 2 based on player inputs
void determineWinnerslvl2() {
for (int player = 0; player < 4; player++) {
// Skip displaying result for inactive players
if (!activePlayers[player]) {
continue; // Move to the next player if the player is inactive
}
bool correct = true; // Assume the player's input is correct
for (int i = 0; i < level2PatternLength; i++) {
if (playerInput[player][i] != level2Pattern[i]) {
correct = false; // Found an incorrect input
break;
}
}
// Show result for each player
if (correct) {
setPlayerRGB(player, 0, 255, 0); // Green for correct
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" wins!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" wins!");
delay(1500);
activePlayers[player] = true; // Keep player active for the next level
} else {
setPlayerRGB(player, 255, 0, 0); // Red for incorrect
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" loses!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" loses!");
delay(1500);
activePlayers[player] = false; // Mark this player as inactive (loser)
}
}
Serial.println("LEVEL 2 ENDED");
// Display on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 2 Ended");
delay(3000); // Show the message for 3 seconds
lcd.clear();
}
// Determine winners for lvl 3 based on player inputs
void determineWinnerslvl3() {
for (int player = 0; player < 4; player++) {
// Skip displaying result for inactive players
if (!activePlayers[player]) {
continue; // Move to the next player if the player is inactive
}
bool correct = true; // Assume the player's input is correct
for (int i = 0; i < level3PatternLength; i++) {
if (playerInput[player][i] != level3Pattern[i]) {
correct = false; // Found an incorrect input
break;
}
}
// Show result for each player
if (correct) {
setPlayerRGB(player, 0, 255, 0); // Green for correct
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" wins!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" wins!");
delay(1500);
activePlayers[player] = true; // Keep player active for the next level
} else {
setPlayerRGB(player, 255, 0, 0); // Red for incorrect
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" loses!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" loses!");
delay(1500);
activePlayers[player] = false; // Mark this player as inactive (loser)
}
}
Serial.println("LEVEL 3 ENDED");
// Display on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 3 Ended");
delay(3000); // Show the message for 3 seconds
lcd.clear();
}
// Determine winners for lvl 4 based on player inputs
void determineWinnerslvl4() {
for (int player = 0; player < 4; player++) {
// Skip displaying result for inactive players
if (!activePlayers[player]) {
continue; // Move to the next player if the player is inactive
}
bool correct = true; // Assume the player's input is correct
for (int i = 0; i < level4PatternLength; i++) {
if (playerInput[player][i] != level4Pattern[i]) {
correct = false; // Found an incorrect input
break;
}
}
// Show result for each player
if (correct) {
setPlayerRGB(player, 0, 255, 0); // Green for correct
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" wins!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" wins!");
delay(1500);
activePlayers[player] = true; // Keep player active for the next level
} else {
setPlayerRGB(player, 255, 0, 0); // Red for incorrect
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" loses!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(player + 1);
lcd.setCursor(0, 1);
lcd.print(" loses!");
delay(1500);
activePlayers[player] = false; // Mark this player as inactive (loser)
}
}
Serial.println("LEVEL 4 ENDED");
// Display on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level 4 Ended");
delay(3000); // Show the message for 3 seconds
lcd.clear();
}
// Resets all RGB lamps to off
void resetAllLamps() {
setMiddleRGB(-1); // Middle lamp off
for (int player = 0; player < 4; player++) {
setPlayerRGB(player, 0, 0, 0); // Set player lamps to off
playerFinished[player] = false; // Reset finished status
}
}
// Show purple on all lamps for the given duration
void showPurple() {
// Set all lamps to purple
for (int player = 0; player < 4; player++) {
setPlayerRGB(player, 255, 0, 255); // Purple
}
setMiddleRGB(255); // Middle lamp purple
}
// Set the middle RGB lamp color based on the index
void setMiddleRGB(int colorIndex) {
if (colorIndex == 0) { // Red
analogWrite(middleRGB[0], 255);
analogWrite(middleRGB[1], 0);
analogWrite(middleRGB[2], 0);
} else if (colorIndex == 1) { // Green
analogWrite(middleRGB[0], 0);
analogWrite(middleRGB[1], 255);
analogWrite(middleRGB[2], 0);
} else if (colorIndex == 2) { // Blue
analogWrite(middleRGB[0], 0);
analogWrite(middleRGB[1], 0);
analogWrite(middleRGB[2], 255);
} else if (colorIndex == -1) { // Turn off
analogWrite(middleRGB[0], 0);
analogWrite(middleRGB[1], 0);
analogWrite(middleRGB[2], 0);
} else if (colorIndex == 255) { // Purple
analogWrite(middleRGB[0], 255);
analogWrite(middleRGB[1], 0);
analogWrite(middleRGB[2], 255);
}else if (colorIndex == 3) { // white
analogWrite(middleRGB[0], 255);
analogWrite(middleRGB[1], 255);
analogWrite(middleRGB[2], 255);
}
}
// Set the RGB lamp for a specific player
void setPlayerRGB(int player, int red, int green, int blue) {
analogWrite(playerRGB[player][0], red);
analogWrite(playerRGB[player][1], green);
analogWrite(playerRGB[player][2], blue);
}
// Show white on players lamps for the given duration
void showwhite() {
// Set all lamps to whtie
for (int player = 0; player < 4; player++) {
setPlayerRGB(player, 255, 255, 255); // white
}
}
void setPlayerRGB(int player, int colorIndex) {
// Ensure player index is valid
if (player < 0 || player >= 4) return;
if (colorIndex == 0) { // Red
analogWrite(playerRGB[player][0], 255); // Red
analogWrite(playerRGB[player][1], 0); // Green
analogWrite(playerRGB[player][2], 0); // Blue
} else if (colorIndex == 1) { // Green
analogWrite(playerRGB[player][0], 0); // Red
analogWrite(playerRGB[player][1], 255); // Green
analogWrite(playerRGB[player][2], 0); // Blue
} else if (colorIndex == 2) { // Blue
analogWrite(playerRGB[player][0], 0); // Red
analogWrite(playerRGB[player][1], 0); // Green
analogWrite(playerRGB[player][2], 255); // Blue
} else if (colorIndex == -1) { // Turn off
analogWrite(playerRGB[player][0], 0); // Red
analogWrite(playerRGB[player][1], 0); // Green
analogWrite(playerRGB[player][2], 0); // Blue
} else if (colorIndex == 255) { // Purple
analogWrite(playerRGB[player][0], 255); // Red
analogWrite(playerRGB[player][1], 0); // Green
analogWrite(playerRGB[player][2], 255); // Blue
} else if (colorIndex == 3) { // White
analogWrite(playerRGB[player][0], 255); // Red
analogWrite(playerRGB[player][1], 255); // Green
analogWrite(playerRGB[player][2], 255); // Blue
}
}
void showwhite(int player) {
// Set the specified player's lamp to white
setPlayerRGB(player, 3); // Use color index 3 for white
}
void setInactiveLampsyellow() {
for (int player = 0; player < 4; player++) {
if (!activePlayers[player]) { // Check if the player is inactive
setPlayerRGB(player, 255, 255, 0); // Set the inactive player's lamp to orange
Serial.print("Player ");
Serial.print(player + 1);
Serial.println(" is inactive and lamp set to yellow.");
}
}
}
void transitionToLevel1() {
unsigned long startMillis = millis(); // Record the start time
int countdownValue = 5; // Countdown from 5
bool countdownActive = true;
// Show purple on all lamps
showPurple(); // Set lamps to purple for 5 seconds
while (countdownActive) {
unsigned long currentMillis = millis(); // Get the current time
// Check if 5 seconds have passed
if (currentMillis - startMillis < 5000) {
// Check if one second has passed since the last update
if (currentMillis - startMillis >= (5000 - countdownValue * 1000)) {
// Display countdown
lcd.setCursor(0, 0);
lcd.print("Level 1 in...");
lcd.setCursor(0, 1);
lcd.print(countdownValue); // Print current countdown value
// Decrement countdown value
countdownValue--;
}
} else {
countdownActive = false; // Stop the countdown after 5 seconds
}
}
// Reset the lamps after countdown is done
resetAllLamps(); // Reset lamps to off
}
void transitionToLevel2() {
unsigned long startMillis = millis(); // Record the start time
int countdownValue = 5; // Countdown from 5
bool countdownActive = true;
// Show purple on all lamps
showPurple(); // Set lamps to purple for 5 seconds
while (countdownActive) {
unsigned long currentMillis = millis(); // Get the current time
// Check if 5 seconds have passed
if (currentMillis - startMillis < 5000) {
// Check if one second has passed since the last update
if (currentMillis - startMillis >= (5000 - countdownValue * 1000)) {
// Display countdown
lcd.setCursor(0, 0);
lcd.print("Level 2 in...");
lcd.setCursor(0, 1);
lcd.print(countdownValue); // Print current countdown value
// Decrement countdown value
countdownValue--;
}
} else {
countdownActive = false; // Stop the countdown after 5 seconds
}
}
// Reset the lamps after countdown is done
resetAllLamps(); // Reset lamps to off
}
void transitionToLevel3() {
unsigned long startMillis = millis(); // Record the start time
int countdownValue = 5; // Countdown from 5
bool countdownActive = true;
// Show purple on all lamps
showPurple(); // Set lamps to purple for 5 seconds
while (countdownActive) {
unsigned long currentMillis = millis(); // Get the current time
// Check if 5 seconds have passed
if (currentMillis - startMillis < 5000) {
// Check if one second has passed since the last update
if (currentMillis - startMillis >= (5000 - countdownValue * 1000)) {
// Display countdown
lcd.setCursor(0, 0);
lcd.print("Level 3 in...");
lcd.setCursor(0, 1);
lcd.print(countdownValue); // Print current countdown value
// Decrement countdown value
countdownValue--;
}
} else {
countdownActive = false; // Stop the countdown after 5 seconds
}
}
// Reset the lamps after countdown is done
resetAllLamps(); // Reset lamps to off
}
void transitionToLevel4() {
unsigned long startMillis = millis(); // Record the start time
int countdownValue = 5; // Countdown from 5
bool countdownActive = true;
// Show purple on all lamps
showPurple(); // Set lamps to purple for 5 seconds
while (countdownActive) {
unsigned long currentMillis = millis(); // Get the current time
// Check if 5 seconds have passed
if (currentMillis - startMillis < 5000) {
// Check if one second has passed since the last update
if (currentMillis - startMillis >= (5000 - countdownValue * 1000)) {
// Display countdown
lcd.setCursor(0, 0);
lcd.print("Level 4 in...");
lcd.setCursor(0, 1);
lcd.print(countdownValue); // Print current countdown value
// Decrement countdown value
countdownValue--;
}
} else {
countdownActive = false; // Stop the countdown after 5 seconds
}
}
// Reset the lamps after countdown is done
resetAllLamps(); // Reset lamps to off
}
bool checkAllInactive() {
// Loop through each player
for (int player = 0; player < 4; player++) {
// If any player is active, return false
if (activePlayers[player]) {
return false;
}
}
// If all players are inactive, return true
return true;
}