Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is my Integer value becoming NoneType when the calculation is performed?

I am doing a simple -= calculation between 2 integers, but for some reason after being performed a couple times, once I am attacked, the integer "playerHealth" becomes a NoneType.

The program is supposed to be a basic fighting game with text appearing in the terminal, it chooses a random type of opponent with a random level. The player chooses the type of attack they wish to do and then get attacked back, the error is when the enemy fights back.

When the code is executed, it should send the message into the console that the player has taken damage and then show how much remaining health there is, however instead, I am given the following error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The error

Traceback (most recent call last):
  File "c:\Users\277563\OneDrive\Python\Practice01.py", line 119, in <module>
    main()
  File "c:\Users\277563\OneDrive\Python\Practice01.py", line 116, in main
    playerHealth = run.opponentMoves(playerHealth)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\277563\OneDrive\Python\Practice01.py", line 91, in opponentMoves
    playerHealth -= self.attack
TypeError: unsupported operand type(s) for -=: 'NoneType' and 'int'

My code:

class Player:
    def __init__(self, playerHealth):
        self.health = playerHealth
        self.defence = 0
        self.attack = 8
        self.level = 1
        self.moves = ["Block","Attack","Dodge","Flee"] #Note: Dodges will be 50/50

    def moveMenu(self):
        print("\n1. " + self.moves[0] + "\t2. " + self.moves[1] + "\n3. " + self.moves[2] + "\t4. " + self.moves[3])
        return None
    
    def moveSelect(self):
        while True:
            try:
                selection = int(input("\nSelect an option (1-4): "))
                while selection not in [1,2,3,4]:
                    selection = int(input("\nSelect an option (1-4): "))
                int(selection)
                break
            except:
                print("Must enter option between 1-4.")
        return selection
    
    def moveExecution(self,move,oppNum,health):
        import random as rd
        enemy = Enemy(health)
        flee = 0
        chance = 1
        if move == 1:
            print(r"You attempt to block the attack and take 50% less damage.")
            self.health -= enemy.attack/2
            print("\nDamage taken: " + str(enemy.attack/2) + "\nHealth remaining: " + str(self.health))
            return chance, flee, health
        elif move == 2:
            print("You attempt to attack the enemy.")
            health -= self.attack
            print("\nDamage dealt: " + str(self.attack) + "\nOpponent health remaining: " + str(health))
            return chance, flee, health
        elif move == 3:
            print("You try to dodge out the way of the enemy.")
            chance = [1,2]
            chance = chance[rd.randint(0,1)]
            if chance == 0:
                print("You have successfully dodged out the way of the enemy.\nDamage taken: 0\nHealth remaining: " + str(self.health))
                return chance, flee, health
            else:
                print("Dodge unsuccessful.")
                return chance, flee, health
        else:
            if self.level <= oppNum:
                print("You attempt to flee, but the enemy is too quick!") #Note: Only happens if opponent is a higher level
                return chance, flee, health
            else:
                print("You have successfully escaped the enemy.")
                flee = 1
                return chance, flee, health
        
                
            

class Enemy:
    def __init__(self, health):
        self.messages = ["Stop right there!", "You owe me money!", "Thought you could walk past without fighting me?","Give us all yer gold!"]
        self.deathMessages = ["Agh!", "Noooo!", "...", "You-"]
        self.health = health
        self.types = ["Bandit","Mugger","Highwayman"]
        self.defence = [0,2,5]
        self.attack = 8
        self.level = [1,2,3,4,5,6,7,8,9,10]
        self.moves = ["Block","Attack"]

    def determineOpponent(self):
        import random as rd
        oppNum = rd.randint(1,len(self.level)-1)
        oppType = self.types[rd.randint(0,len(self.types)-1)]
        return oppNum, oppType
    
    def opponentMessage(self,oppNum,oppType):
        import random as rd
        print("\n\n\nYou have encountered a level " + str(oppNum) + " " + oppType + "!\n")
        print(oppType + ": " + self.messages[rd.randint(0,len(self.messages)-1)])
        return None

    def opponentMoves(self,playerHealth):
        import random as rd
        oppMoves = ["Attack","Block"]
        oppMove = oppMoves[rd.randint(0,1)]
        if oppMove == "Attack":
            print("The enemy attacks you.")
            playerHealth -= self.attack
            print("\nDamage Received: " + str(self.attack) + "\nHealth remaining: " + str(playerHealth))
            return playerHealth
        else:
            print("Works")

def main():
        health = 100
        playerHealth = 100
        run = Enemy(health)
        running = Player(playerHealth)
        oppNum, oppType = run.determineOpponent()
        run.opponentMessage(oppNum,oppType)
        while True:
            running.moveMenu()
            move = running.moveSelect()
            chance, flee, health = running.moveExecution(move,oppNum,health)
            if flee == 1:
                running.health = 100
                break
            else:
                pass
            if chance == 0:
                pass
            else:
                playerHealth = run.opponentMoves(playerHealth)
    
if __name__ == "__main__":
    main()

>Solution :

playerHealth = run.opponentMoves(playerHealth)

you are calling opponentMoves method and store the return value to playerHealth here, but opponentMoves does not always return a value. If oppMove is something different than "Attack", this code block runs and thus the method returns None.

else:
            print("Works")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading