Module magic has no attribute damage - python

still working on my Text RPG and have run into an error in my magic doing damage i was fallowing the same format as my melee damage but then realized that i had a separate function to determine best_weapon.damage and in my spells I am just trying to pull the damage value from the spell object to modify the enemy hp.
Here is my magic.py file iv only got 2 spells for testing purposes
import player
class Spell:
def __init__(self):
raise NotIMplementedError("Do not create raw spell objects!")
def __str__(self):
return self.name
class magic_missle(Spell):
def __init__(self):
self.name = "Magic Missle"
self.discription = "A bolt of condensed magical power that you fling at an opponent."
self.damage = 15
self.mana = 10
class fire_ball(Spell):
def __init__(self):
self.name = "Fire Ball"
self.discription = "A ball of fire that explodes on impact."
self.damage = 20
self.mana = 15
this is the combat function I'm having issues with the line enemy.hp =- magic.damage which i thought would pull the damage value of the previously selected spell but i just keep getting the error module object has no value magic.
def attack(self):
spell = [magic_spell for magic_spell in self.spell_book if isinstance(magic_spell,magic.Spell)]
if not spell:
print("You have no spells to cast!")
user_input = input('What do you want to attack with? Melee or Magic: ')
if user_input == str('magic'):
for i, magic_spell in enumerate(spell, 1):
print("Choose a spell to cast: ")
print("{}. {}".format(i,magic_spell))
valid =False
while not valid:
choice = input("")
try:
if self.mana == 0:
print("You dont have enough mana")
else:
room = world.tile_at(self.x,self.y)
enemy = room.enemy
print("You use {} against {}!".format(spell,enemy.name))
enemy.hp -= magic.damage
self.mana = self.mana - spell.mana
if not enemy.is_alive():
print("You killed {}!".format(enemy.name))
else:
print("{} HP is {}.".format(enemy.name,enemy.hp))
except(ValueError,IndexError):
print("Invalid choice, try again")
elif user_input == str('melee'):
best_weapon = self.most_powerful_weapon()
room = world.tile_at(self.x,self.y)
enemy = room.enemy
print("You use {} against {}!".format(best_weapon.name,enemy.name))
enemy.hp -= best_weapon.damage
if not enemy.is_alive():
print("You killed {}!".format(enemy.name))
else:
print("{} HP is {}.".format(enemy.name,enemy.hp))
thanks for any help.

Related

Issue with Python Classes

I'm writing a simple Python program which is a text-based fighting simulator, and I'm using classes to allow myself to create heroes and enemies. I've created an attack function within my hero class, but it doesn't seem to be subtracting the enemy health from the hero strength like I want it to.
Here's the code:
import random
class Enemy:
eName = "Name"
eHealth = 0
eStrength = 0
def __init__ (self, eName, eHealth, eStrength):
self.eName = eName
self.eHealth = eHealth
self.eStrength = eStrength
def attack (self):
print("The enemy attacked you and dealt", self.eStrength, "damage!")
Hero.health -= self.eStrength
def __repr__(self):
if self.eName == "Zombie":
return "Zombie"
elif self.eName == "Skeleton":
return "Skeleton"
else:
return "Spider"
class Hero:
name = "Name"
health = 0
strength = 0
def __init__ (self, name, health, strength):
self.name = name
self.health = health
self.strength = strength
def attack(self, enemy):
print("You attacked", enemy, "for", self.strength, "damage!\n")
Enemy.eHealth -= self.strength
print(enemy, "now has", enemy.eHealth, "health points left!\n")
print("Welcome to my fighting simulator!")
hName = input("Please input your character's name:\n")
hHealth = int(input("Please enter your hero's amount of health points (10-25):\n"))
hStrength = int(input("Please enter your hero's amount of strength points (2-4): \n"))
character = Hero(hName, hHealth, hStrength)
zombie = Enemy("Zombie", 25, 3)
skeleton = Enemy("Skeleton", 15, 4)
spider = Enemy("Spider", 20, 2)
randEnemy = random.randint(1, 3)
if randEnemy == 1:
print("\nYour enemy will be a zombie!\n")
chosenEnemy = zombie
elif randEnemy == 2:
print("\nYour enemy will be a skeleton!\n")
chosenEnemy = skeleton
else:
print("\nYour enemy will be a spider!\n")
chosenEnemy = spider
while True:
if character.health == 0:
print("You died!")
elif chosenEnemy.eHealth == 0:
print("You won!")
action = input("What would you like to do? (h = heal, a = attack): ")
if (action == 'a') or (action == 'A'):
character.attack(chosenEnemy)
The main things that need to be seen are the variables in the Enemy class, the attack function in the Hero class, and the input variables for the heroes stats.
You just had a typo. In the attack() method, you wrote
Enemy.eHealth -= self.strength
instead of
enemy.eHealth -= self.strength
And since you are unable to subtract health from the Enemy class, the described problem that you mentioned occurs.

