Last Updated on 24th March 2023 by peppe8o
In a previous article we saw how to use a mini button switch with Raspberry PI.
In this tutorial we are going to apply what we have learned to create a small reaction game. It uses cheap circuit components (mini button switch, resistors, LEDs and wirings), Raspberry PI and a little of Python programming.
Differently from common Reaction games, it is a little more complete: it includes a terminal scoreboard. dedicated player leds and a referee.
I’ll use a Raspberry PI Zero W, but this guide works with all Raspberry PI models.
This game has very simple rules. It requires 2 players (named Player 1 and Player 2). A central LED (match LED) lights on at a random time. After match LED gets on, the first player that pushes its button gains 1 point. The player having more points at the end of game, wins.
This game hasn’t a limit of matches before ending, so you can stop whenever you want by interrupting python script (pressing CTRL+C).
A third person can act as referee to restart each match, but also one of players can be the referee as it is needed only to reset match LED and script waits at least 2 seconds after match reset.
Points progress is traced on terminal match by match, so you don’t need to remember them.
At game start, a small testing phase runs, asking the 2 players to test their buttons one at time. This way you can also identify who is player 1 and who is player 2.
After this test, match LED powers on and game starts pushing reset button which powers off match LED.
From here, match LED switches on at a random time (between 2 seconds and 7 seconds). The when one player pushes its button as first, its LED lights on and terminal scoreboard is updated. Pressing reset button starts a new match.
What We Need
As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if continue with the project or remove them from the shopping cart. So, hardware will be only:
- Raspberry PI Zero W (including proper power supply or using a smartphone micro usb charger with at least 3A) or newer Raspberry PI Board
- high speed micro SD card (at least 16 GB, at least class 10)
- Dupont Wiring
- Solderless breadboard
- Mini Switch Button
You can find many of this pieces (excluding Raspberry PI and micro SD card) in the good Elegoo kit, which also include other sensors tested in my blog.
Check hardware prices with following links:
Please find below wiring diagram for this project. Note that LED positive pins (longer) are connected to resistors, then to GPIO led controlling PINs:
Please find below some project detail pictures:
Prepare Operating system
Make your OS updated:
sudo apt update -y && sudo apt upgrade -y
RPI.GPIO should be already installed (otherwise, you can get it installed with the command “sudo apt install python3-rpi.gpio”).
Prepare Python Script for Reaction Game
In order to get python script avoiding copy-paste errors, you can get it from my download area directly in your Raspberry PI with wget terminal command:
Please find below script explaination.
Required packages are imported:
- RPi.GPIO is used to manage Raspberry PI PINS
- time is used to creae delays between matches
- random is used to generate a casual delay duration between matches
import RPi.GPIO as GPIO import time import random
PINs are then associated to variables for better code reading. This way you can also edit PINs according to your favourite cabling (if needed) without looking for numbers in all script as they are defined at beginning:
Player1But = 21 Player1Led = 20 refereeBut = 16 refereeLed = 12 Player2But = 7 Player2Led = 1
PINs are also set using RPi.GPIO package Broadcom (BCM) naming. LED PINs are defined as output. Button PINs are defined as input with a default value to high (please refer to Using mini Switch Button tutorial for more info about this setting):
GPIO.setmode(GPIO.BCM) GPIO.setup((Player1Led,refereeLed,Player2Led),GPIO.OUT) GPIO.setup((Player1But,refereeBut,Player2But),GPIO.IN, pull_up_down=GPIO.PUD_UP)
The try … except functions manage main Reaction Game program. Try statement includes main functions while except statement manage program interrupts (“KeyboardInterrupt” is triggered with CTRL+C) by printing winner and cleaning GPIO state before exiting.
LED PINs status are set to off, in order to avoid inconsistent states which may lead to incorrect LEDs powered on at game beginning:
Initialization phase starts, with program asking Player 1 (first) and Player 2 (after) to test their buttons and LEDs. Both tests are managed in same way:
- print function asks from terminal player to use its button
- a while loop waits for related button pushing (remember that button PINs are positive by default and goes to 0 when button is pushed). On button pushing, player led becomes on and while loop exits
- 1 second of delay is performed (with player LED on) to allow user be aware of its action correctly finished
- a greeting message is printed
- user LED is powered off
print('Player 1, please test your button') while GPIO.input(Player1But): GPIO.output(Player1Led,not(GPIO.input(Player1But))) GPIO.output(Player1Led,1) time.sleep(1) print('Thank you, Player 1') GPIO.output(Player1Led,0) print('Player 2, please test your button') while GPIO.input(Player2But): GPIO.output(Player2Led,not(GPIO.input(Player2But))) GPIO.output(Player2Led,1) time.sleep(1) print('Thank you, Player 2') GPIO.output(Player2Led,0)
After players test, game is initialized by lighting on referee LED and waiting for very first reset (which is the game start). Terminal messages are printed accordingly. Last while loop does … nothing (pass): it just waits for referee button pressing:
print('---------------------------------------------') print('Ready for the Game.') print('Referee LED is going to light on...') GPIO.output(refereeLed,1) time.sleep(1) print('Please push Referee button to start game.') print('---------------------------------------------') while GPIO.input(refereeBut): pass
p1Points and p2Points are used to store players points. Before first Reaction Game match they are reset to 0. Scoreboard heading is also printed:
p1Points = 0 p2Points = 0 print('-----------------------') print('| Player 1 | Player 2 |')
Matches run in next while loop, until “KeyboardInterrupt” trigger exits program. Each loop execution is a match.
Match LED (named “refereeLED”) is set to off. A random time (between 0 and 5 seconds) delay is performed. It is also increased of 2 seconds to give time after referee button pushing to prepare users (in case one of them is also the referee). Then referee LED is powered on:
GPIO.output(refereeLed,0) time.sleep(2+random.randint(0, 5)) GPIO.output(refereeLed,1)
inputP1 and inputP2 are variables set to 0 and used each match to store match winner.
Competition is managed in next while loop. Even if inputP1 is recorded as first, while loop is so fast in Raspberry PI that this little “benefit” is not usable by human speed. This while loop exits when one (the first) between players pushes its button. After this, winner LED is powered on:
inputP1=0 inputP2=0 while not(inputP1+inputP2): inputP1 = not(GPIO.input(Player1But)) inputP2 = not(GPIO.input(Player2But)) GPIO.output(Player1Led,inputP1) GPIO.output(Player2Led,inputP2)
Next part updates players scores and prints points progress. Python print() function can concatenate only strings. For this reason the str() python function converts points (which are collected as integers) to strings before printing them on scoreboard:
p1Points=p1Points+inputP1 p2Points=p2Points+inputP2 print('| ' +str(p1Points)+' | '+str(p2Points)+' |')
Before re-running loop, the referee button pression is waited to reset match by lighting off players led:
while GPIO.input(refereeBut): pass GPIO.output((Player1Led,Player2Led),0)
Final program part manages script interruption. When user interrupts execution, the winner is identified by comparing scores and printing who is the winner (or a draw if players have same points), ending the game and cleaning PINs:
except KeyboardInterrupt: if p1Points>p2Points: print('!! Player 1 won !!') elif p2Points>p1Points: print('!! Player 2 won !!') else: print('!!! Draw !!!') print('Game Over') GPIO.cleanup()
Running the game
To run Reaction Game, use following terminal command:
First player is asked to test its button:
pi@raspberrypi:~ $ python3 reactGame2_button.py Player 1, please test your button
Press player 1 button. Its LED powers on for 1 second. Back to terminal:
pi@raspberrypi:~ $ python3 reactGame2_button.py Player 1, please test your button Thank you, Player 1 Player 2, please test your button
Press player 2 button. Its LED lights on for 1 second. Then match LED is powered on and back to terminal:
pi@raspberrypi:~ $ python3 reactGame2_button.py Player 1, please test your button Thank you, Player 1 Player 2, please test your button Thank you, Player 2 --------------------------------------------- Ready for the Game. Referee LED is going to light on… Please push Referee button to start game. ---------------------------------------------
Push referee button. Scoreboard heading is printed and game starts by powering off matche LED. After a random time match LED powers on and the first player which pushes its button gets its LED on (together with match LED). Scoreboard is updated accordingly:
pi@raspberrypi:~ $ python3 reactGame2_button.py Player 1, please test your button Thank you, Player 1 Player 2, please test your button Thank you, Player 2 -------------------------------------------- Ready for the Game. Referee LED is going to light on… Please push Referee button to start game. -------------------------------------------- ----------------------- | Player 1 | Player 2 | | 0 | 1 |
Rerefee button will power off both LEDs (winner player LED and match LED) and start a new match untill game is finished with CTRL+C.
We are sorry that this post was not useful for you!
Let us improve this post!
Tell us how we can improve this post?