Monday, January 12, 2015

Simon, Version 1

I have completed my first version of Simon. The game seems to work completely. Here are some features:
  • While the game is in "waiting" mode, it cycles through the four main game LEDs.
  • When the game starts (by pressing one of the four main buttons), the lights flash a few times to let you know that the game is about to start. Then there's a little pause, and it the game begins.
  • After the game is done giving you the sequence, there's a pause, and then the indicator light turns on to let you know it's your turn.
  • When you mess up, it shows you the sequence up to the point where you made your error, and then shows you the correct answer.
The code below gives a user display which tells you what the right button to press is. It's a bit of cheating and was used for debugging. To get rid of that, just change the DebugDisplay variable to False.
This concludes the program structure phase of this project. However, there are several more things I want to do.
  • Sounds: This is a memory tool, plus it's a programming challenge.
  • Visuals: I need to learn Pygame. It doesn't look too complex, but it will still take some time to learn the syntax and the structure of how to make the visuals work the way I want them to.
  • High scores: This is file input/output exercise. I need to read scores from a file and then export scores to a file.
And the code:
import RPi.GPIO as GPIO
import time
import random
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):
    GPIO.output(LED[LEDNum], GPIO.HIGH)
    time.sleep(OnTime)
    GPIO.output(LED[LEDNum], GPIO.LOW)

def PlayList(Listing):
    for i in Listing:
        LEDFlash(i, 0.5)
        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 = True
button = [4, 12, 16, 20, 21]
LED = [22, 5, 6, 13, 19]

# 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)
                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)
                else:
                    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)
                    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()

No comments:

Post a Comment