Fun Arduino Number Guessing Game With LCD Display – Beginner-Friendly

by _Stemonkey in Circuits > Arduino

40 Views, 0 Favorites, 0 Comments

Fun Arduino Number Guessing Game With LCD Display – Beginner-Friendly

Screenshot 2024-10-12 113243.png
Screenshot 2024-10-12 113211.png
Screenshot 2024-10-12 113108.png

Introduction

Have you ever wanted to bring a classic number-guessing game to life using electronics? This project allows you to do just that using an Arduino, a 4x4 keypad, and an I2C LCD. The game is simple: guess the number selected by the Arduino, and you'll receive feedback on whether your guess is too high, too low, or correct. You get a limited number of attempts to guess the number, and if you run out, the correct answer will be revealed.

This project is perfect for beginners looking to improve their skills with Arduino, user input, and LCDs. It’s also a fun way to create an interactive game that you can play with friends and family.




Supplies

Materials Needed

  1. Arduino Uno: The main controller for the project.
  2. 4x4 Matrix Keypad: For user input (guessing the number).
  3. I2C 16x2 LCD Display: To display the game prompts and feedback.
  4. Buzzer: (Optional) For sound feedback on correct and incorrect guesses.
  5. Breadboard and Jumper Wires: For connecting components. (additional)

Circuit Diagram

  1. Connect the Keypad:
  2. The 4x4 keypad has 8 pins, which connect to the Arduino’s digital pins. (check the image)
  3. Connect the LCD:
  4. The I2C LCD connects to the Arduino’s SDA and SCL pins (typically A4 and A5).
  5. Connect the Buzzer (Optional):
  6. Connect the positive pin of the buzzer to a digital pin (e.g., pin 11) and the negative pin to the ground.

Code Overview

Here’s a breakdown of how the code works:

1. Setup and Initialization

  1. The LCD and keypad are initialized in the setup() function. The LCD is configured to display prompts, and the keypad is used to take input from the user.

2. Starting a New Game

  1. The startNewGame() function sets up a new round by generating a random number within the selected range (0-9 or 0-99). It also displays the initial prompt for the user to enter their guess.

3. User Input and Validation

  1. The user enters their guess via the keypad. The input is displayed on the LCD, and the game checks if the guess is within the valid range.
  2. If the guess is out of range, an error message is displayed, and the user is prompted to enter a valid number.

4. Checking the Guess

  1. The checkGuess() function compares the user’s guess to the target number.
  2. If the guess is correct, a congratulatory message is displayed, and the game restarts.
  3. If the guess is incorrect, feedback is given (too high or too low), and the remaining number of attempts is displayed.
  4. If the user runs out of attempts, the correct number is revealed before restarting the game.

5. Game Modes

  1. The game has two modes:
  2. 0-9 Range: The player has 3 attempts to guess a number between 0 and 9.
  3. 0-99 Range: The player has 7 attempts to guess a number between 0 and 99.
  4. The player can toggle between these two modes using the C key.

6. Additional Features

  1. The A key provides help, explaining how to play the game and the functions of the keys.
  2. The B key allows the user to backspace and correct their input.
  3. A buzzer provides audio feedback for correct and incorrect guesses.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

// Initialize the I2C LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Keypad setup
const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

int targetNumber;
int guessCount = 0;
int maxAttempts;
String guessInput = "";
int buzzerPin = 11;
bool isRange99 = false; // Start with guessing range 0-9
bool buzzerEnabled = true; // Buzzer state

void setup() {
lcd.init();
lcd.backlight();
pinMode(buzzerPin, OUTPUT);
randomSeed(analogRead(0)); // Initialize random seed

startNewGame();
}

void loop() {
char key = customKeypad.getKey();

if (key) {
if (key >= '0' && key <= '9') {
// Limit input based on range
if ((isRange99 && guessInput.length() < 2) || (!isRange99 && guessInput.length() < 1)) {
guessInput += key;
updateDisplay();
} else {
displayLimitMessage();
}
} else if (key == '#') {
if (guessInput.length() > 0) {
int guessedNumber = guessInput.toInt();
int maxValue = isRange99 ? 99 : 9;
if (guessedNumber >= 0 && guessedNumber <= maxValue) {
checkGuess(guessedNumber);
guessInput = "";
} else {
displayInvalidInput();
guessInput = "";
}
}
} else if (key == '*') {
startNewGame();
} else if (key == 'A') {
showHelp();
} else if (key == 'B') {
if (guessInput.length() > 0) {
guessInput.remove(guessInput.length() - 1); // Remove last character
updateDisplay();
}
} else if (key == 'C') {
toggleRange();
} else if (key == 'D') {
toggleBuzzer();
}
}
}

