Search

Lights Out!

About the project

In this resource, you will find out how to make a fun and fast-paced reaction game using the Explorer HAT.

Project info

Items used in this project

Hardware components

Pimoroni Explorer HAT Pro Pimoroni Explorer HAT Pro x 1
Raspberry Pi 3 - Model B+ Raspberry Pi 3 - Model B+ x 1

Software apps and online services

Software Installation Software Installation curl -sS get.pimoroni.com/explorerhat | bash

Story

What you will need

Hardware

  • Explorer HAT

Software

Software Installation

To install the software you need, open a terminal window and run the following command:

  1. curl -sS get.pimoroni.com/explorerhat | bash

You can find further instructions here

Lights Out!

In this resource you will find out how to make a fun and fast-paced reaction game using the Explorer HAT.

The Explorer HAT has touch buttons labelled from 1 to 4, and four LED lights in different colours. The aim of the game is to program the Explorer HAT to turn a light on at random, at which point the player must press the corresponding button to turn the light off. If the player is too slow, or if they press the wrong button, the game is over.

Setting up

Before you start, make sure your Raspberry Pi is powered down and switched off.

  • Carefully mount the Explorer HAT onto the GPIO pins on your Raspberry Pi, then boot the Pi.

  • Open Python 3 from the Programming menu:

  • Create a new file by clicking File > New File and type the code import explorerhat before pressing F5 to run your program.

If everything is working you should see a message saying “Explorer HAT Pro detected…”. If not, check that you have installed the softwareand that you have connected your Explorer HAT correctly to the GPIO pins.

Turning lights on

  • You can use Python to tell the Explorer HAT which lights to turn on and off. Add the following new lines of code into your Python file, then run the program to see what it does:
  1. import explorerhat
  2. from time import sleep
  3.  
  4. explorerhat.light.red.on()
  5. sleep(2)
  6. explorerhat.light.red.off()
  7. sleep(1)
  8. explorerhat.light.on()
  9. sleep(5)

Can you work out how to do make your program do these things?

  • Turn the other coloured lights on individually (blue, yellow, green)
  • Turn all of the lights off at once
  • Change the length of time for which the lights are turned on and off

Using the random library

This would be a pretty easy game if the lights always came on in the same order, for the same length of time! To make it as tricky as possible for the player, you need to add some randomness. You will randomize which light is turned on, and how long the program will wait before turning the next light on.

  • To generate random numbers, you need to use Python’s random library. Find the line in your program that says from time import sleep, and underneath it type in import random. Delete all of the code beneath this (where you experimented with turning the lights on and off).

  • First, you will ask Python to choose a random light to turn on. Add this code to your program:
  1. light = random.randint(1,4)

This code chooses a random integer (whole number) between 1 and 4 and assigns it to the variable light.

  • Now add some code to turn one light on depending on the number which was randomly chosen. Can you finish off the rest of the code? Note that 3 is the red light and 4 is the green light:
  1. if light == 1:
  2. explorerhat.light.blue.on()
  3. elif light == 2:
  4. explorerhat.light.yellow.on()

Run your program several times. Check that, each time the program runs, a different light is randomly chosen. The light should turn on immediately.

  • To make the game more fun, there needs to be an unpredictable gap between the lights turning on, so let’s add some code to make the program wait a random length of time before turning on the next light:

Underneath the code where you chose which light to turn on, add two new lines of code:

  1. light = random.randint(1,4)
  2.  
  3. wait_for_next = random.uniform(0.5, 3.5)
  4. sleep(wait_for_next)

This time you are using the random.uniform function which allows you to choose numbers with fractional parts (decimals). In the code above, Python chooses a number which could be anything between half (0.5) and three and a half (3.5) and then waits for that number of seconds. You can change these values if you want to be more (or less) mean to your player!

Pressing the button

  • You need to know when the player presses a button on the Explorer HAT, and which button it was that they pressed. At the bottom of your code, add this line:
  1. explorerhat.touch.pressed(button_pressed)
  • When a button is pressed, the button_pressed function will be called, so you need to write this function. Put the following code at the start of your file, just after the import statements:
  1. def button_pressed(channel, event):
  2. print("You pressed button " + str(channel) )
  3. explorerhat.light.off()

The variable channel contains the number of the button that was pressed (1-4). Test your program and you should see that when you press a button, the number of the button you pressed will be displayed in the Python shell and all lights will be switched off.

