|
|
Arduino Nano R3 |
x 1 | |
|
|
I2C 16x2 Arduino LCD Display Module |
x 1 | |
|
PKB24SPCH3601-B0Murata Electronics
|
x 1 | |
|
|
Illuminated Pushbutton Switch |
x 5 | |
|
|
Resistor, 470 ohm |
x 5 |
|
Soldering Iron Kit |
|
|
arduino IDEArduino
|
DIY Simple Arduino Whack-a-Mole Game
A "Whack-a-Mole" game is a classic arcade-style game where moles pop up randomly from holes, and the player uses a mallet or similar tool to "whack" the moles before they disappear.

The goal is to hit the moles as they appear, to score points while avoiding hitting any other targets. It’s typically timed and the game ends after a certain period, with the player's score displayed. This time I will present you a simple way to make a Whack a mole portable game using an Arduino microcontroller
In this case, the "moles" will be small buttons with built-in LEDs in different colors. A randomly selected button lights up for a certain time when we have to press it to get a point.
This project is sponsored by PCBWay. They has all the services you need to create your project at the best price, whether is a scool project, or complex professional project. On PCBWay you can share your experiences, or get inspiration for your next project. They also provide completed Surface mount SMT PCB assemblY service at a best price, and ISO9001 quality control. Visit pcbway.com for more services.

The device is very simple to make and consists of a few components:

- Arduino Nano microcontroller module
- 5 Buttons with built-in Leds with different colours
- LCD display with 16x2 characters and I2C communication protocol
- 5 resistors 470 Ohms
- and Buzzer

The start of the game is indicated on the LCD display and then the buttons start to light up in random order. With each successful press of a button while it is lit, we get a point. If we press the wrong button, we get a negative point and the score is reduced by 1.

Successful or unsuccessful activation of the button (actually catching the mole), as well as other states of the game are signaled by an appropriate sound generated by the buzzer. When the game starts, the first line shows the current score, while the second line shows a bar graph that gradually decreases over time and disappears after exactly thirty seconds, the same time the game lasts. This way we have a visual representation of the remaining time in the game.

To make the game more fun and addictive, over time the duration of the lighting of the corresponding button is reduced, in fact the game is accelerated. At the end of the game, all the buttons flash several times and this is accompanied by appropriate sounds. Then the final score appears on the screen.

After a 5-second break, a new game starts.

I updated the code so that the player has a better overview of the game duration and now the bar instead of 16 horizontal, consists of 80 vertical bars.