void startNewGame() {
targetNumber = random(0, isRange99 ? 100 : 10); // Generate random number between 0-9 or 0-99
guessCount = 0;
maxAttempts = isRange99 ? 7 : 3; // Set max attempts to 7 for 0-99 and 3 for 0-9
guessInput = "";

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Your Guess");
lcd.setCursor(0, 1);
lcd.print(isRange99 ? "(0-99)" : "(0-9)");
}

void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Your Guess: ");
lcd.print(guessInput);
lcd.setCursor(0, 1);
lcd.print(isRange99 ? "(0-99)" : "(0-9)");
}

void checkGuess(int guessedNumber) {
guessCount++;
lcd.clear();

if (guessedNumber == targetNumber) {
lcd.setCursor(0, 0);
lcd.print("Correct! The ");
lcd.setCursor(0, 1);
lcd.print("Number is ");
lcd.print(guessedNumber);
playTone(1000, 500); // Play success tone
delay(2000);
displayFunnyMessage(true);
startNewGame();
} else if (guessedNumber < targetNumber) {
displayTryAgain("Low", "more attempts");
} else {
displayTryAgain("High", "more attempts");
}

if (guessCount >= maxAttempts) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Out of attempts!");
delay(2000);

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("The number was");
lcd.setCursor(0, 1);
lcd.print(targetNumber);
delay(3000);

startNewGame();
}
}

void displayInvalidInput() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Invalid input!");
lcd.setCursor(0, 1);
lcd.print(isRange99 ? "Enter 0-99" : "Enter 0-9");
playTone(500, 200); // Play error tone
delay(2000);

updateDisplay();
}

void displayTryAgain(String line1, String line2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
int remainingAttempts = maxAttempts - guessCount;
if (remainingAttempts > 1) {
lcd.print(remainingAttempts);
lcd.print(" ");
lcd.print(line2);
} else if (remainingAttempts == 1) {
lcd.print("1 more attempt");
}
playTone(500, 200); // Play incorrect guess tone
delay(1500);

updateDisplay();
}

void displayFunnyMessage(bool success) {
lcd.clear();
if (success) {
switch (random(0, 3)) {
case 0:
lcd.setCursor(0, 0);
lcd.print("You're a");
lcd.setCursor(0, 1);
lcd.print("Mind Reader!");
break;
case 1:
lcd.setCursor(0, 0);
lcd.print("Are you");
lcd.setCursor(0, 1);
lcd.print("psychic?!");
break;
case 2:
lcd.setCursor(0, 0);
lcd.print("Congrats!");
lcd.setCursor(0, 1);
lcd.print("You nailed it!");
break;
}
}
delay(2000);
}

void showHelp() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("*: New Game");
lcd.setCursor(0, 1);
lcd.print("#: Confirm Guess");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("B: Backspace");
lcd.setCursor(0, 1);
lcd.print("C: Toggle Range");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("D: Buzzer On/Off");
lcd.setCursor(0, 1);
lcd.print(buzzerEnabled ? "Buzzer: ON" : "Buzzer: OFF");
delay(2000);

updateDisplay();
}

void displayLimitMessage() {
lcd.clear();
lcd.setCursor(0, 0);
if (isRange99) {
lcd.print("Limit: 2 Digits");
} else {
lcd.print("Limit: 1 Digit");
}
delay(2000);
updateDisplay(); // Return to guessing display
}

void toggleRange() {
isRange99 = !isRange99; // Toggle range
startNewGame(); // Restart game with new range
}

void toggleBuzzer() {
buzzerEnabled = !buzzerEnabled; // Toggle buzzer state
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(buzzerEnabled ? "Buzzer: ON" : "Buzzer: OFF");
delay(1000);
updateDisplay(); // Return to guessing display
}

void playTone(int frequency, int duration) {
if (buzzerEnabled) {
tone(buzzerPin, frequency, duration);
delay(duration);
noTone(buzzerPin);
}
}