Reputation: 5
This is my basic randomised movement program where a cube runs down and right along going different distances each time it goes down and each time it goes right.
When writing the program i had the error message of: UnboundLocalError: local variable 'wantedcordx' referenced before assignment and UnboundLocalError: local variable 'wantedcordy' referenced before assignment
i fixed the problem by making both the variables global inside the function but have no idea why I had to do this or why it works:
Heres the program :(not very well written i'm a begginer)
import pygame,sys,random
from pygame.locals import *
#colours
red =(255,0,0)
white=(255,255,255)
#variables/objects
x = 50
y = 50
FPS = 60
clock =pygame.time.Clock()
screen = pygame.display.set_mode((800,600))
xcord = random.randint(1,100)
ycord = random.randint(1,100)
newcords_needed = False
run_once = False
def get_newcords():
global x,y
global run_once
global newcords_needed
wantedcordx
global wantedcordy
if run_once == False:
xcord = random.randint(1, 100)
ycord = random.randint(1, 100)
wantedcordy = (y + ycord)
wantedcordx = (x + xcord)
run_once = True
print(wantedcordx)
if newcords_needed == True:
xcord = random.randint(1,100)
ycord = random.randint(1,100)
wantedcordy = (y + ycord)
wantedcordx = (x + xcord)
newcords_needed = False
if x != wantedcordx:
x_done = False
x +=1
elif x == wantedcordx:
x_done = True
if x_done == True:
if y != wantedcordy:
y +=1
elif y == wantedcordy:
y_done = True
newcords_needed = True
return (x,y)
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
get_newcords()
screen.fill(white)
pygame.draw.rect(screen, red, [x,y,20,20])
pygame.display.update()
It never copys and pastes in correctly but I did my best to reformat it.
Upvotes: 0
Views: 72
Reputation: 56
Check out the official programming documentation FAQ for Python, specifically the section about "Why am I getting an UnboundLocalError when the variable has a value?": https://docs.python.org/2/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
The question immediately after deals with why and where "global" is needed, which may also be helpful to you.
In short, it's a choice in the Python language to allow access to global definitions "implicitly" (meaning it's a safe assumption in most cases), but the ability to change them requires the explicit use of the "global" keyword. The limitation is to remind you that you are modifying something that may be shared (ie global) which may introduce unintended side-effects in other sections of your code if you are not mindful. The only reason that they did not require "global" for accessing the value as well is because the resulting "clutter would defeat the usefulness of the global declaration for identifying side-effects."
It should be noted that utilizing globals in many scenarios is considered bad practice, not just in Python, and that the ideal solution in Python is typically utilizing the namespacing system offered by modules. This is further detailed in the FAQ section I linked you. However, when developing a simple game, it is often useful (practical?) to have a set of globals as the "one true source of truth" at any given moment represent the state of the world accessible to most portions of code.
Upvotes: 1
Reputation: 140256
in def get_newcords()
, if run_once == True
and newcords_needed == False
, the first time variable wantedcordx
is accessed is here:
if x != wantedcordx:
since the first time it's accessed in that case is through a read access, you get "undefined variable", unless you define it global like you did.
(same goes for wantedcordy
)
Defining them global
has the following effect: since at first call of the function, you assign wantedcordx
to something, it remains valid in the next function calls.
Upvotes: 1