[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Initializing and Reinitializing Instance variables



For just a score variable, it's probably not a big deal to have an = 0 in there twice as duplicate code, but games are complicated and so I'm sure you've got lots of other fields as well, and that's where the duplication becomes problematic, especially if it's just there to appease the linter. I'm assuming the Game object is sort of an application context that survives the entire duration of the program's runtime, and that aside from score, you have a variety of other fields as well that need to be reset. For things like this, I would split game into a 2-tiered object, where each object has the desired lifespan. Something like this...

class ApplicationContext:
  def __init__(self):
    self.session = GameSession()

  def reset(self):
    self.session = GameSession()

class GameSession:
  def __init__(self):
    self.score = 0
    self.player_location = (0, 0)
    self.zombies = self.build_zombie_list()
    self.im_just_making_up_examples = etc

Nope, this doesn't solve your fundamental problem of getting rid of a duplicate assignment, but it does group things with identical lifecycles so that the duplication is always limited to just the single 'session' field no matter how complicated your game becomes.


On Sat, May 25, 2019 at 11:37 AM Irv Kalb <Irv@xxxxxxxxxxxxxx> wrote:
Hi,

I am teaching an Python object-oriented programming class based on my own materials.  I am using Pygame to explain many OOP concepts.  So far its going very well.

I have built many small games as examples, but I keep running into a design dilemma.  I will often have a class, where I have an instance variable (I know it should be called an attribute!), and I want to be able to give it a starting value, but I also want to be able to reset it to the same value if the game is played more than once.  As a trivial example, here is the start of a Game class, that keeps track of the score of the game:

class Game:
    def __init__(self):
        self.score = 0

    def reset(self):
         self.score = 0

My main code instantiates a Game object and the game plays.  If the user wants to start the game over, I call the reset method.  There are two different problems with this approach:

  1) I am duplicating code.  This gets nasty when I have lots of instance variables to reset.
  2) Any time I want to change the "starting" value, I must make the identical change in both methods.

The obvious solution is to have the __init__ method call the reset method:

class Game:
    def __init__(self):
         self.reset()

    def reset(self):
          self.score = 0

That does work fine and I like it.  But it breaks a general rule that you should declare all instance variables in the __init__ method.  I use PyCharm for the development of these games, and the "linter" (over the right side scroll bar) always flags this as a warning that a variable like this is not defined in my __init__ method.

I'm looking for a general solution that solves this.  The best I've come up with so far is to do something like this for each instance variable:

class Game:
    def __init__(self):
         self.score = None  # create the variable here, but only assign it a value in the reset method below
         self.reset()

    def reset(self):
          self.score = 0  # Supply the actual start value here.

Anyone have any other suggestions for how to do this cleanly?

Thanks,

Irv