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.
Related
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.
So, I have recently got into coding and I am currently developing a small turn-based RPG, but I have encountered some real issue with the battle system. I am still learning and I never thought about asking questions here. Anyway, after getting many things done correctly, I have encountered this issue where using the defend command rises the player hp for some reason. Here is the code:
import random
import sys
import os
class Entity():
def __init__(self, hp, atk, dif):
self.hp = hp
self.atk = atk
self.dif = dif
class Battle():
def Attack(self, attacker, defender):
damage = attacker.atk - defender.dif
defender.hp -= damage
def Combat(self, player, enemy):
turns = []
while True:
while len(turns) < 5:
turn = random.randint(1, 2)
if turn == 1:
turns.append("player")
else:
turns.append("enemy")
for current_turn in turns:
print(player.hp, enemy.hp)
if current_turn == "player":
print(f"TURNS: \n{current_turn}\n{turns[turns.index(current_turn)+ 1:]}")
choice = input("1. Attack\n2. Defend\n")
if choice == "1":
self.Attack(player, enemy)
player.dif = 20
elif choice == "2":
player.dif *= 2
else:
print("Lost your chance!")
elif current_turn == "enemy":
print("Enemy turn!")
print(f"Next turns are: {turns}")
enemy_choice = random.randint(1, 2)
if enemy_choice == 2:
print("He attacks you!")
self.Attack(enemy, player)
enemy.dif = 0
else:
print("He defends himself.")
enemy.dif = 10
os.system("clear")
turns.pop(0)
if player.hp <= 0:
print("You died!")
sys.exit(0)
elif enemy.hp <= 0:
print("YOU WON!")
sys.exit(0)
break
charachter = Entity(100, 15, 15)
boss = Entity(300, 40, 0)
testbattle = Battle()
testbattle.Combat(charachter, boss)
In your Battle.Attack method:
def Attack(self, attacker, defender):
damage = attacker.atk - defender.dif
defender.hp -= damage
If attacker.atk - defender.dif is a negative number, then you'll be subtracting a negative number from defender.hp, increasing it.
If I'm the player, and my defense starts out as 15, and then I defend, my defense will become 30 because of player.dif *= 2. If I defend again the next turn, my defense will be 60, which is greater than the boss' attack of 40. So, if the boss then attacks me in Battle.Attack, we would get damage = 40 - 60, which is damage = -20, effectively healing the player by twenty points.
The entity will be healed if the attackers attack value is less than the defender's defence value. Perhaps instead of subtracting the 2 values you could use a defence divisor/ multiplier
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.
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"
When User enters the food='Apple' health becomes 0 and in my loop it will continue till 3 times I want to exit the loop when health becomes 0 0r less than 0.
How can I solve the problem of exiting loop out of the function but continue to the remaining program?
print("Let us play a game")
class Hero():
def __init__(self, heroName):
self.heroName = heroName
self.health = 100
def game(self, food):
if food == 'Apple':
print("Hero is dead")
self.health = self.health - 100
#something to do here I think
elif food == 'Banana':
self.health +=30
elif food == 'Pear':
self.health -= 40
else:
print("We are strict to our rules You just got 3 choices")
x = input("Press <A> to continue")
if x == 'a':
name = input("Enter Your Name")
print("Welcome!",name, " You can Play An Intersting Game")
heroName = input(" What name do you want to give your hero")
hero = Hero(heroName)
print("Ok, Your Hero is ", hero.heroName)
print("Now lets paly the game...\n\n You have three choices to food your
hero (i) Apple (ii) Banana (iii) Pear\n\n")
i = 0
while i < 3:
food = input("What You want your hero to feed")
hero.game(food)
print("Life of",hero.heroName,"is",hero.health)
i +=1
sth = input("Press anykey and then hit <ENTER> to exit...")
You should break when the hero's health is <= 0. Add something like
if hero.health <= 0:
break
on suitable place in the loop.
Something like this:
just exit the loop means
while something:
if self.health <= 0:
break
exit the function and continue with program
while something:
if self.health <= 0:
break
call_hero()
print "Let us play a game"
class Hero():
def __init__(self, heroName):
self.heroName = heroName
self.health = 100
def game(self, food):
if food == 'Apple':
print"Hero is dead"
self.health = self.health - 100
elif food == 'Banana':
self.health +=30
elif food == 'Pear':
self.health -= 40
else:
print "We are strict to our rules You just got 3 choices"
x = raw_input("Press 'a' to continue")
if x == 'a':
name = str(raw_input("Enter Your Name"))
print "Welcome!",name, " You can Play An Intersting Game"
heroName =str(raw_input(" What name do you want to give your hero"))
hero = Hero(heroName)
print "Ok, Your Hero is ", hero.heroName
print "Now lets paly the game...\n\n You have three choices to food your
hero (i) Apple (ii) Banana (iii) Pear\n\n"
i = 0
else:
print "entry not allowed"
i=4
while i < 3:
food=str(raw_input("What You want your hero to feed"))
hero.game(food)
if hero.health<1:
i=i+4
else:
print "Life of",hero.heroName,"is",hero.health
i +=1
sth = str(raw_input("Press anykey and then hit <ENTER> to exit..."))
You can use this code to learn and make your interesting game to ride over its problems.