Python Says, Simon's Hipster Brother

Many of you may remember playing with a Simon Electronic Memory Game when you were younger, you know something that looks like this: At it’s core the game is rather simple, the device lights up random colors, and you need to repeat the pattern. Of course it gets harder the longer you play.

I thought it would be fun to build a Simon game using Raspberry Pi and a few electronic components:

I used the following components to assemble the project:

  • Raspberry Pi 3
  • 3x 330 Ohm resistor
  • 3x 1k Ohm resistor
  • White LED
  • Blue LED
  • Red LED
  • Breadboard
  • Assortment of wires

Here is a close up of the bread board and components: The Raspberry Pi’s GPIO pins are then connected to the bread board, and a small Python script powers the Simon game:


from RPi import GPIO

from sys import exit
from random import choice
from time import sleep

# define our pins for leds
white = 14
blue = 15
red = 18

# define our pins for buttonss
white_button = 21
blue_button = 20
red_button = 16

# disable warnings
GPIO.setwarnings(False)

# set the board to use broadcom pin numbering
GPIO.setmode(GPIO.BCM)

# setup our LED pins as output
GPIO.setup(white, GPIO.OUT)
GPIO.setup(blue, GPIO.OUT)
GPIO.setup(red, GPIO.OUT)

# setup our buttons as input
GPIO.setup(white_button, GPIO.IN)
GPIO.setup(blue_button, GPIO.IN)
GPIO.setup(red_button, GPIO.IN)

# create empty pattern list for simon says game
pattern = []

# create a list of our choices for simon says game
choices = [white, blue, red]

# starting difficulty based on blink durations
duration = 0.75


def add_color():
 """
 Append a random color to our pattern list
 """

 color = choice(choices)
 pattern.append(color)


def get_button():
 """
 Gets the next button press and returns
 """

 while True:
 if GPIO.input(white_button):
 return white

 if GPIO.input(blue_button):
 return blue

 if GPIO.input(red_button):
 return red

def blink(led, duration):
 """
 Blink a led for duration
 """

 GPIO.output(led, GPIO.HIGH)
 sleep(duration)
 GPIO.output(led, GPIO.LOW)


def blink_pattern(duration):
 """
 Blinks our pattern using duration as waits
 """

 for led in pattern:
 sleep(duration)
 blink(led, duration)


def check_pattern():
 """
 Checks our button presses against pattern
 """

 for led in pattern:
 if led != get_button():
 return False
 sleep(0.3) # delay so button press doesn't overlap
 return True


def game_over():
 """
 Game over function
 """

 print 'Pattern Length: {}'.format(len(pattern))
 print '''
 _____ __ __ ______ ______ ________ _____
 / ____| /\ | \/ | ____| / __ \ \ / / ____| __ \
 | | __ / \ | \ / | |__ | | | \ \ / /| |__ | |__) |
 | | |_ | / /\ \ | |\/| | __| | | | |\ \/ / | __| | _ /
 | |__| |/ ____ \| | | | |____ | |__| | \ / | |____| | \ \
 \_____/_/ \_\_| |_|______| \____/ \/ |______|_| \_\

 '''

 # blink all leds to show game over
 for _ in range(3):
 for c in choices:
 blink(c, duration=0.1)

 exit()


if __name__ == '__main__':

 # populate initial pattern
 add_color()
 add_color()

 while True:

 # blink back pattern
 blink_pattern(duration)

 # check if our inputs were correct, else end game
 if not check_pattern():
 game_over()

 # add a new color to pattern
 add_color()

 # decrease our duration to increase difficulty
 if duration > 0.05:
 duration -= 0.07

Happy Hacking!