This is all about scope, where you declare a variable (where it is first used, eg myVar = 0
) declares it’s scope. The scope is ended when an indentation level is decreased. For example:
def foo():
myVar = 0
print (myVar)
will throw the exception myVar is not defined
because it was not declared in that scope.
This also be shown here:
myVar = 2
def foo():
myVar = 0
print (myVar)
will output 2
not 0
because the first myVar is not the same as the second myVar, even though they have the same name. The second myVar’s scope ends when the function ends.
When you pass parameters, you are passing that variable to be used inside another function (there are caveats and exceptions here so note that I am simplifying the details of this). For example:
def bar(param):
print (param)
param += 1
def foo():
myVar = 0
bar(myVar)
print (myVar)
foo()
Here several important things happen. First, foo is called (at the bottom). Second, myVar is created inside foo()'s scope and initialized to 0. Then, bar is called with myVar as a parameter. The key here is that when print(param)
is called, param is not the same variable as myVar. Rather, myVar was copied to param, and now param is in the scope of bar. Bar prints param, the copy, adds 1 to param and then returns to function foo. Then foo prints out myVar. myVar is still 0, because even though param was incremented by 1, that is a different variable. So the output of the above would be:
0
0
This is because an integer (number) is what is called immutable in python. A list or object would be called mutable. Things that are immutable will work like above, things that are mutable will work differently. Here is an example of a mutable:
def bar(param):
print (param)
param.append(2)
def foo():
myList = [1]
bar(myList)
print (myList)
foo()
which outputs:
[1]
[1, 2]
Classes and Objects
The classic example for classes and objects is with blueprints. If you have a house, the blueprint for how to build the house would be the class, and the actual house itself would be the object. In strongly typed languages (C++, Java, etc) this is much more regulated and certain structures are forced. In python, you are much more free to do what you want (and thus more room for errors like the one you are experiencing).
game_state is an object made from the class GameState. You can see it is created using game_state = gamelib.GameState(self.config, turn_state)
(ignore the gamelib part for now, I’ll answer that in your other thread).
When game_state is not defined, it means you are trying to use game_state when it has not been created (just like any other variable). Thus, you must pass it as a parameter everywhere you want to use it or declare it as part of the class (and thus the object when you make it). Whenever you get that error, it means it is not in the scope of where you are using it.