local variable assigned in enclosing line referenced before assignment

I have this bit of code
health = 12
manager_health = 10
def manager_boss_fight_used_for_backup():
sleep(1)
print("manager health is ",manager_health)
print("your health is ",health)
sleep(1)
print("the boss gets first attack")
manager_boss_damage = random.randint(1,8)
print(manager_boss_damage)
print(health)
health = health - manager_boss_damage
sleep(1)
print("the boss did",manager_boss_damage,"damage")
sleep(1)
print("your health is now",health)
if health <= 0:
sleep(1)
print("you have died")
sleep(1)
print("better luck next time")
exit()
sleep(1)
print("your turn to attack")
sleep(1)
heal_or_attack = input("Do you wish to heal or attack?(1/2)")
if heal_or_attack == "1":
healing = random.randint(1,7)
print("you have healed by",healing)
health = health + healing
manager_boss_fight_used_for_backup()
if heal_or_attack == "2":
print("you attack the boss")
sleep(1)
attack_damage = random.randint(1,6)
print("You did",attack_damage,"damage")
manager_health = manager_health - attack_damage
if manager_health <= 0:
sleep(1)
print("You have killed the boss")
sleep(1)
if manager_health > 0:
manager_boss_fight_used_for_backup()
and in the parts of code where for example health = health - manager_boss_damage it will error out. I have fiddled with global variables and all that but I cant get it to work so I came here. Any answers appreciated!
As probably everyone will tell you, using global variables is pretty bad. Why don't you use OOP instead? You can create a class Manager: and a class Player: with health as property and damage and take_damage as a method of the class, for example:
class Manager:
def __init__(self):
self.health = 10
def attack(self):
damage = ramdom.randint(1,8)
return damage
def take_damage(self, damage):
self.health -= damage
if (self.health <= 0):
self.health = 0
return self.health
then the Player class would be more or less the same:
class Player:
def __init__(self):
self.health = 12
def attack(self):
damage = ramdom.randint(1,8)
return damage
def take_damage(self, damage):
self.health -= damage
if (self.health <= 0):
self.health = 0
return self.health
def heal(self, amount):
self.health += amount
return self.health
Ideally of course, you can create one class called "Actor" or "Enemy" and derive those from there, but let's stick with this for now:
# Instantiate the classes like this:
manager = Manager()
player = Player()
# and then just invoke the methods from the classes:
sleep(1)
print("manager health is ",manager.health)
print("your health is ",player.health)
sleep(1)
print("the boss gets first attack")
damage = manager.Attack()
print("You were hit by {} points".format(damage))
player.take_damage(damage)
print("Your Health is {}".format(player.health))
Etc.
Whenever you make an assignment to health inside the manager_fight_used_for_backup() function, Python attempts to assign a new variable called health by default.
The fastest fix is to use the global keyword at the beginning of the function body, to make it clear that you're referring to the health variable outside of the function:
global health
This will tell Python that you're referring to the health variable outside of the function. However, the best solution is to refactor this code so that functions don't modify a shared global state.

whenever a object is outputed all it says is <character_template.characer object at 0x0398DA50>

I'm making a text-based adventure game and having a bit of a problem with the enemies since whenever one of them comes out all it says is
class characer:
def __init__(self,name,health,items):
self.name = name
self.health = health
self.items = items
def make_NPC():
global npc
health = [64,75,32,93,12,54]
enemy_list = ["bandit","junkie","mutated human"]
items = ["weapon","food","health items"]
npc_name = random.choice(enemy_list)
npc_health = random.choice(health)
npc_items = random.choice(items)
npc = characer(npc_name,npc_health,npc_items,)
def state_combat():
make_NPC()
global state
print(npc)
attack = 12
while state == "combat":
fight = input("press F to fight")
if fight == "F":
npc.health =- attack
print(npc)
elif fight == "I":
print("items coming soon")
elif fight == "E":
print("you've escaped the battle")
state = "defult"
elif npc.health == 0:
print("you won")
state = "defult"

My python game code is not working

