#include <LiquidCrystal_I2C.h>
#define LCD_ADDRESS 0x27 // Change this to your LCD's address
#define LCD_COLUMNS 16 // Number of LCD columns
#define LCD_ROWS 2 // Number of LCD rows
#define BUTTON1_PIN 2 // Pin for Button 1
#define BUTTON2_PIN 3 // Pin for Button 2
#define BUTTON3_PIN 4 // Pin for Button 3
#define BUTTON4_PIN 5 // Pin for Button 4
#define SAVE_BUTTON_PIN A0 // Pin for Save Button
#define GUESS_BUTTON_PIN A0
#define LED1_RED_PIN 6 // Pin for LED 1 red channel
#define LED1_BLUE_PIN 7 // Pin for LED 1 blue channel
#define LED2_RED_PIN 8 // Pin for LED 2 red channel
#define LED2_BLUE_PIN 9 // Pin for LED 2 blue channel
#define LED3_RED_PIN 10 // Pin for LED 3 red channel
#define LED3_BLUE_PIN 11 // Pin for LED 3 blue channel
#define LED4_RED_PIN 12 // Pin for LED 4 red channel
#define LED4_BLUE_PIN 13 // Pin for LED 4 blue channel
#define DEBOUNCE_DELAY 200 // Debounce delay in milliseconds
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
int digit1 = 0; // First digit value
int digit2 = 0; // Second digit value
int digit3 = 0; // Third digit value
int digit4 = 0; // Fourth digit value
int digits[4]; // Array to store the digits
int guess[4]; // Temporary array to store player's guess
int prevguess[4];
bool button1State = HIGH; // Button 1 state
bool button2State = HIGH; // Button 2 state
bool button3State = HIGH; // Button 3 state
bool button4State = HIGH; // Button 4 state
bool saveButtonState = HIGH; // Save Button state
bool guessButtonState = HIGH; // Guess Button state
unsigned long debounceTime = 0; // Debounce timer
int attemptsLeft = 10; // Number of attempts left for the player
bool gameActive = false; // Flag to indicate if the game is active
int k=0;
void setup() {
Serial.begin(9600);
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.print("Secret digits?");
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(BUTTON3_PIN, INPUT_PULLUP);
pinMode(BUTTON4_PIN, INPUT_PULLUP);
pinMode(SAVE_BUTTON_PIN, INPUT_PULLUP);
pinMode(LED1_RED_PIN, OUTPUT);
pinMode(LED1_BLUE_PIN, OUTPUT);
pinMode(LED2_RED_PIN, OUTPUT);
pinMode(LED2_BLUE_PIN, OUTPUT);
pinMode(LED3_RED_PIN, OUTPUT);
pinMode(LED3_BLUE_PIN, OUTPUT);
pinMode(LED4_RED_PIN, OUTPUT);
pinMode(LED4_BLUE_PIN, OUTPUT);
// Turn off all LEDs initially
digitalWrite(LED1_RED_PIN, LOW);
digitalWrite(LED1_BLUE_PIN, LOW);
digitalWrite(LED2_RED_PIN, LOW);
digitalWrite(LED2_BLUE_PIN, LOW);
digitalWrite(LED3_RED_PIN, LOW);
digitalWrite(LED3_BLUE_PIN, LOW);
digitalWrite(LED4_RED_PIN, LOW);
digitalWrite(LED4_BLUE_PIN, LOW);
}
void loop() {
if (!gameActive) {
handleInput();
} else {
gameactive();
}
}
void handleInput() {
bool newSaveButtonState = digitalRead(SAVE_BUTTON_PIN);
bool newGuessButtonState = digitalRead(GUESS_BUTTON_PIN);
// Check if save button is pressed
if (newSaveButtonState != saveButtonState && millis() - debounceTime >= DEBOUNCE_DELAY) {
saveButtonState = newSaveButtonState;
if (saveButtonState == LOW) {
// Generate random numbers
randomSeed(millis()); // Initialize random seed
digits[0] = random(1, 10); // Generate random numbers between 1 and 9 (inclusive)
digits[1] = random(1, 10);
digits[2] = random(1, 10);
digits[3] = random(1, 10);
resetGame();
gameActive = true;
lcd.clear();
lcd.print("Welcome to");
lcd.setCursor(0, 1);
lcd.print("MasterMind");
delay(3500);
lcd.clear();
lcd.print("Your goal is to");
lcd.setCursor(0, 1);
lcd.print("guess my secret");
delay(3500);
lcd.clear();
lcd.print("Game Started!");
delay(1000); // Display game message for 1 second
}
debounceTime = millis();
}
// Display current digit values on the LCD
lcd.setCursor(0, 1);
lcd.print(digit1);
lcd.print(digit2);
lcd.print(digit3);
lcd.print(digit4);
}
void gameactive() {
// Read button state
bool newGuessButtonState = digitalRead(GUESS_BUTTON_PIN);
prevguess[0]=guess[0];
prevguess[1]=guess[1];
prevguess[2]=guess[2];
prevguess[3]=guess[3];
// Check if guess button state has changed
if (newGuessButtonState != guessButtonState && millis() - debounceTime >= DEBOUNCE_DELAY) {
guessButtonState = newGuessButtonState;
if (guessButtonState == LOW) {
attemptsLeft--;
// Check the number of digits guessed correctly
int correctDigits = 0;
int correctPositions = 0;
for (int i = 0; i < 4; i++) {
if (guess[i] == digits[i]) {
correctPositions++;
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (guess[i] == digits[j] && i != j) {
correctDigits++;
break;
}
}
}
// Serial.println("red led");
// Serial.println(correctPositions);
// Serial.println("blue led");
// Serial.println(correctDigits);
//delay(1000);
// Control LEDs based on the number of digits guessed correctly
controlLEDs(correctPositions, correctDigits);
displayAttempts();
k++;
if (guess[0] == digits[0] && guess[1] == digits[1] && guess[2] == digits[2] && guess[3] == digits[3]) {
lcd.clear();
lcd.print("Congratulations!");
delay(2000);
lcd.clear();
lcd.print("Secret digits?");
gameActive = false;
} else if (attemptsLeft == 0) {
lcd.clear();
lcd.print("Game Over!");
delay(2500);
lcd.clear();
lcd.print("My secret was!");
lcd.setCursor(0,1);
lcd.print(digits[0]);
lcd.print(digits[1]);
lcd.print(digits[2]);
lcd.print(digits[3]);
delay(2500);
lcd.clear();
lcd.print("Secret digits");
gameActive = false;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("0");
lcd.print(k);
lcd.print(":");
lcd.print(prevguess[0]);
lcd.print(prevguess[1]);
lcd.print(prevguess[2]);
lcd.print(prevguess[3]);
// delay(1000);
clearGuess();
updateDisplay();
}
}
debounceTime = millis();
}
// Read button states
bool newButton1State = digitalRead(BUTTON1_PIN);
bool newButton2State = digitalRead(BUTTON2_PIN);
bool newButton3State = digitalRead(BUTTON3_PIN);
bool newButton4State = digitalRead(BUTTON4_PIN);
// Check if any button state has changed
if (newButton1State != button1State && millis() - debounceTime >= DEBOUNCE_DELAY) {
button1State = newButton1State;
if (button1State == LOW) {
guess[0] = (guess[0] + 1) % 10;
updateDisplay();
}
debounceTime = millis();
}
if (newButton2State != button2State && millis() - debounceTime >= DEBOUNCE_DELAY) {
button2State = newButton2State;
if (button2State == LOW) {
guess[1] = (guess[1] + 1) % 10;
updateDisplay();
}
debounceTime = millis();
}
if (newButton3State != button3State && millis() - debounceTime >= DEBOUNCE_DELAY) {
button3State = newButton3State;
if (button3State == LOW) {
guess[2] = (guess[2] + 1) % 10;
updateDisplay();
}
debounceTime = millis();
}
if (newButton4State != button4State && millis() - debounceTime >= DEBOUNCE_DELAY) {
button4State = newButton4State;
if (button4State == LOW) {
guess[3] = (guess[3] + 1) % 10;
updateDisplay();
}
debounceTime = millis();
}
// // Check the number of digits guessed correctly
// int correctDigits = 0;
// int correctPositions = 0;
// for (int i = 0; i < 4; i++) {
// if (guess[i] == digits[i]) {
// correctPositions++;
// }
// }
// for (int i = 0; i < 4; i++) {
// for (int j = 0; j < 4; j++) {
// if (guess[i] == digits[j] && i != j) {
// correctDigits++;
// break;
// }
// }
// }
// // Serial.println("red led");
// // Serial.println(correctPositions);
// // Serial.println("blue led");
// // Serial.println(correctDigits);
// //delay(1000);
// // Control LEDs based on the number of digits guessed correctly
// controlLEDs(correctPositions, correctDigits);
}
void controlLEDs(int redLEDs, int blueLEDs) {
// Turn off all LEDs
digitalWrite(LED1_RED_PIN, LOW);
digitalWrite(LED1_BLUE_PIN, LOW);
digitalWrite(LED2_RED_PIN, LOW);
digitalWrite(LED2_BLUE_PIN, LOW);
digitalWrite(LED3_RED_PIN, LOW);
digitalWrite(LED3_BLUE_PIN, LOW);
digitalWrite(LED4_RED_PIN, LOW);
digitalWrite(LED4_BLUE_PIN, LOW);
// Turn on red LEDs for the correct positions
for (int i = 0; i < redLEDs; i++) {
switch (i) {
case 0:
digitalWrite(LED1_RED_PIN, HIGH);
break;
case 1:
digitalWrite(LED2_RED_PIN, HIGH);
break;
case 2:
digitalWrite(LED3_RED_PIN, HIGH);
break;
case 3:
digitalWrite(LED4_RED_PIN, HIGH);
break;
}
}
// Turn on blue LEDs for the correct digits in wrong positions
for (int i = 0; i < blueLEDs; i++) {
switch (i) {
case 0:
if (redLEDs < 1) {
digitalWrite(LED1_BLUE_PIN, HIGH);
} else if (redLEDs < 2) {
digitalWrite(LED2_BLUE_PIN, HIGH);
} else if (redLEDs < 3) {
digitalWrite(LED3_BLUE_PIN, HIGH);
} else if (redLEDs < 4) {
digitalWrite(LED4_BLUE_PIN, HIGH);
}
break;
case 1:
if (redLEDs < 2) {
digitalWrite(LED2_BLUE_PIN, HIGH);
} else if (redLEDs < 3) {
digitalWrite(LED3_BLUE_PIN, HIGH);
digitalWrite(LED4_BLUE_PIN, HIGH);
}
// else if (redLEDs < 4) {
// }
break;
case 2:
if (redLEDs < 3) {
digitalWrite(LED3_BLUE_PIN, HIGH);
} else if (redLEDs < 4) {
digitalWrite(LED4_BLUE_PIN, HIGH);
}
break;
case 3:
if (redLEDs < 4) {
digitalWrite(LED4_BLUE_PIN, HIGH);
}
break;
}
}
}
void displayAttempts() {
lcd.setCursor(0, 0);
lcd.print("Attempts Left: ");
lcd.print(attemptsLeft);
}
void clearGuess() {
for (int i = 0; i < 4; i++) {
guess[i] = 0;
}
}
void resetGame() {
attemptsLeft = 10;
k=0;
clearGuess();
lcd.clear();
displayAttempts();
}
void updateDisplay() {
lcd.setCursor(0, 1);
lcd.print(guess[0]);
lcd.print(guess[1]);
lcd.print(guess[2]);
lcd.print(guess[3]);
}