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:
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")