Estimated Time:
150 min
Level of Difficulty:
programming
hardware
assembly

Whack-a-Mole

In the ‘80s, when programming became more and more common, people started to do all sorts of crazy stuff. This, of course, included designing arcade games. In this game, the goal is to react as fast as possible to the LEDs that light up by pressing the button corresponding to the LED. But don't cheat or press the wrong button, otherwise the game is over. This game is based on the most popular arcade game, 'Whack-A-Mole'. We will learn how to build this game, how to program it, and how to make changes to improve it. Ready for the challenge?

You will learn about:

  • Skills
  • Knowledge

We will be focusing on

  • assembling mechanical structures (that will be the base of the project),
  • combining the electronic circuits with the mechanics of the project, and
  • programming new applications with the concepts we learned in the lessons.

We are going to assemble the project by following a sequence of stages. These stages include instructions about how to assemble the mechanical and electronic parts. Then, after we’ve assembled them, we will build a program to test if the project is working as intended. This will help us to identify if there is anything wrong after each stage.

Let’s start building!

Let’s start with the LEDs

In this stage, we are going to assemble the base of the project. This part will hold the Arduino board and the breadboard. Then, we will create the circuit for the LEDs. Finally, we will program a test code to check that all of the LEDs are well connected and working.

Materials needed

We are going to need to have these components close by:

  • 1Arduino Uno WiFi
  • 1EDU Shield
  • 1Breadboard
  • 1USB Cable
  • 110mm Red LED
  • 110mm Green LED
  • 310mm Yellow LED
  • 4Male-Male jumper wire
  • 10Male-Female Jumper Wire
  • 5220Ω Resistor
  • 41x7 Bar
  • 22x13 Bar
  • 5LED Plate
  • 10Mushroom Connector
  • 1Board Bar
  • 1Board Plate

Assembling the structure

The following 3D assembly video will show us how to assemble the mechanical part of the base of the project.

Building the circuit

Now we are ready to start building the circuit with the help of the steps below. These steps will help us control the wiring by using the following instructions:

step 1

Let's add an LED connected to pin 13.

Programming the board

The program of Whack-A-Mole has two different game modes, the "waiting" mode and the "arcade" mode. We are going to program the behavior of the “waiting” mode now.

In this stage, the LEDs will blink all together - one second turned ON and one second turned OFF. While we are programming the "waiting" mode, we will check that all the connections in the circuit we have built are correct.

The code we need to build follows the information in the flowchart below.

Completing the code

We are going to follow a plan for our entire project. The way we are going to program it is by typing some parts of the corresponding stage programs. These programs are available in Arduino IDE, but they are not fully functional programs - they are incomplete.

In these programs, we will find some parts marked as "____" which we will need to complete in order to have a code without errors that we can upload to the board.

To get an idea about what each part of the code should do, and to be able to complete them, in each stage we will find the same code that is in the IDE with some explanations about its behavior.

Tip: Now it’s time to get hands-on with the code! To program the project, we will need to complete the codes. Let’s open the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage1. Then, let’s follow the code below with its descriptions. This will allow us to understand how to complete the selected parts.

Naming the LED variables and matching them with their pin connections.

Setting up the LED pin connections as outputs.

Blinking all the LEDs at the same time to program the behavior for the "waiting" game mode.

Expected behavior

Once we have completed the code, let’s check to make sure that it does not have any errors by clicking the verify button, and then let’s upload it to the board. The LEDs should blink all together - one second ON and one second OFF.

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That the wiring is right and that there are no disconnected wires.
  • That we have configured the pinMode as INPUT properly.
  • That we connected the LEDs with the right polarity and to the right pins.
  • That there are no short circuits (this can happen if the terminals of the LEDs are touching each other).

Let’s connect the buttons

The buttons are an important part of this game. In this stage, we are going to fit the buttons within the structure and build a circuit for each of them. Then, we will continue programming the game modes and testing that all the components work as they should.

Materials needed

We are going to need to have these components close by:

  • 3Arcade Button
  • 310kΩ Resistor
  • 3Male-Male jumper wire
  • 41x5 Bar
  • 21x7 Bar
  • 2Angle Bar
  • 3Button Plate
  • 8Parallel Connector
  • 10Mushroom Connector

Assembling the structure

The following 3D assembly video will show us how to assemble the structure we need for this stage.

Building the circuit

Now we are going to finish building the circuit with the help of the steps below. These steps will help us control the wiring by using the following instructions. We won’t be adding any more components after this stage, so make sure the components are connected the right way before moving on.

step 1

Let's add a button connected to pin 7 to the circuit.

Programming the board

This time, we will control the buttons. To do this, we will program different behaviors for the LEDs based on the state of the buttons (if they are pressed or released).

To code our program, we will follow the flowchart below.

Differentiating old and new code