I am trying to code a sort of walking on the ledge random chance game, users would input a certain amount they would like to bet and then depending on how many steps they would take, they would either live or fall off the ledge. The code so far is FAR from being finished but I have encountered a problem and I was wondering if someone could help me fix it.
import time
import random
class Player():
def __init__(self,name):
self.name = name
self.luck = 2
self.gold = 10
def main():
print("Hello what is your name?")
option = input("--> ")
global PlayerIG
PlayerIG = Player(option)
start1()
def start1():
print("Name: {}".format(PlayerIG.name))
print("Luck: {}".format(PlayerIG.luck))
print("Gold: {}".format(PlayerIG.gold))
inputgold()
def inputgold():
print("Please input how much gold you would like to play with")
goldinput = input("--> ")
strgold = str(goldinput)
print("You inputted {}".format(strgold))
if strgold <= PlayerIG.gold:
print("You don't have enough gold")
inputgold()
else:
print("Get ready to start!")
ledge()
def ledge():
print("You are standing on a ledge with an unknown length")
time.sleep(1)
choice = input("How many steps do you want to take forward? Between 1-100")
if choice == step1:
print("You have fallen off the ledge")
PlayerIG.gold -= goldinput
print("Gold: ".format(PlayerIG.gold))
elif choice == step2:
print("You...")
time.sleep(1)
print("Didn't fall off the ledge!")
PlayerIG.gold*1.2
print("Gold: ".format(PlayerIG.gold))
else:
print("You slipped off the ledge and face planted onto the side walk")
PlayerIG.gold -= goldinput
print("Gold: ".format(PlayerIG.gold))
def steps():
step1 = random.randint(10,30)
step2 = random.randint(30,50)
step3 = random.randint(50,100)
main()
When I run it is says:
if strgold <= PlayerIG.gold: TypeError: unorderable types: str() <= int()
How can I fix it?
The problem is this line:
if strgold <= PlayerIG.gold:
Here you are comparing a string with an integer. This is not possible, you have to convert the string to an integer first:
if int(strgold) <= PlayerIG.gold:
I haven't checked the rest of your code, but I suspect you might also have similar mistakes elsewhere too.

how to get out of my game while game ending conditions are not met?

