Maker.io main logo

Build a Simple Electronic Rock-Paper-Scissor Game

2021-11-11 | By Maker.io Staff

License: None Switches

This article explains how you can build a simple electronic rock-paper-scissors game using an Arduino. This project is perfect for beginners, as it only requires a handful of components. While both the wiring diagram and the associated software are easy to understand, the firmware portion has a few tricks up its sleeve to make the project work efficiently.

assemble_1

By following this article, you’ll be able to assemble this simple beginner-friendly project yourself!

BOM

To build this project, you’ll need the following components:

Part/Pcs./Where to buy

In addition to these components, you may also need a soldering iron and some solder. Further, I recommend you take a look at this introductory article if you’re new to soldering.

Assembling the Electronics

Assembling this project is easy to do, and you should be able to get the mini-game up and running in practically no time, regardless of your skill level. First, look at the device’s wiring diagram:

 

  

The wiring diagram of the electric rock-paper-scissors mini-game. Scheme-it link.

As you can see, the project comprises three LEDs, four push-buttons, and the resistor that goes along with each of the components. If you’re a complete beginner in electronics, I recommend reading this introductory guide to input and output devices on an Arduino.

In the wiring diagram above, the left LED is red, the next one is green, and the rightmost LED emits blue light. These three lamps represent the three choices in the game. The player presses the bottom button to start a new game. The player then inputs their choice using one of the three top buttons. It's possible to change the selected option during this process, and the Arduino displays the current selection using one of the three LEDs. By pressing the bottom button, the player finalizes the choice.

Before the player makes their selection, the machine also randomly thinks of what option to pick. The Arduino then determines the winner of the current round and displays the result using the serial console. In addition, the red LED lights up if the Arduino won, the green LED indicates the player won, and the blue LED signals both opponents picked the same option.

The microcontroller also keeps track of the scores and displays them using the serial console:

message_2

The Arduino displays various status messages during and after each game.

You can use a solderless breadboard to build this project. If you’re already more experienced, you can solder the components onto a prototyping perfboard to get a more refined end product:

project_3

The Software

As you just saw, the hardware portion of this project is rather simple, which is due to the software that does the heavy lifting. I’ll go over the most important parts of the firmware here, and you can download the full source code at the end of this article. First, the variables and setup()-function:

Copy Code
#define ACTION_BTN 8
/* Other button and LED I/O pins omitted */
#define SCISSORS_LED 4

#define BTN_DEBOUNCE_DELAY 250

unsigned long lastButtonDetection = 0UL;
unsigned int mode = 0;
unsigned int pick = 0;
unsigned int user_pick = 0;
unsigned int player_score = 0;
unsigned int arduino_score = 0;

// Lines = Arduino's choice
// Columns = Player's choice
const int win_matrix[3][3] = {
// Player chose rock, Player chose paper, Player chose scissors
{ 0, 1, -1 }, // Arduino chose rock
{ -1, 0, 1 }, // Arduino chose paper
{ 1, -1, 0 } // Arduino chose scissors
};

void setup()
{
Serial.begin(9600);

pinMode(ACTION_BTN, INPUT);
/* Other I/O initialization code omitted */
pinMode(SCISSORS_LED, OUTPUT);
}

The script starts with the definitions of the I/O pins used for connecting the LEDs and buttons. I also added several variables to keep track of the game state and the score of each player. Next, I want to draw your attention to the win_matrix two-dimensional array. While this method might look complicated at first, it’s an efficient solution for determining who wins a game after each player makes their choice. The lines represent the Arduino’s choice, and the columns correspond to the player’s pick. Line zero corresponds to the Arduino picking rock. Line one indicates the Arduino chose paper, and line two means that the Arduino chose scissors. A zero at a given array position means that no one wins the game (tie), a one means that the player wins, and a negative one indicates the Arduino wins.

After each opponent chooses an option, the Arduino only needs to select the value in the array that corresponds to each pick. As an example, suppose that the player picked paper, and the Arduino chose scissors. To determine the winner, the MCU scans the value in row two and column one in the win_matrix array. The value at that position is minus one. Therefore, we know that Arduino wins this round. Note that array indices start at zero in the C programming language.

Either way, the loop()-method contains the core game logic in the form of a few if-blocks:

Copy Code
void loop()
{
// Idle mode
if(mode == 0)
{
Serial.println("Press any button to begin!");
mode = 1;
}

// Waiting for the user to start a new game
// Once the user presses a button, the Arduino thinks of its game move
if(mode == 1)
{
if(readButtons() != -1)
{
mode = 2;
pick = random(0,3); // 0 = rock; 1 = paper; 2 = scissors
Serial.println("Choose either rock, paper, or scissors!");
}
}

// Waiting for the user to pick an option
if(mode == 2)
{
/* See below */
}

// Check who wins this round
if(mode == 3)
{
/* See below */
}
}