We are going to differentiate the code of the previous and current stages by color coding. The code we are going to add or modify will be highlighted in yellow. We will do this for every stage in order to focus and provide explanations for the code that will be built on top of the previous stage codes.

Tip: As in the previous stage, we are going to complete the code created in the last stage. Let’s do this by typing the code or modifying the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage2.

Naming the button variables and matching them with its pin connections.

Setting up the button pins as inputs.

In the loop, we don’t need the LEDs blinking now, so let’s comment this part to avoid its execution until we need it later. To do this, let’s type /* before the first digitalWrite and */ after the last delay.

Then, we are going to turn on an LED when its corresponding button is pressed. To do this, we are going to read the state of each button inside of an if() statement. In case the button is pressed, we will turn ON the corresponding LED. Otherwise, we will check the next button. Then, after checking all the buttons, we need to turn OFF all the LEDs.

Expected behavior

When a button is pressed, the corresponding LED should light up.

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That the wiring is correct.
  • That the button wiring is connected exactly the same way as depicted in the circuit diagram.
  • That the programmed behavior for the buttons and the LEDs is the desired behavior.
  • That we have properly configured pinMode as INPUT and OUTPUT.
  • That we used the double equal (==) operator when comparing two values in an if() statement.

Introducing the game states

In this stage, we will continue programming the game. Now we will define game states for the code lines that we programmed in the previous stages.

Programming the board

This time, we will program the states of the game. To do this, we will introduce a variable called gameStarted to check and control if the game has started or is still in the "waiting" mode.

To code our program, we will follow the flowchart below.

Tip: As in the previous stage, we are going to complete the code created in the last stage. Let’s do this by typing the code or modifying the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage3.

Initializing the game variables: startLevel is to set the starting difficulty level, and gameStarted is to select when the game starts.

Now we need to blink the LEDs when the gameStarted is 0 ("waiting state"). To do this, we will include the if() statement that checks the value of it and uncomment the part of the code that blinks the LEDs. To do this, we have to delete the /* and */ symbols.

At the same time, the speed the LEDs will blink will depend on the game level. To do this, we will program the delay in function of the game level. To do this, we need to change the 1000 that we programmed in stage 1 for startLevel.

Then, to start playing, the user has to press button_1. Once it is pressed, gameStarted changes from 0 to 1.

In the "arcade" mode when gameStarted = 1. We are going to check if each button is pressed. If the button is pressed, we are going to turn ON its corresponding LED. We do the same with button_2 & button_3. Then, if all of the buttons are released, we are going to turn OFF all the LEDs.

Expected behavior

All LEDs will be blinking at the same time until we press button_1, then each yellow LED should turn on when its corresponding button is pressed.

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That the values for gameStarted are correct according to the desired behavior.
  • That we have configured the delays with the correct variable/number.
  • That we are programing the right logic for the button presses.
  • That the LEDs’ program behaves according to the expected result.
  • That we are using the double equal (==) operator when we are comparing two values in an if() statement.

Filling the "arcade" mode

In this stage, we are going to complete the "arcade" mode of the project. To do this, we will need to program the condition that will move the game from the waiting mode.

Programming the board

We will use the logical OR operator to check if button_1 or button_2 or button_3 is pressed. We will also add some blinking before we go to the game mode.

To code our program, we will follow the flowchart below.

Tip: As in the previous stage, we are going to complete the code created in the last stage. Let’s do this by typing the code or modifying the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage4.

The new condition to start the game is pressing any button. To do this, we need to check in the same if() statement if any of the buttons are pressed. We are going to use the OR (||) condition to check this.

When the player presses any of the buttons, the game will turn ON the loseLED and winLED. They will be ON for two seconds, then turn OFF. Then, the game starts.

Expected behavior

At this point, all of the LEDs should stop blinking when we press any button, then each yellow LED should turn on when its corresponding button is pressed.

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That when we checked more than one button in an if() statement, we used the OR (||) condition.
  • That we have programmed the LEDs’ behavior according to the expected result.
  • That if there are compiling errors, we check the brackets. There are so many of them, and it is likely that we are missing some. To make this easier, click on one and IDE will show its pair.

Blinking the LEDs randomly

We are more than halfway to finishing our project. Now it is time to make the LEDs blink in a random order. This should happen in the "arcade" state when the gameStarted is 1. We will also program a way to know when each LED is ON and what should happen in these cases.

Programming the board

In this stage, we are going to blink the LEDs randomly; we will be programming the way the LEDs are going to behave in the arcade mode.

To code our program, we will follow the flowchart below.

Tip: As in the previous stage, we are going to complete the code created in the last stage. Let’s do this by typing the code or modifying the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage5.

Here we define the blinkLED as the variable that defines which random LED is blinking.

