Automated Ultrasonic Whack-A-Mole Game

by Balpreet Singh in Circuits > Arduino

29 Views, 1 Favorites, 0 Comments

Automated Ultrasonic Whack-A-Mole Game

IMG_20260615_120819.jpg
engineering final project.png

This project is a homemade, arcade-style Whack-A-Mole game built using an Arduino Uno microcontroller. It is a fun, fast-paced electronic game designed to test your real-world reaction times using a combination of active sensors, physical buttons, target lights, sound effects, and a digital scoreboard. The system is programmed to act like a smart machine that automatically switches between two stages. It starts in an idle Standby Mode where a solid red light stays turned on to show the game is resting. In the background, an ultrasonic distance sensor acts like invisible radar, constantly casting sound waves into the room to see if a player is nearby. The exact moment you wave your hand close to the sensor, the red light shuts off, the buzzer plays a lively startup melody, and the Arduino instantly switches the system into active Gameplay Mode.

Once the game begins, the computer randomly chooses one of three target LEDs to light up. You have to quickly look at which light turned on and smash the matching tactile push button directly underneath it before a hidden background stopwatch timer runs out. To make the game exciting and competitive, it features a built-in speed booster mechanic. Every single time you hit the correct button, the code automatically slashes 300 milliseconds off your reaction window, causing the lights to flash faster and faster the higher your score climbs. Your live score is tracked in real-time from 0 up to 9 on a 7-segment digital display screen.

Because this specific scoreboard is a Common Anode hardware component, it operates using inverted logic, meaning it works completely backward from normal lights. Instead of sending positive power to turn the screen lines on, the code is programmed to pull the microcontroller pins down to Ground to light up each segment. If you press the wrong button, or if your hands are too slow and the background stopwatch timer expires, the game triggers an instant Game Over. It plays a low, sad buzzer tone, clears your score screen straight back to zero, and locks itself back into Standby Mode until the next player steps up. If you can survive the extreme speed increases and successfully press your way all the way to a maximum score of 9, a green victory light flashes rapidly to celebrate your win before the system safely resets back to the starting line.

Supplies

IMG_20260605_101041.jpg

To build this project, you will need the following electronic components:

  1. 1x Arduino Uno Microcontroller (and a USB cable to power it)
  2. 1x Large Breadboard
  3. 1x HC-SR04 Ultrasonic Distance Sensor (to detect your hand)
  4. 1x 7-Segment Display (Common Cathode) (to show the live score)
  5. 3x Push Buttons (your game controllers)
  6. 5x LEDs (3 for the game targets, 1 Green for winning a round, 1 Red for losing/standby)
  7. 1x Piezo Buzzer (for game sound effects)
  8. Resistors: 10k ohm resistors for the buttons and 330 ohm resistors to protect the LEDs and display segments.
  9. Many Jumper Wires (to connect everything)

Gather Your Pieces

IMG_20260605_101041.jpg

First, collect all the parts you need to build the game. You will need the Arduino computer board to act as the brain, a plastic breadboard to plug things into, and lots of colorful wires. For the game pieces, gather one ultrasonic sensor that works like eyes, three buttons to press, a sound buzzer, and five little LED light bulbs. Finally, grab one square number screen to show your score.

Give the Board Power

IMG_20260605_101124.jpg

To make everything work, you have to share electricity across the board. Run a wire from the Arduino's power pin to the long red line on the side of the breadboard, and another wire to the long blue line. Because the breadboard has two different sides, make sure to use two wires to jump across the middle gap to connect the left side lines straight to the right side lines so the whole board has power.

Plug in the Sensor

IMG_20260615_122944.jpg

Next, push the ultrasonic sensor down into the board. This part acts like radar to see your hand. Connect its power pin to the red line and its ground pin to the blue line. Then, use two jumper wires to link its middle data pins straight into pins 6 and 7 on the Arduino board so it can talk to the brain.

Add the Target Lights and Buttons

IMG_20260615_122914.jpg

Now, line up your three buttons on the board so you can press them. Connect one side of each button to the power rail, and wire the other side to pins 2, 3, and 4 on the Arduino. Right above each button, poke a colored target light bulb into the board. Wire the long leg of each light to pins 8, 9, and 10, and put the short leg into the blue ground line using a small resistor.

Connect the Scoreboard Screen

IMG_20260609_155356.jpg

Put your square scoreboard screen right in the middle of the board. Because this is a Common Anode screen, it shares one positive wire. Connect its middle pin with a resistor straight into the positive red power line. Then, run wires from its individual segment pins into pins A0, A1, A2, A3, A4, A5, and pin 5 on your Arduino so it can draw the numbers.

Complete Your Code and Upload the Code

The last step is to give the Arduino its code instructions. The code tells the computer to keep a red light on until the sensor sees your hand wave close by. Once your hand wakes up the game, the code plays a happy song and starts choosing target lights completely at random. It tells the scoreboard to count your points every time you hit the right button, and it shrinks the timer to make the game move faster and faster until you win!

Here is the link from where i get knowledge about some parts of my code:-

code

this is the tinkercad circuit link:

tinkercad Link

click this link to watch the video of testing:

Link to the video of game testing

