Anthony Anthony - 22 days ago 9
Python Question

Converting globals to class

I have been using global variables for a little text game in python and have come across a lot of articles saying that global variables are a no no in python. I have been trying to understand how to get what I have below (just a health variable and being able to change it and print it) working using classes but I am confused how I can converted something like this in a class. Any help, example, point in the right direction would be great.

Here is an example of me using variables.

import sys
import time

health = 100
b = 1

def intro():
print("You will die after two moves")


def exittro():
time.sleep(1)
print("Thanks for playing!")
sys.exit()


def move():
global health
global b
health -= 50

if health <= 51 and b >0:
print("almost dead")
b = b - 1


def death():
if health == 0 or health <= 0:
print("...")
time.sleep(1)
print("You died\n")
time.sleep(2)
print("Dont worry, this game sucks anyway\n")
exittro()

intro()

a = 1

while a == 1:
input("Press Enter to move")
move()
death()


Thank you

Edit: this is the kind of thing I have been trying to do...

class Test:
def __init__(self):
number = 100

def __call__(self):
return number

def reduceNum(self):
number -=10

def printNum(self):
print(number)

a = 1
while a == 1:
input("Enter")
Test.self.reduceNum()
Test.self.printNum()


This is where I got to using global variables

import time,sys,random

#starting stats
playerhealth = 100
stamina = 100
hydration = 100

#avaliable controls
controls = {
"?" : "for help",
"move" : "to make a move",
"stats" : "to check current health status and other stats",
"rest" : "to rest and regain some stamina",
}

#introduction text
def intro():
print("\n\nWelcome, you must try to survive. Keep an eye on your health, you will die if your health reaches zero. Other factors affect how much health you lose each move, such as stamina. \nGood luck, you will need it!")
print("\ntype ? for help")

#outro text and sys exit
def outtro():
print("Thanks for playing!")
time.sleep(2)
sys.exit()

#current stats
def currents():
global playerhealth
global stamina
global hydration
print("\nHealth", playerhealth,"Stamina:", stamina, "Hydration", hydration)


def checks():
global playerhealth
global stamina
global hydration
if playerhealth > 80:
print("\nYou are in good Health")
elif playerhealth > 50:
print("\nYou are getting weaker")
elif 20 <= playerhealth <= 50:
print("\nYou are getting dangerously weak")
elif playerhealth < 20:
print("\nYou are near death")

def lowerhydration():
global hydration
hydration = hydration - 50

def lowerstamina():
global stamina
stamina = stamina - 20

def lowerhealth():
global playerhealth
global stamina
global hydration
if stamina > 60:
playerhealth = playerhealth -10
time.sleep(1)
elif stamina == 60:
print("\nWarning! Your stamina is low, Your health will now deteriorate quicker each move")
playerhealth = playerhealth - 20
time.sleep(1)
elif stamina < 60:
playerhealth = playerhealth - 20
time.sleep(1)
if hydration < 50:
print("\n You are thirsty")

time.sleep(1)
print("\nMove made...")
time.sleep(2)

#choose what to do
def makeamove():
a = 1
while a == 1:
command = input(">").split()
if len(command) == 0:
continue

if len(command) > 0:
verb = command[0].lower()

if verb == "?":
for key in controls:
print("type:", key + " - " + controls[key])
print

if verb == "stats":
currents()

if verb == "healthcheat":
global playerhealth
playerhealth = 100
print("Cheater! Your Health has been reset to full")

if verb == "move":
input("Press Enter to confirm move...")
a = 0

if verb == "rest":
global stamina
stamina = stamina + 25
print("You rested and regained stamina")
if stamina >100:
stamina = 100
else:
input("Press Enter to confirm move...")
a = 0

#Main game loop
def mainloop():
while (playerhealth>5) and (hydration !=0):
checks()
makeamove()
lowerstamina()
lowerhealth()
lowerhydration()
else:
print("Game Over")

playAgain = "yes"
while playAgain == "yes" or playAgain == "y":
intro()
mainloop()
playAgain =""
playAgain = input("Do you want to play again? (yes or y to continue playing, any other key to end the game): ")
else:
outtro()

Answer

I would avoid classes for this, as classes are generally slower. You could make the function return the new value for the health variable.

I would also suggest making a main controller function to take the return value and apply it to other functions. This prevents global variables outside of a function's scope.

import time

def intro():
    print("You will die after two moves")


def outro():
    time.sleep(1)
    print("Thanks for playing!")
    # sys.exit() # You can avoid this now by just stopping the program normally


def move(health):
    health -= 50

    if health <= 51:
        print("almost dead")
    return health  # Return the new health to be stored in a variable


def death(health):
    if health <= 0:
        print("...")
        time.sleep(1)
        print("You died\n")
        time.sleep(2)
        print("Dont worry, this game sucks anyway\n")
        return True  # Died
    return False  # Didn't die

def main():
    health = 100  # You start with 100 health
    intro()
    while not death(health):
        # While the death function doesn't return `True` (i.e., you didn't die) ...
        input("Press enter to move")
        health = move(health)  # `health` is the new health value
    outro()

If you want to use classes, you need to actually instantiate the class (Make a new object from it) by doing instance = Test(). You also need to store variables as attributes of self (so self.number = number) as any local variables are different from each other.

class Test:
    def __init__(self):
        self.number = 100

    def __call__(self):
        return self.number

    def reduceNum(self):
        self.number -= 10

    def printNum(self):
        print(self.number)

a = 1
game = Test()
while a == 1:
    input("Enter")
    game.reduceNum()
    game.printNum()
    # Or:
    print(game())
    # As you've changed `__call__` to return the number as well.