2

First post and and only been learning Python for 3 weeks...

I'm trying to create a game where 2 players have to wait for a buzzer sound connected to a breadboard and then press a button to see who is first.

This worked fine until I tried to add a method of keeping score. Now when the game runs the buzzer doesn't stop when the button is pressed and I get several error messages that repeat in the window. Can anyone help me to see what I've done wrong please?

from gpiozero import Button, LED, Buzzer
from time import time, sleep
from random import randint

led1 = LED(17)
led2 = LED(27)
btn1 = Button(14)
btn2 = Button(15)
buz = Buzzer(22)
score1 = 0
score2 = 0

btn1_name = input('right player name is ')
btn2_name = input('left player name is ')

while True:
    print(btn1_name + ' ' + str(score1) + ' - ' + btn2_name + ' ' + str(score2))
    sleep(randint(1,10))
    buz.on()
    def pressed(button):
        if button.pin.number == 14:
            print(btn1_name + ' won the game')
            score1 += 1
        else:
            print(btn2_name + ' won the game')
            score2 += 1
        buz.off()
    btn1.when_pressed = pressed
    btn2.when_pressed = pressed

The output messages are as follows

dave 0 - keith 0
keith won the game
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/gpiozero/pins/rpigpio.py", line 232, in <lambda>
    callback=lambda channel: self._when_changed(),
  File "/usr/local/lib/python3.4/dist-packages/gpiozero/mixins.py", line 311, in _fire_events
    self._fire_activated()
  File "/usr/local/lib/python3.4/dist-packages/gpiozero/mixins.py", line 343, in _fire_activated
    super(HoldMixin, self)._fire_activated()
  File "/usr/local/lib/python3.4/dist-packages/gpiozero/mixins.py", line 289, in _fire_activated
    self.when_activated()
  File "/usr/local/lib/python3.4/dist-packages/gpiozero/mixins.py", line 279, in wrapper
    return fn(self)
  File "/home/d.chilver/twobuttonreaction.py", line 26, in pressed
    score2 += 1
UnboundLocalError: local variable 'score2' referenced before assignment
dave 0 - keith 0

1 Answer 1

1

The problem is a problem of scoping. The two variables score1 and score2 are in the so called global scope. But you want to use them locally in a function. Python tries to create a local variable called score1 or score2 respectively by assigning a local variable score1 or score2 and then adding 1. Since the variable does not exist yet, you are subjected to the error message that you see.

In order to access the global variables you have to mark them explicitly like this:

[...]
def pressed(button):
    global score1
    global score2
    if button.pin.number == 14:
        print(btn1_name + ' won the game')
        score1 += 1
    else:
        print(btn2_name + ' won the game')
        score2 += 1
    buz.off()
[...]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer! It was a big help. Just as a follow up... are global variables like my original ones bad practice? My next step is to stop the game accepting spam inputs. As it stands the player can hammer the button and receive a +1 score each time regardless of when the buzzer sounds. Any ideas would be a great help.
There is no problem with using global variables. Check out this gist: gist.github.com/NemoNessuno/1121acc79823f1d54dc83f8258118162 for some ideas regarding the input spam. Please note that I did not check the code because I'm at work right now, so if you encounter some problems please send me a message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.