int button1 = 2;
int button2 = 3;
int button3 = 4;

int ledTarget1 = 8;
int ledTarget2 = 9;
int ledTarget3 = 10;
int greenWinLED = 11;
int redLoseLED = 12;

int pinSegA = A0;
int pinSegB = A1;
int pinSegC = A2;
int pinSegD = A3;
int pinSegE = A4;
int pinSegF = A5;
int pinSegG = 5;

int gameStarted = 0;
int currentSpeed = 2000;
int scoreCount = 0;

void setup() {

pinMode(pinSegA, OUTPUT);
pinMode(pinSegB, OUTPUT);
pinMode(pinSegC, OUTPUT);
pinMode(pinSegD, OUTPUT);
pinMode(pinSegE, OUTPUT);
pinMode(pinSegF, OUTPUT);
pinMode(pinSegG, OUTPUT);

pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);

pinMode(ledTarget1, OUTPUT);
pinMode(ledTarget2, OUTPUT);
pinMode(ledTarget3, OUTPUT);
pinMode(greenWinLED, OUTPUT);
pinMode(redLoseLED, OUTPUT);
pinMode(gameBuzzer, OUTPUT);

randomSeed(analogRead(A0));
}

void loop() {

if (gameStarted == 0) {
digitalWrite(redLoseLED, HIGH);
displayNumber(0);

digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10);
digitalWrite(trigPin, LOW);

long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;

if (distance > 1 && distance < 10) {
digitalWrite(redLoseLED, LOW);

tone(gameBuzzer, 440, 100); delay(100);
tone(gameBuzzer, 554, 100); delay(100);
tone(gameBuzzer, 659, 100); delay(100);
tone(gameBuzzer, 880, 300); delay(400);

gameStarted = 1;
currentSpeed = 2000;
scoreCount = 0;
displayNumber(0);
delay(1000);
}
}

if (gameStarted == 1) {
int currentTarget = random(1, 4);

if (currentTarget == 1) { digitalWrite(ledTarget1, HIGH); }
if (currentTarget == 2) { digitalWrite(ledTarget2, HIGH); }
if (currentTarget == 3) { digitalWrite(ledTarget3, HIGH); }

int playerChoice = 0;
unsigned long timeLimitCheck = millis();

while ((millis() - timeLimitCheck < currentSpeed) && playerChoice == 0) {
if (digitalRead(button1) == HIGH) { playerChoice = 1; }
if (digitalRead(button2) == HIGH) { playerChoice = 2; }
if (digitalRead(button3) == HIGH) { playerChoice = 3; }
}

digitalWrite(ledTarget1, LOW);
digitalWrite(ledTarget2, LOW);
digitalWrite(ledTarget3, LOW);

if (playerChoice == currentTarget) {
digitalWrite(greenWinLED, HIGH);
delay(200);
digitalWrite(greenWinLED, LOW);

scoreCount++;
displayNumber(scoreCount);

if (currentSpeed > 600) {
currentSpeed = currentSpeed - 300;
}

if (scoreCount >= 9) {
digitalWrite(greenWinLED, HIGH);
tone(gameBuzzer, 523, 150);
delay(150);
digitalWrite(greenWinLED, LOW);
delay(150);

digitalWrite(greenWinLED, HIGH);
tone(gameBuzzer, 659, 150);
delay(150);
digitalWrite(greenWinLED, LOW);
delay(150);

digitalWrite(greenWinLED, HIGH);
tone(gameBuzzer, 784, 150);
delay(150);
digitalWrite(greenWinLED, LOW);
delay(150);

digitalWrite(greenWinLED, HIGH);
tone(gameBuzzer, 1047, 400);
delay(400);
digitalWrite(greenWinLED, LOW);

gameStarted = 0;
scoreCount = 0;
displayNumber(0);
delay(1000);
} else {
delay(400);
}
}
else {
digitalWrite(redLoseLED, HIGH);
tone(gameBuzzer, 180, 800);
delay(1000);
digitalWrite(redLoseLED, LOW);

gameStarted = 0;
scoreCount = 0;
displayNumber(0);
delay(1000);
}
}
}


void displayNumber(int num) {
digitalWrite(pinSegA, HIGH);
digitalWrite(pinSegB, HIGH);
digitalWrite(pinSegC, HIGH);
digitalWrite(pinSegD, HIGH);
digitalWrite(pinSegE, HIGH);
digitalWrite(pinSegF, HIGH);
digitalWrite(pinSegG, HIGH);

if (num == 0) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
digitalWrite(pinSegE, LOW);
digitalWrite(pinSegF, LOW);
}
else if (num == 1) {
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
}
else if (num == 2) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegG, LOW);
digitalWrite(pinSegE, LOW);
digitalWrite(pinSegD, LOW);
}
else if (num == 3) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegG, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
}
else if (num == 4) {
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegG, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
}
else if (num == 5) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegG, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
}
else if (num == 6) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegE, LOW);
digitalWrite(pinSegD, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegG, LOW);
}
else if (num == 7) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
}
else if (num == 8) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
digitalWrite(pinSegE, LOW);
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegG, LOW);
}
else if (num == 9) {
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegG, LOW);
}
}