The blinkLED is being used to make one LED light up. We are going to save a random number from 1 to 3 on blinkLED. Then, in function of the value stored on blinkLED, we will blink the corresponding yellow LED during a certain time depending on the game level. In the beginning, it will blink slower, then it will gradually become faster each time the player presses the right button.

To finish this stage, we will need to introduce a delay of 300 milliseconds after turning OFF all the LEDs.

Expected behavior

The goal of this stage is to have a random blinking LED after pressing any button while the game is in waiting mode (all the LEDs should blink together).

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That we have selected the correct numbers to introduce in the random function.
  • That in each case, the blinkLED values correspond with the LED we want to blink.
  • That we have configured the delays with the correct variable/number.

Let’s Play!

This is the last stage to program the Whack-A-Mole game. We have done a great job so far.

Programing the board

The only things we are missing are introducing the win and lose situations and increasing the level with each right button selection.

To code our program, we will follow the flowchart below.

Tip: As in the previous stage, we are going to complete the code created in the last stage. Let’s do this by typing the code or modifying the File > Examples > CTC GO CORE > Projects > WhackAMole > WhackAMole_Stage6.

We will need to add a variable called level that will control the game difficulty.

Let’s add the level of difficulty to the blinking speed by subtracting level from startLevel inside the delay(). If yellowLED_1 is turned ON when button_2 or button_3 is pressed, turn ON loseLED for 2 seconds and set gameStarted to 0. This means that the game is over. If the button pressed matches with the blinking LED, turn ON the winLED for 300 milliseconds and increase level by 5 units.

Let’s include the level difficulty in yellowLED_2 by modifying the delay as we did with yellowLED_1. If yellowLED_2 is turned ON when button_1 or button_3 is pressed, turn ON loseLED for 2 seconds and set gameStarted to 0. This means that the game is over. If the button pressed matches with the blinking LED, turn ON the winLED for 300 milliseconds and increase level by 5 units.

Let’s include the level difficulty in yellowLED_3 by modifying the delay(). If yellowLED_3 is turned ON when button_1 or button_2 is pressed, turn ON loseLED for 2 seconds and set gameStarted to 0. This means that the game is over. If the button pressed matches with the blinking LED, turn ON the winLED for 300 milliseconds and increase level by 5 units.

If level turns bigger than startLevel, it will generate a negative number when subtracting that will break the program. To avoid this, we need to program a condition that makes the biggest value of level to be startLevel value. To finish, we need to include the level difficulty in the delay() after turning OFF the LEDs.

Expected behavior

The game starts in the waiting mode until we press any of the buttons, then the game changes to the arcade mode. It’s time to play. The goal is to react as fast as possible to the LEDs that light up by pressing the button corresponding to the LED. With each right press, the LEDs will blink faster. If we fail, the game is over and goes back to the waiting mode.

Not working?

The program isn’t working the way it’s supposed to? Let’s make sure:

  • That we subtracted the level value in the delay() correctly.
  • That in each case, the blinkLED values correspond with the LED we want to blink.
  • That we are programing the right logic for the button presses.
  • That when we changed the state of a variable, we used "=" once.
  • That we are using the OR (||) operator when we are checking more than one button in an if() statement.
  • That we haven’t forgotten to change some LED and button numbers when we copy-pasted code. Check to make sure they are working correctly. If not, we can always upload the previous code to see if everything is working as intended with that one.

Project Demonstration

Good job! We’re done with our project and we have just enough time to play around and explore it. Now it’s time to share our experience with our classmates. Let’s show the projects by playing the game together with our groupmates and our classmates. Let’s also present the projects, explaining the building and programming process to each other.

Here’s a list of things to talk about:

  • How does the project work?
  • How does the sketch logic work?
  • What new functions/terms have we learned/used?
  • Was there a frustrating part? Why was it frustrating?
  • If something went wrong, how could we fix it next time?
  • Is there anything we could add to the project to make it more fun?

Wrapping up

At the end of class, all the materials should be organized in their respective boxes to make sure that they are ready to use in the next lesson. Before leaving, make sure that:

  • The battery is disconnected from the battery holder.
  • There are no components on the floor.
  • Broken components (if any) are reported to the teacher.

Challenge

How was the experience of building this project? Was it challenging? In case it was not challenging enough, we have some suggestions that will make the project more advanced.

  • Instead of having all of the LEDs blinking together while the game is in the "waiting" mode, we suggest changing them to blink in a row continuously until we change to the "arcade" mode.
  • Instead of turning on the loseLED for two seconds when a wrong button is pressed, we suggest blinking it 3 times before it changes to the "waiting" mode.

Tip: Before you start experimenting with this challenge, make sure the complete program we just worked on is saved, then let’s modify a separate sketch. Let’s name it as WhackAMole_Challenge. We’re going to do it this way so if something goes wrong, or if we want to start over, we can always go back to the previous code.