this is my first attempt at python coding, or any coding for that matter.
I have made this simple little game, and it seems to be running fine but I want to add another option to it.
the code generate a random character with HP, attack power, XP and level, then generates a dragon with HP and attack power, the game then decides each time who strikes, and if the player wins he gets to get some Xp and level up, if the dragon wins the player is dead and it asks you to play again.
what I want to add is what if I'm in the middle of a fight, and don't want to continue, I want ask the user if they want to continue fighting, if not the game ends.
I've tried to do that but I failed.
Also , if there is anything I can do to enhance my code.
thanks in advance.
import random
def charGen():
char = [random.randint(1,10),random.randint(1,3), 0, 0]#[hp, power,xp,level]
return char
def drgnGen():
drgn = [random.randint(1,5),random.randint(1,5)]
return drgn
def playAgain():
print('do you want to play again?(y)es or no')
return input().lower().startswith('y')
def xpValues(levels):
for i in range(levels):
n=0
n=((i+2)**2)
xpLevels.append(n)
def xpIncrement(XP,xpLevels,char):
#returns the level of the character( the bracket in which the character XP level lies within)
#level = char[3]
for i in range(len(xpLevels)):
if XP>= xpLevels[i] and XP<xpLevels[i+1]:
#level = i+1
return i
def levelUp(char,level):
if level+1>char[3]:
char[0] += 1
char[3] += 1
print ('you are now at level %s!, your health now is %s points'%((level+1),char[0]))
def isNotDead(char):
if char[0]>0:
return True
else:
return False
while True:
XP = 5 #the default XP gain after battle win
char = charGen() #generate the character
xpLevels=[]
xpValues(15)
print (xpLevels)
print ('______________________________________')
print ('Welcome to the Battle of the dragons!')
print ("you are a fierce Warrior with %s health points and A power of %s points" %(char[0],char[1]))
print ('------------------------------------------------------------------------')
while isNotDead(char):
print(' ')
print ('While adventuring you have met a scary looking dragon')
print('Without hesitation you jump to fight it off!')
print('=============================================')
print(' ')
drgn = drgnGen() #generate a dragon
while True:
roll = random.randint(0,1)
if roll == 0:
print("the dragon hits you for %s points" %drgn[1])
char[0] = char[0] - drgn[1]
if isNotDead(char) :
print("you have %s health left!" %char[0])
input('Press Enter to continue')
print(' ')
else:
print("you're dead!Game Over")
print(' ')
break
else:
print("you hit the dragon for %s points"%char[1])
drgn[0] = drgn[0] - char[1]
if drgn[0] >0:
print("the dragon have %s health left!" %drgn[0])
input('Press Enter to continue')
print(' ')
else:
char[2]+= XP
print("Horaay!you have killed the dragon!and your experience points are now %s"%char[2])
levelUp(char,(xpIncrement(char[2],xpLevels,char)))
input('Press Enter to continue')
break
if not playAgain():
break
A quick fix to get what you want is to have a couple of flags marking whether the user is fighting or not. Also you can delay printing output until the end of the innermost loop, to avoid having to repeat too much printing:
new_dragon = True
while new_dragon:
print(' ')
print ('While adventuring you have met a scary looking dragon')
print('Without hesitation you jump to fight it off!')
print('=============================================')
print(' ')
drgn = drgnGen() #generate a dragon
fighting = True
while fighting:
message = []
roll = random.randint(0,1)
if roll == 0:
message.append("the dragon hits you for %s points" %drgn[1])
char[0] = char[0] - drgn[1]
if isNotDead(char) :
message.append("you have %s health left!" %char[0])
else:
message.append("you're dead!Game Over")
fighting = False
new_dragon = False
else:
message.append("you hit the dragon for %s points"%char[1])
drgn[0] = drgn[0] - char[1]
if drgn[0] >0:
message.append("the dragon have %s health left!" %drgn[0])
else:
char[2]+= XP
message.append("Horaay!you have killed the dragon!and your experience points are now %s"%char[2])
levelUp(char,(xpIncrement(char[2],xpLevels,char)))
continue_flag = False
for m in message:
print (m)
print ('')
if fighting:
r = input("Press enter to continue or enter q to quit")
if r is 'q':
fighting = False
To improve the code more generally:
make a Character class and classes for Player and Dragon that inherit shared properties from the Character class
the check for whether to level up can be greatly simplified by just comparing whether new_xp > xpLevels[previous_xp]
the programme will soon get over-complicated if you continue to expand it just using nested while loops. What you want is a single while loop, functions (or a class) for each stage/status of the game, variables that record the game's current status (e.g. any dragons present), and a condition that decides what to do next.
give things clear descriptive names, using classes, e.g. player.power instead of char[2]
E.g. the following...
import random
class Character:
def __init__(self, max_hp, max_power):
self.hp = random.randint(1, max_hp)
self.power = random.randint(1, max_power)
def is_dead(self):
return self.hp <= 0
def hit_by(self, enemy):
self.hp -= enemy.power
class Player(Character):
def __init__(self):
Character.__init__(self, max_hp=10, max_power=3)
self.xp = 0
self.level = 0
self.xp_thresholds = [(i + 2) ** 2 for i in range(15)]
def battle_win(self):
self.xp += battle_win_xp
if self.level < len(self.xp_thresholds) and self.xp > self.xp_thresholds[self.level + 1]:
self.level_up()
def level_up(self):
self.hp += 1
self.level += 1
print('you are now at level %s!, your health now is %s points' % (self.level + 1, self.hp))
def begin():
game.player = Player()
print('______________________________________')
print('Welcome to the Battle of the dragons!')
print("you are a fierce Warrior with %s health points and A power of %s points" %(game.player.hp, game.player.power))
print('------------------------------------------------------------------------')
def new_dragon():
print('While adventuring you have met a scary looking dragon')
print('Without hesitation you jump to fight it off!')
print('=============================================')
game.dragon = Character(5, 5)
def fight():
player, dragon = game.player, game.dragon
if random.randint(0, 1):
player.hit_by(dragon)
print("the dragon hits you for %s points" % dragon.power)
if player.is_dead():
print("you're dead! Game over")
return
else:
print("you have %s health left!" % player.hp)
else:
dragon.hit_by(player)
print("you hit the dragon for %s points" % player.power)
if dragon.is_dead():
print("Horaay!you have killed the dragon!and your experience points are now %s"%player.xp)
player.battle_win()
game.dragon = None
return
else:
print ("the dragon have %s health left!" %dragon.hp)
print "Press enter to continue (q to quit)"
if input() is 'q':
game.finished = True
def play_again():
print 'do you want to play again?(y)es or no'
if input().lower().startswith('y'):
game.__init__()
else:
game.finished = True
battle_win_xp = 5 #the default XP gain after battle win
class Game:
def __init__(self):
self.dragon = None
self.player = None
self.finished = False
game = Game()
while not game.finished:
if not game.player:
begin()
elif game.player.is_dead():
play_again()
elif not game.dragon:
new_dragon()
else:
fight()

Categories