Lots of lights!    

  • Your program can choose and switch on a random light, and then switch it off when a button is pressed. Add a game_in_progress variable and a loop to your game so that lights keep being randomly chosen.

Your code so far should look like this:

  1. import explorerhat
  2. from time import sleep
  3. import random
  4.  
  5. # The button_pressed function
  6. def button_pressed(channel, event):
  7. print("You pressed " + str(channel) )
  8. explorerhat.light.off()
  9.  
  10. # Keep playing the game until game_in_progress becomes False
  11. game_in_progress = True
  12.  
  13. while game_in_progress:
  14.  
  15. # Randomly choose the number of a light (1-4)
  16. light = random.randint(1, 4)
  17.  
  18. # Choose how long to wait before turning on the light
  19. wait_for_next = random.uniform(0.5, 3.5)
  20. sleep(wait_for_next)
  21.  
  22. # Turn on the selected light
  23. if light == 1:
  24. explorerhat.light.blue.on()
  25. elif light == 2:
  26. explorerhat.light.yellow.on()
  27. elif light == 3:
  28. explorerhat.light.red.on()
  29. elif light == 4:
  30. explorerhat.light.green.on()
  31.  
  32. # When a button is pressed, call the button_pressed function
  33. explorerhat.touch.pressed(button_pressed)

Notice that at the moment pressing any button will turn the light off, whether that button corresponds to the light’s number or not! That’s not quite right but we will fix it later.

Adding a timer

After you switch a light on, you need to start a timer and check how long the player takes to press the button.

  • Firstly, you will need to tell Python to import the time function. Next to your other import  statements, add the line from time import time to tell Python you want to use the time  function.

  • Go to the place in your program just before the line of code checking for the button being pressed. Create a variable called start  to record the current time: this will be provided by your Raspberry Pi and is pretty accurate.
  1. # ...other code above
  2.  
  3. # Record the current time
  4. start = time()
  5.  
  6. # ... other code below
  • You can choose how many seconds the player will have to press the button once a light is turned on. Add a constant to your program just after the game_in_progress variable with the value you have chosen. We chose to allow our player 1.5 seconds:
  1. game_in_progress = True
  2. TIME_ALLOWED = 1.5

The smaller the number, the quicker the player will have to be!

  • Now add a loop to keep checking whether the user has run over the amount of time they were allowed to take. You can think of this loop’s constant checking as being like someone on a long car journey who keeps asking “are we nearly there yet?”, “are we there now?”, “how about now?”!
  1. ...
  2.  
  3. # Record the current time
  4. start = time()
  5.  
  6. waiting_for_press = True
  7. while waiting_for_press and game_in_progress:
  8.  
  9. # What's the time now?
  10. now = time()
  11. time_taken = now - start
  12.  
  13. # Check if they have taken more time than they were allowed
  14. if time_taken > TIME_ALLOWED:
  15. print("You took too long!")
  16. explorerhat.light.off()
  17. game_in_progress = False # Lose the game
  18.  
  19. else:
  20. explorerhat.touch.pressed(button_pressed)

Move the code for dealing with button presses to be part of the else  statement. You will need to indent it for it to be in the right place.

  • If you run this code you will see that even if you press the correct button extremely quickly, the program will still declare you to have taken too long. This is because you haven’t told the game to stop checking if time is up when a button is pressed. Alter your button_pressed function to tell the code to stop the timer when a button is pressed.
  1. def button_pressed(channel, event):
  2. print("You pressed " + str(channel) )
  3.  
  4. explorerhat.light.off()
  5.  
  6. global waiting_for_press
  7. waiting_for_press = False

In this code, global allows us to change the value of the variable waiting_for_press from inside the function.

But was it the right button?

The final part of our game is to check if the button the player pressed was in fact the right button. To do this you need to edit your button_pressed function again. At the start of the function, add code to check whether the variable light (the number of the chosen light) is equal to the variable channel (the number of the button pressed):

  1. def button_pressed(channel, event):
  2. if light == channel:
  3. print("Well done")
  4. else:
  5. print("Wrong button")
  6. global game_in_progress
  7. game_in_progress = False

Once again, you will need to tell Python that you want to change the value of the variable game_in_progress from inside the function by using the word global.

That’s it! Now test your game with your friends.

Credits

Photo of Raspberry Pi

Raspberry Pi

Our mission is to put the power of computing and digital making into the hands of people all over the world. We do this so that more people are able to harness the power of computing and digital technologies for work, to solve problems that matter to them, and to express themselves creatively.

   

Leave your feedback...