For now, let’s focus on the cases where the mode variable is either zero or one. In mode zero, the Arduino outputs a status message, and then it immediately switches over to mode one. In mode one, the Arduino waits for the user to push a button. Pressing any of the buttons starts a new game. The readButtons()-function is a short helper method that returns the pin-number of the button the user pressed or minus one if the Arduino didn’t detect any button presses. So, as soon as the player presses a button in mode one, the Arduino randomly picks either rock, paper, or scissors and then switches to mode two.

Copy Code
void loop()
{
// Idle mode
if(mode == 0)
{
/* See above */
}

// Waiting for the user to start a new game
// Once the user presses a button, the Arduino thinks of its game move
if(mode == 1)
{
/* See above */
}

// Waiting for the user to pick an option
if(mode == 2)
{
int pressedButton = readButtons();
selectLED(user_pick);

if(pressedButton == ACTION_BTN)
{
/* Serial output commands omitted */
turnOffLEDs();
mode = 3;
}
else if(pressedButton != -1)
{
user_pick = pressedButton - ACTION_BTN - 1;
}
}

// Check who wins this round
if(mode == 3)
{
/* Serial output commands omitted */
if(checkWinner() == -1)
arduinoWins();
else if(checkWinner() == 1)
playerWins();
else
tie();

/* Serial output commands omitted */

mode = 0;
}
}

In mode two, the Arduino reads the buttons another time. Here, the program checks whether the user pressed one of the selection buttons or the action button, which the player can use to lock in a previously selected option. If the user presses one of the selection buttons, for example, to choose the rock option, the program updates the user_pick variable and then lights up the rock-LED in the next iteration of the loop()-method.

If the user presses the action button, the program turns off all LEDs and switches to mode three. In mode three, the program uses the previously mentioned win_matrix to determine the winner of the current round. Depending on who won, the program then calls one of the following small helper functions before switching back to mode zero:

Copy Code
void tie(void)
{
Serial.println("Tie!");
selectLED(2);
}

void playerWins(void)
{
player_score += 1;
Serial.println("You win!");
selectLED(1);
}

void arduinoWins(void)
{
arduino_score += 1;
Serial.println("The Arduino wins!");
selectLED(0);
}

As you can see, each of the helper methods outputs a short status message and illuminates one of the three LEDs to indicate who won. Besides that, the arduinoWins() and playerWins() functions increase the Arduino’s or the player’s current score, respectively.

Download the Source Code

You can download the complete firmware source code for this project here.

Summary

This beginner-friendly Arduino project teaches you a few important things for working on a DIY project. First, you learn the basics of using physical input- and output options with your Arduino. This project utilizes three LEDs and four pushbuttons to allow users to interact with the finished device. The software of this project does most of the heavy lifting, thanks to which the hardware is very uncomplicated.

The firmware keeps an internal state and updates it according to the user input. The loop()-method acts according to the current internal mode. First, the program displays a short status message before waiting for the user to press any button to start a new game. Then, the software allows the player to pick an option while the Arduino randomly selects one. Lastly, the program uses a matrix to determine who wins the current round. You can try adding a character LCD to this project if you’d like to spice things up a bit. You can read this article to learn how to incorporate an LCD in your Arduino projects!

制造商零件编号 A000066
ARDUINO UNO R3 ATMEGA328P BOARD
Arduino
¥224.66
Details
制造商零件编号 EALP05RDHRA0
LED RED DIFFUSED 5MM T/H
Everlight Electronics Co Ltd
¥2.95
Details
制造商零件编号 151051VS04000
LED GREEN DIFFUSED 5MM ROUND T/H
Würth Elektronik
¥2.19
Details
制造商零件编号 151051BS04000
LED BLUE DIFFUSED 5MM ROUND T/H
Würth Elektronik
¥2.19
Details
制造商零件编号 CF14JT150R
RES 150 OHM 5% 1/4W AXIAL
Stackpole Electronics Inc
¥0.81
Details
制造商零件编号 CF14JT2K20
RES 2.2K OHM 5% 1/4W AXIAL
Stackpole Electronics Inc
¥0.81
Details
制造商零件编号 MJTP1230
SWITCH TACTILE SPST-NO 0.05A 12V
APEM Inc.
¥1.47
Details
制造商零件编号 1957
JUMPER WIRE M TO M 6" 28AWG
Adafruit Industries LLC
¥15.87
Details
制造商零件编号 MIKROE-1097
BREADBOARD TERMINAL STRIP
MikroElektronika
¥75.74
Details
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum