Seb0026
Seb0026

Reputation: 3

How to avoid globals (and use classes)?

To have some exercise in learning Python, and especially with Object orientated programming. I'm creating a simple text based game. I'm a bit struggling with the use of global variables. People say it's better to avoid them.

My question how can I make thing work without them and where to declare those variables.

Currently in my main() method I'll start the game based on Classes for every room or interaction that can happen in the game. But there are some objects I want to access anytime, like enemies or the main character, like Health, Inventory, etc (see code).

I created a global from those variables to access it anytime but I think I should not.

Any advise how I should do this?

class Character(object):

    def __init__(self, location, accuracy):
            self.current_health = 100
        self.max_health = 100
        self.max_ammo = 20
        # self.current_ammo = 0
        self.current_ammo = 20
        # self.inventory = {}
        self.inventory = {'Gun': True}
        self.location = location
        self.accuracy = accuracy


class MainCharacter(Character):
    # some extra attributes only for the main character


class EnemyChar(Character):

    def __init__(self, location, accuracy, can_see_you=True):
        self.type = 'Alien'
        self.can_see_you = can_see_you
        super(EnemyChar, self).__init__(location, accuracy)


def main():
    # Some globals to be able to access anytime
    global enemies, main_char, keypad


    # Where we start
    first_room = 'first_room'

    # Enemies
    enemies = {
        #'Enemy_1': EnemyChar('small_ally', 30, False),
        'Enemy_1': EnemyChar(first_room, 30, False),
        'Enemy_2': EnemyChar(first_room, 90)
    }

    # You
    main_char = MainCharacter(first_room, 50)

    # Stuff to interact with
    keypad = Keypad()

    map = Map(first_room)
    game = GameEngine(map)
    game.play()


if __name__ == '__main__':
    main()

Currently it works with my global variables, but I think it's not the "right" way of doing it.

Upvotes: 0

Views: 514

Answers (1)

Radosław Cybulski
Radosław Cybulski

Reputation: 2992

This is usually solved by using some global class as container for all those variables. For example:

class Game:
    def __init__(self):
        # Where we start
        self.first_room = 'first_room'

        # Enemies
        self.enemies = {
            #'Enemy_1': EnemyChar('small_ally', 30, False),
            'Enemy_1': EnemyChar(self.first_room, 30, False),
            'Enemy_2': EnemyChar(self.first_room, 90)
        }

        # You
        self.main_char = MainCharacter(self.first_room, 50)

        # Stuff to interact with
        self.keypad = Keypad()

        self.map = Map(self.first_room)
        self.game = GameEngine(map)

    def play(self):
        self.game.play()

and so on. Now when you need one of those variables, you create function, that accept Game object or you make that function become method of Game class. In your case you could probably use GameEngine instead of Game.

Upvotes: 1

Related Questions