And finally, a quick conclusion. This is a really simple Arduino version of the Whack-a-Mole arcade game made with just a few components, but endlessly fun and addictive, great for testing and practicing reflexes. I installed the device in a suitable box made of PVC board with a thickness of 3 and 5mm and covered with self-adhesive colored wallpaper. Also, for compactness and mobility, the game is powered by 2 lithium batteries (7.4V).
/*Arduino Whack-A-Mole Game
by mircemk, June 2025
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin Definitions
const int buttonPins[] = {8, 9, 10, 11, 12}; // Button pins
const int ledPins[] = {2, 3, 4, 5, 6}; // LED pins
const int buzzerPin = 13; // Buzzer pin (digital 13)
const int numMoles = 5; // Number of moles/buttons/LEDs
// Game variables
int currentMole = -1; // Current mole (LED) to be lit
int score = 0; // Player's score
unsigned long reactionTime = 1000; // Initial reaction time (milliseconds)
unsigned long lastMoleTime = 0; // Time when the last mole was lit
unsigned long gameStartTime = 0; // Start time of the game
unsigned long gameDuration = 30000; // Total game duration (30 seconds)
// Reaction time adjustment
const unsigned long reactionTimeDecrement = 100; // Time to reduce reaction by (milliseconds)
const unsigned long minReactionTime = 300; // Minimum reaction time (milliseconds)
void setup() {
lcd.backlight();
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Whack-a-Mole");
lcd.setCursor(3, 1);
lcd.print("by mircemk");
delay(2000);
lcd.clear();
// Initialize button pins and LED pins
for (int i = 0; i < numMoles; i++) {
pinMode(buttonPins[i], INPUT_PULLUP); // Set button pins as input with pull-up resistors
pinMode(ledPins[i], OUTPUT); // Set LED pins as output
digitalWrite(ledPins[i], LOW); // Turn off all LEDs initially
}
pinMode(buzzerPin, OUTPUT); // Set buzzer pin as output
Serial.begin(9600); // For debugging and displaying the score
randomSeed(analogRead(0)); // Initialize random seed from an unused analog pin
Serial.println("Whack-a-Mole Game Started!");
lcd.setCursor(2, 0);
lcd.print("GAME STARTED!");
delay(500);
lcd.clear();
gameStartTime = millis(); // Record game start time
}
void loop() {
unsigned long currentMillis = millis(); // Get the current time
// Update the progress bar
unsigned long elapsedTime = currentMillis - gameStartTime;
if (elapsedTime <= gameDuration) {
int barLength = map(gameDuration - elapsedTime, 0, gameDuration, 0, 16);
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
lcd.print(i < barLength ? '-' : ' '); // Print '-' for remaining time, ' ' for elapsed
}
}
// Light up a mole after a certain amount of time (based on reactionTime)
if (currentMillis - lastMoleTime >= reactionTime) {
if (currentMole != -1) {
digitalWrite(ledPins[currentMole], LOW); // Turn off the previous mole
}
currentMole = random(0, numMoles); // Randomly pick a mole (LED)
digitalWrite(ledPins[currentMole], HIGH); // Light up the chosen LED
lastMoleTime = currentMillis; // Update the time when the mole was lit
}
// Check if the player pressed the correct button for the lit mole
for (int i = 0; i < numMoles; i++) {
if (digitalRead(buttonPins[i]) == LOW) { // Button pressed (LOW due to INPUT_PULLUP)
if (i == currentMole) {
score++; // Correct mole hit
lcd.setCursor(2, 0);
lcd.print(" Score: "); // Clear the score field with extra spaces
lcd.setCursor(12, 0);
lcd.print(score); // Update the score
tone(buzzerPin, 1000, 200); // High-pitched sound (1000Hz) for 200ms
if (reactionTime > minReactionTime) {
reactionTime -= reactionTimeDecrement;
}
} else {
score--; // Wrong mole hit
lcd.setCursor(2, 0);
lcd.print(" Score: "); // Clear the score field with extra spaces
lcd.setCursor(12, 0);
lcd.print(score); // Update the score
tone(buzzerPin, 400, 200); // Low-pitched sound (400Hz) for 200ms
}
digitalWrite(ledPins[currentMole], LOW); // Turn off the current mole
currentMole = -1; // Reset the mole to indicate no active mole
delay(500); // Short delay to debounce button press
}
}
// End the game after the set duration
if (elapsedTime >= gameDuration) {
lcd.setCursor(3, 0);
lcd.print("Game Over! ");
lcd.setCursor(0, 1);
lcd.print("Final Score: ");
lcd.setCursor(13, 1);
lcd.print(" "); // Clear any leftover characters
lcd.setCursor(13, 1);
lcd.print(score); // Print the final score
// Flash all LEDs and play a sound three times
for (int i = 0; i < 3; i++) {
for (int j = 0; j < numMoles; j++) {
digitalWrite(ledPins[j], HIGH);
}
tone(buzzerPin, 1000, 300); // Play sound
delay(300); // Keep LEDs on
for (int j = 0; j < numMoles; j++) {
digitalWrite(ledPins[j], LOW);
}
delay(300); // Keep LEDs off
}
delay(2000); // Pause before resetting the game
lcd.clear();
score = 0;
currentMole = -1;
for (int i = 0; i < numMoles; i++) {
digitalWrite(ledPins[i], LOW);
}
lcd.setCursor(0, 0);
lcd.print(" Start New Game");
delay(5000);
lcd.clear();
gameStartTime = millis();
reactionTime = 1000;
}
}
DIY Simple Arduino Whack-a-Mole Game
- Comments(0)
- Likes(0)
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Mirko Pavleski
-
Arduino 3D Printed self Balancing Cube
Self-balancing devices are electronic devices that use sensors and motors to keep themselves balanc...
-
Build simple Retro Style VFO (Variable frequency oscillator) with Crowoanel 1.28 inch Round Display
Today I received a shipment with a Small round LCD display from Elecrow. The device is packed in tw...
-
Human vs Robot – Rock Paper Scissors with MyCobot 280 M5Stack
Today I received a package containing the few Elephant Robotics products. The shipment is well pack...
-
How to Build a Simple Audio Spectrum Analyzer with Adjustable Settings
An audio spectrum analyzer is an electronic device or software tool that measures and visually disp...
-
How to Make a Digital Clock on a Vintage B&W TV using Arduino
These days I accidentally came across this small retro Black and White TV with a built-in Radio, so ...
-
Build a $10 Function Generator with Frequency Meter for Your Lab
A function generator is a piece of electronic test equipment used to generate various types of elec...
-
From Unboxing to Coding - Radar Clock on Elecrow’s 2.1 HMI Display
Today I received a shipment with a large round LCD display from Elecrow. The device is packed in two...
-
Making a Retro Analog NTP Clock with Unihiker K10 - Arduino IDE Tutorial
Some time ago I presented you a way to use standard Arduino libraries on the Unihiker k10 developme...
-
Build a Cheap & Easy HF Preselector - Antenna Tuner
HF antenna preselector is an electronic device connected between an HF radio antenna, and a radio r...
-
DIY Static Charge Monitor - Electrostatic Field Detector (Arduino & TL071)
A Static Charge Monitor also known as a Static Field Meter or Electrostatic Voltmeter is a device u...
-
XHDATA D-219 Radio Short Review with complete disassembly
Some time ago I received an offer from XHDATA to be one of the first test users of their new radio m...
-
How to make Simplest ever Oscilloscope Clock
An oscilloscope clock is a unique and creative way to display the time using an oscilloscope, which...
-
DIY Digital Barograph with BME280 and ESP32 - 24 Hour Pressure Trends
A barograph is a self-recording barometer that continuously measures and records atmospheric pressu...
-
Build a Raspberry Pi Pico SDR Radio with Waterfall Display
Software-defined radio (SDR) is a radio communication system where components that have traditional...
-
DIY Magnet Polarity Detector - How to Identify Poles with a Hall Sensor from a PC Fan
Recently, while working on a project, I needed to determine the polarity of several permanent magne...
-
Light Meter Project - Making Dfrobot Unihiker K10 Work with Standard Arduino Libraries
The other day I received a shipment with a UNIHIKER K10 development board from DFRobot, which I rec...
-
DIY Simple Arduino Whack-a-Mole Game
A "Whack-a-Mole" game is a classic arcade-style game where moles pop up randomly from holes, and th...
-
Wireless Power Transmission, Long-Distance and High-Efficiency with Class-E Tesla Coil
Wireless energy transfer also known as wireless power transmission is a method of getting useful el...
-
-
AEL-2011 Power Supply Module
322 0 1 -
AEL-2011 50W Power Amplifier
296 0 1 -
-
-
Custom Mechanical Keyboard
565 0 0 -
Tester for Touch Screen Digitizer without using microcontroller
230 2 2 -
Audio reactive glow LED wristband/bracelet with NFC / RFID-Tags
236 0 1 -
-
-







