#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
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
void setup() {
Serial.begin(9600);
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.print("Welcome to");
lcd.setCursor(0, 1);
lcd.print("MasterMind");
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);
// Display initial game launch prompt
lcd.clear();
lcd.print("Press Save to");
lcd.setCursor(0, 1);
lcd.print("start the game");
// Wait for Save Button press to start the game
while (digitalRead(SAVE_BUTTON_PIN) == HIGH) {
// Do nothing
}
// Clear the LCD and start the game
lcd.clear();
lcd.print("Game started!");
delay(1000);
lcd.clear();
// Initialize the random seed
randomSeed(analogRead(A1));
// Generate the secret code
generateSecretCode();
// Start the game loop
gameActive = true;
}
void loop() {
if (gameActive) {
// Check for button presses and update the display
checkButtonPresses();
updateDisplay();
// Check if the player's guess is correct
if (checkGuess()) {
// Player guessed the correct code
gameActive = false;
lcd.clear();
lcd.print("You win!");
lcd.setCursor(0, 1);
lcd.print("Game over");
} else if (attemptsLeft == 0) {
// Player ran out of attempts
gameActive = false;
lcd.clear();
lcd.print("Looser! My secret");
lcd.setCursor(0, 1);
lcd.print("combination was ");
lcd.print(digits[0]);
lcd.print(digits[1]);
lcd.print(digits[2]);
lcd.print(digits[3]);
}
}
}
void generateSecretCode() {
for (int i = 0; i < 4; i++) {
digits[i] = random(1, 7); // Generate a random number from 1 to 6
}
}
void checkButtonPresses() {
// Check Button 1 state
if (millis() - debounceTime > DEBOUNCE_DELAY) {
int newButton1State = digitalRead(BUTTON1_PIN);
if (newButton1State != button1State) {
button1State = newButton1State;
if (button1State == LOW) {
// Button 1 was pressed
digit1 = (digit1 + 1) % 7; // Increment the digit value
}
debounceTime = millis();
}
}
// Check Button 2 state
if (millis() - debounceTime > DEBOUNCE_DELAY) {
int newButton2State = digitalRead(BUTTON2_PIN);
if (newButton2State != button2State) {
button2State = newButton2State;
if (button2State == LOW) {
// Button 2 was pressed
digit2 = (digit2 + 1) % 7; // Increment the digit value
}
debounceTime = millis();
}
}
// Check Button 3 state
if (millis() - debounceTime > DEBOUNCE_DELAY) {
int newButton3State = digitalRead(BUTTON3_PIN);
if (newButton3State != button3State) {
button3State = newButton3State;
if (button3State == LOW) {
// Button 3 was pressed
digit3 = (digit3 + 1) % 7; // Increment the digit value
}
debounceTime = millis();
}
}
// Check Button 4 state
if (millis() - debounceTime > DEBOUNCE_DELAY) {
int newButton4State = digitalRead(BUTTON4_PIN);
if (newButton4State != button4State) {
button4State = newButton4State;
if (button4State == LOW) {
// Button 4 was pressed
digit4 = (digit4 + 1) % 7; // Increment the digit value
}
debounceTime = millis();
}
}
// Check Save Button state
if (millis() - debounceTime > DEBOUNCE_DELAY) {
int newSaveButtonState = digitalRead(SAVE_BUTTON_PIN);
if (newSaveButtonState != saveButtonState) {
saveButtonState = newSaveButtonState;
if (saveButtonState == LOW) {
// Save Button was pressed
attemptsLeft--;
checkGuess(); // Check the player's guess
}
debounceTime = millis();
}
}
}
void updateDisplay() {
lcd.setCursor(0, 0);
lcd.print("Guess: ");
lcd.print(digit1);
lcd.print(digit2);
lcd.print(digit3);
lcd.print(digit4);
lcd.setCursor(0, 1);
lcd.print("Attempts: ");
lcd.print(attemptsLeft);
}
bool checkGuess() {
int guess[4] = {digit1, digit2, digit3, digit4};
// Check if the guess matches the secret code
for (int i = 0; i < 4; i++) {
if (guess[i] != digits[i]) {
return false; // Incorrect guess
}
}
return true; // Correct guess
}