One modification I made to the code was to add a 0.1 second delay with the sound in order to avoid the situation that the sound has not quite finished playing before the light goes off, thus creating a situation where you press a button and no sound comes out. I stumbled across this error while playing around with it, and since adding the delay this has not been a problem.
This is the end of what I consider to be things I kind of already knew how to do. The next step for me is to go into the graphical world of pygame.
import RPi.GPIO as GPIO
import time
import random
import pygame
GPIO.setmode(GPIO.BCM)
##### Debug Scripts
def log(msg):
if DebugDisplay == True:
print msg
##### LED Scripts
def AllLEDsOn():
for i in range(0,5):
GPIO.output(LED[i], GPIO.HIGH)
def AllLEDsOff():
for i in range(0,5):
GPIO.output(LED[i], GPIO.LOW)
def Flashes(times, pause):
AllLEDsOff()
for j in range(0,times):
AllLEDsOn()
time.sleep(0.1)
AllLEDsOff()
time.sleep(0.1)
time.sleep(pause)
def LEDFlash(LEDNum, OnTime, Sound):
GPIO.output(LED[LEDNum], GPIO.HIGH)
if Sound == 1:
toneChannel[LEDNum-1].play(tone[LEDNum-1])
time.sleep(0.1)
time.sleep(OnTime)
GPIO.output(LED[LEDNum], GPIO.LOW)
def PlayList(Listing):
for i in Listing:
LEDFlash(i, 0.5, 1)
time.sleep(0.1)
time.sleep(1)
##### Button Scripts
def LookupButton(channel):
for i in range(0,5):
if channel == button[i]:
return i
def ButtonPressed(channel):
global Pressed, Listening, Busy
TheButton = LookupButton(channel)
if (TheButton == 0):
log("Button 0 Pressed")
Pressed = 0
Listening = 0
elif (TheButton > 0 and Listening == 1):
log("Button {} Pressed -- Listening".format(TheButton))
Pressed = TheButton
Listening = 0
elif (TheButton > 0 and Listening == 0):
log("Button {} Pressed -- NOT Listening".format(TheButton))
Pressed = -1
##### MAIN GAME LOOP
# Game Constants
DebugDisplay = False
button = [4, 12, 16, 20, 21]
LED = [22, 5, 6, 13, 19]
pygame.mixer.init(48000, -16, 1, 1024)
tone = [pygame.mixer.Sound("RedTone.ogg"), \
pygame.mixer.Sound("YellowTone.ogg"), \
pygame.mixer.Sound("GreenTone.ogg"), \
pygame.mixer.Sound("BlueTone.ogg")]
toneChannel = [pygame.mixer.Channel(1), \
pygame.mixer.Channel(2), \
pygame.mixer.Channel(3), \
pygame.mixer.Channel(4) ]
# Variables
Pressed = -1
Listening = 1
GameState = 1
# Set GPIO pins
for i in range (0,5):
GPIO.setup(button[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(LED[i], GPIO.OUT)
GPIO.add_event_detect(button[i], GPIO.FALLING, callback=ButtonPressed, bouncetime=200)
# LED loop in waiting mode
while True:
Listening = 1
if GameState == 0:
log("GameState = 0, Exiting Game")
break
elif GameState == 1:
log("GameState = 1, Pressed = {}".format(Pressed))
if Pressed == 0:
GameState = 0
break
else:
for i in range(1,5):
LEDFlash(i,0.2,0)
if Pressed == 0:
GameState = 0
break
elif Pressed > 0:
GameState = 2
break
Pressed = -1
elif GameState == 2:
log("GameState = 2, Pressed = {}".format(Pressed))
Pressed = -1
Listening = 0
Simon = [random.randint(1,4)]
Flashes(5, 2)
while GameState == 2:
log("Starting a round, length = {}".format(len(Simon)))
Listening = 0
PlayList(Simon)
Flashes(1,0)
for Levels in range(0, len(Simon)):
log("Waiting for user input, correct answer = {}".format(Simon[Levels]))
GPIO.output(LED[0], GPIO.HIGH)
Listening = 1
Pressed = -1
for timerloop in range(0,500):
if Pressed > -1:
break
time.sleep(0.01)
if Pressed == Simon[Levels]:
LEDFlash(Pressed, 0.5, 1)
else:
toneChannel[0].play(tone[0])
toneChannel[1].play(tone[1])
toneChannel[2].play(tone[2])
toneChannel[3].play(tone[3])
Flashes(5,2)
GameState = 1
break
GPIO.output(LED[0], GPIO.LOW)
if (GameState == 1 and Pressed != 0):
PlayList(Simon[0:Levels])
for i in range(0,10):
LEDFlash(Simon[Levels], 0.1, 1)
time.sleep(0.1)
time.sleep(1)
elif GameState == 2:
Simon.append(random.randint(1,4))
time.sleep(0.2)
Flashes(2,0)
time.sleep(1)
GameState = 1
Pressed = -1
AllLEDsOff()
GPIO.cleanup()