1

I am making my first pygame project which is a maze project. It should print out "win" when the sprite touches blue. But when it touches blue it prints out many wins. So, I added a won variable to record is the player has already won. But it is saying that won is not defined! Please help. I am giving my code below.

import pygame
import keyboard
pygame.init()
img = pygame.image.load('maze.jpg')
spr=pygame.image.load('C:/Users/abhijato chatterjee.LAPTOP-F4VMRK00/Desktop/my 
folder/programs/python/pygame/Mushroom expansion/PNG/tallShroom_red.png')
screen = pygame.display.set_mode((640, 480))
screen.fill((255,255,255))
pygame.mixer.init()
q=False
won=False
class Players(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image=spr
        self.image.set_colorkey((255,255,255))
        self.rect=self.image.get_rect()
        self.rect.bottomleft=(30,460)
    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 2
        if keys[pygame.K_RIGHT]:
            self.rect.x += 2
        if keys[pygame.K_UP]:
            self.rect.y -= 2
        if keys[pygame.K_DOWN]:
            self.rect.y += 2
        r,g,b = screen.get_at((self.rect.bottomright[0], self.rect.bottomright[1]))[:3]
        listz=[r,g,b]
        r,g,b = screen.get_at((self.rect.bottomleft[0], self.rect.bottomleft[1]))[:3]
        listy=[r,g,b]
        r,g,b = screen.get_at((self.rect.center[0], self.rect.center[1]))[:3]
        listx=[r,g,b]
        r,g,b = screen.get_at((self.rect.right, self.rect.y))[:3]
        listw=[r,g,b]
        r,g,b = screen.get_at((self.rect.topleft[0], self.rect.topleft[1]))[:3]
        listv=[r,g,b]
        r,g,b = screen.get_at((self.rect.topright[0], self.rect.topright[1]))[:3]
        listu=[r,g,b]
    if listz==[0,0,0] or listy==[0,0,0] or listx==[0,0,0] or listw==[0,0,0] or listv==[0,0,0] or 
listu==[0,0,0]:
            self.rect.bottomleft=(30,460)
        if won==False:
            if listz[0]<21 and listz[1]>142 and listz[1]<184 and listz[2]>212 and listz[2]<254:
                print("you win!!!")
            elif listx[0]<21 and listx[1]>142 and listx[1]<184 and listx[2]>212 and listx[2]<254:
                print("you win!!!")
            elif listw[0]<21 and listw[1]>142 and listw[1]<184 and listw[2]>212 and listw[2]<254:
                print("you win!!!")
            elif listv[0]<21 and listv[1]>142 and listv[1]<184 and listv[2]>212 and listv[2]<254:
                print("you win!!!")
            elif listy[0]<21 and listy[1]>142 and listy[1]<184 and listy[2]>212 and listy[2]<254:
                print("you win!!!")
            elif listu[0]<21 and listu[1]>142 and listu[1]<184 and listu[2]>212 and listu[2]<254:
                print("you win!!!")
            won=True
player=Players()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
clock = pygame.time.Clock()
while q==False:
    screen.blit(img,(0, 0))
    pygame.display.update() 
    all_sprites.update()
    all_sprites.draw(screen)
    pygame.display.flip()
    clock.tick(30)
    for event in pygame.event.get() :
        if event.type == pygame.QUIT : 
            q=True
            pygame.quit()

and then it is giving me the following error:

Traceback (most recent call last):

  File "C:\Users\abhijato chatterjee.LAPTOP-F4VMRK00\Desktop\my folder\programs\python\pygame\maze.py", line 68, in <module>
    all_sprites.update()

  File "C:\Users\abhijato chatterjee.LAPTOP-F4VMRK00\anaconda3\lib\site-packages\pygame\sprite.py", line 463, in update
    s.update(*args)

  File "C:\Users\abhijato chatterjee.LAPTOP-F4VMRK00\Desktop\my folder\programs\python\pygame\maze.py", line 42, in update
    if won==False:

UnboundLocalError: local variable 'won' referenced before assignment

1 Answer 1

2

wow is a global variable. You have to use the global statement to access a variable in global namespace:

won=False

class Players(pygame.sprite.Sprite):
    # [...]

    def update(self):
        global won

        # [...]

        if won==False:
            # [...]

            won=True

Actually the global keyword is not so that you can read the value of a global scoped variable. It will read it just fine without it. It is only when you try to write it that you get a scoping issue. If you try to write to global scoped variable it will create a local scoped variable that hides the higher scoped variable and will not make changes to the global variable. The global tells it not to do that and to update the global variable.

Sign up to request clarification or add additional context in comments.

3 Comments

Actually the global keyword is not so that you can read the value of a global scoped variable. It will read it just fine without it. It is only when you try to write it that you get a scoping issue. If you try to write to global scoped variable it will create a local scoped variable that hides the higher scoped variable and will not make changes to the global variable. The global tells it not to do that and to update the global variable. As a tip to the OP, pylint catches and complains about this accidental hiding.
@GlennMackintosh yes, but when there's an assignment to the same variable name in code of a function, global variable is not readable by default to avoid confusing when at first iteration global variable is read and on next iteration after writing to local var, global is no longer available.
@PavelShishmarev you're correct. I'm quite certain that Rabbid76 understands these things too. My purpose was to prevent others with less understanding of the scoping hierarchy being confused by the original statement in his answer: 'You have to use the global statement to read from a variable in global namespace'. He has updated his answer, which is great. I would delete my comment now since it is unnecessary, but that would leave your comment hanging without context. Maybe we should delete all three of these since the answer now stands on its own? Not really sure of the protocol on this.

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.