I'm a beginner and stumbled across an issue with inheritance.
When I use this block of code, the program doesn't work correctly thanks to a line in the enter function:
class Bathroom(Room):
def __init__(self):
super(Bathroom, self).__init__("bathroom")
def enter(self, world, player):
super(Bathroom, self).enter(world, player)
But, when I use this, it does:
class Bathroom(Room):
def __init__(self):
super(Bathroom, self).__init__("bathroom")
Are they not the same thing?
The full script I've written (not finished btw) is below. When I enter 'y' after being asked 'Do you want to leave', the program finishes when I use 'super' to inherit the enter function. If I don't, the program works:
while player and self.name != "corridor":
response = self._ask_question("Do you want to leave? (y/n) ", "y", "n")
if response == "y":
return world.corridor
elif response == "n" and self.enemy:
print("The", self.enemy, "kills you. You didn't even put up a\
fight")
return world.death
Full script:
import random
import time
# bad from sys import exit
class Character(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
def __str__(self):
return str(self.health) + " health and " + str(self.attack) + " attack."
class Room(object):
def __init__(self, name):
self.name = name
self.enemy = self._getRandEnemy()
def enter(self, world, player):
print(player.name + ",", "you are in the", self.name + ". You have\
" + str(player))
if self.enemy: # you may have killed it
print("But, wait! There's a", self.enemy.name, "with " + str(\
self.enemy))
response = self._ask_question("Do you stay and fight?(y/n)\
", "n", "y")
if response == "n":
pass
if response == "y":
self.combat(player, self.enemy)
else:
print("No enemies here.")
# check if player has no health after potential fight
if player.health < 1:
return world.death
while player and self.name != "corridor":
response = self._ask_question("Do you want to leave? (y/n) ", "y", "n")
if response == "y":
return world.corridor
elif response == "n" and self.enemy:
print("The", self.enemy, "kills you. You didn't even put up a\
fight")
return world.death
def _getRandEnemy(self):
names = ["Troll", "Witch", "Ogre", "Jeremy Corbyn"]
return Character(random.choice(names), random.randint(4, 6),\
random.randint(2, 3))
def _ask_question(self, question, a, b):
response = None
while response not in(a, b):
response = input(question)
return response
def combat(self, player, enemy):
while player.health > 0 and enemy.health > 0:
time.sleep(1)
print("You attack and deal", player.attack, "damage")
enemy.health -= player.attack
if enemy.health >= 1:
print("The enemy has " + str(self.enemy))
time.sleep(1)
print("The", self.enemy.name, "attacks and deals you",\
self.enemy.attack, "\
damage.")
player.health -= enemy.attack
print("You have " + str(player))
if player.health < 1:
pass
if enemy.health < 1:
print("Ha! Got him!")
self.enemy = None
class Corridor(Room):
def __init__(self):
self.name = "corridor"
self.enemy = None
def enter(self, world, player):
super(Corridor, self).enter(world, player)
room = self._ask_question("Which room: bathroom, bedroom ",\
"bedroom", "bathroom", "Library", "study")
if room == "bedroom":
return world.bedroom
if room == "bathroom":
return world.bathroom
class Bathroom(Room):
def __init__(self):
super(Bathroom, self).__init__("bathroom")
def enter(self, world, player):
super(Bathroom, self).enter(world, player)
class Bedroom(Room):
def __init__(self):
super(Bedroom, self).__init__("bedroom")
class Death(Room):
def __init__(self):
super(Death, self).__init__("death")
def enter(self, world, player):
time.sleep(1)
responses = ["Off to the man in sky. You are dead", "You died,\
no-one cried.", "Lolz. You're dead!"]
print(random.choice(responses))
return None
class World(object):
def __init__(self):
self.corridor = Corridor()
self.bathroom = Bathroom()
self.death = Death()
self.bedroom = Bedroom()
self.start = self.corridor
def play_game(world, player):
room = world.start
while room:
room = room.enter(world, player)
play_game(World(), Character("Bob", 12, 2))
I know I must be missing something obvious.
Thanks, Dave.
You forgot to return the result of the super().enter() call. You are swallowing the return value, so you never returned the new room. The following would be correct:
class Bathroom(Room):
def enter(self, world, player):
return super(Bathroom, self).enter(world, player)
Not that there is a point in defining a new Bathroom().enter() method if all you do is call the original version with super(). You may as well remove the whole enter() method (as I've done for the __init__ method, above).
Related
I'm new to coding, using sololearn and trying to make some changes to the code in a simple python game to do with injuring a goblin. It takes two words, the first is the verb and there are a few options of what you can do. Then there is the noun, and only class of character here is the goblin.
Two things I am stuck on:
I am wanting to print out the goblin's health and then the comment
(e.g. "Tis but a flesh wound") after each time he is hit.
I was also wanting to add a generic verb that allows for other types of injury; stroke, stab, and have one class that logs that as
a hit too.
Appreciate any feedback
#simple game
class GameObject:
class_name = ""
desc = ""
objects = {}
def __init__(self, name):
self.name = name
GameObject.objects[self.class_name] = self
def get_desc(self):
return self.class_name + "\n" + self.desc
class Goblin(GameObject):
def __init__(self, name):
self.class_name = "goblin"
self.health = 3
self._desc = "A foul creature"
super().__init__(name)
#property
def desc(self):
if self.health >= 3:
return self._desc
elif self.health == 2:
health_line = "Tis but a flesh wound"
elif self.health == 1:
health_line = "He's not looking good"
elif self.health <= 0:
health_line = "It is dead"
return self._desc + "\n" + health_line
#desc.setter
def desc(self, value):
self._desc = value
def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
if type(thing) == Goblin:
thing.health = thing.health -1
print(thing.health)
if thing.health <= 0:
msg = "You killed the Goblin"
else:
msg = "You hit the {}".format(thing.class_name)
else:
msg = "There is no {} here".format(noun)
return msg
goblin = Goblin("Gobbly")
def examine(noun):
if noun in GameObject.objects:
return GameObject.objects[noun].get_desc()
else:
return "What do you mean, there is no {} here".format(noun)
def get_input():
command = input(": ").split()
verb_word = command[0]
if verb_word in verb_dict:
verb = verb_dict[verb_word]
else:
print("Unrecognised verb {}, not in our incredibly limited dictionary".format(verb_word))
return
if len(command) >= 2:
noun_word = command[1]
print(verb(noun_word))
else:
print(verb("Nothing. Nada"))
def say(noun):
return "You said {}".format(noun)
verb_dict = {"say": say,
"examine": examine,
"hit": hit,
# "stab": stab,
# "stroke": stroke
}
while True:
get_input()
The part with the goblin works but the part with the elf doesn't.
#importing the random module
import random
#creating the game object class
class GameObject:
class_name = ""
desc = ""
objects = {}
def __init__(self, name):
self.name = name
GameObject.objects[self.class_name] = self
#defining the description
def get_desc(self):
return self.class_name + "\n" + self.desc
#creating the goblin class
class Goblin(GameObject):
def __init__(self, name):
self.class_name = "goblin"
self.health = 3
self._desc = "A foul creature"
super().__init__(name)
#property
def desc(self):
if self.health >= 3:
return self._desc
elif self.health == 2:
x = random.randint(13, 35)
health_line = "You struck and dealt " + str(x) + " damage!"
elif self.health == 1:
y = 40 - random.randint(13, 35)
health_line = "You rushed and dealt " +str(y) + " damage! \n Goblin activated effect Rage!"
elif self.health <= 0:
health_line = "It is dead."
return self._desc + "\n" + health_line
#desc.setter
def desc(self, value):
self._desc = value
#creating the goblin object
goblin = Goblin("Gobbly")
#creating the elf class
class Elf(GameObject):
def __init__(self, name):
self.class_name = "Elf"
self.health = 5
self._desc = "A strong warlock"
super().__init__(name)
#property
def desc(self):
if self.health >= 5:
return self._desc
elif self.health == 4:
x = random.randint(20, 50)
health_line = " You struck and dealt " + str(x) + " damage!"
elif self.health == 3:
x = random.randint(20, 40)
health_line = " You countered and dealt " + str(x) + " damage!"
elif self.health == 2:
y = 40 - random.randint(20, 50)
health_line = "You rushed and dealt " +str(y) + " damage! \n Elf activated effect Sectum Sempra!!"
elif self.health == 1:
y = 40 - random.randint(20, 50)
health_line = " You struck and dealt " + str(x) + " damage!"
elif self.health <= 0:
health_line = "It is dead."
return self._desc + "\n" + health_line
#desc.setter
def desc(self, value):
self._desc = value
#creating an elf object
elf = Elf("Elfy")
#defining the hit verb
def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
if type(thing) == Goblin:
thing.health -= 1
if thing.health <= 0:
msg = "You killed the goblin!"
else:
msg = "You hit the {}".format(thing.class_name)
elif type(thing) == Elf:
thing.health -= 1
if thing.health <= 0:
msg = "You killed the elf!"
else:
msg = "You hit the {}".format(thing.class_name)
else:
msg = "There is no {} here.".format(noun)
return msg
#defining the examine verb
def examine(noun):
if noun in GameObject.objects:
return GameObject.objects[noun].get_desc()
else:
return "There is no {} here.".format(noun)
#getting input
def get_input():
command = input(": ").split()
verb_word = command[0]
if verb_word in verb_dict:
verb = verb_dict[verb_word]
else:
print("Unknown verb {}".format(verb_word))
return
if len(command) >= 2:
noun_word = command[1]
print(verb(noun_word))
else:
print(verb("nothing"))
#defining the say verb
def say(noun):
return 'You said "{}"'.format(noun)
#the verbs
verb_dict = {
"say": say,
"examine": examine,
"hit": hit
}
while True:
get_input()
It's supposed to say |you hit the elf| when I type |hit elf| like how it says |you hit the goblin| when I type |hit goblin|
I just started learning oop in python and some parts are confusing. If anyone understands, please help me fix the code.
At first elif refers to else if , that simply means that if statement is activated then the elif statement gets skipped . So try replacing elif with if . If problem still continues , reply.
I don't see that you need to check the type of the object here:
def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
thing.health -= 1
if thing.health <= 0:
msg = "You killed the {}!".format(thing.class_name.lower())
else:
msg = "You hit the {}".format(thing.class_name)
else:
msg = "There is no {} here.".format(noun)
return msg
I have been trying to get my objects to be printed out as list. The list is the inventory. It should be printed out by typing i. But I only an error that shows there objects in a list that can't be printed. I keep getting an error. Please can you help me?
def play():
while True:
Action_input = get_player_action()
if Action_input in ["n","North"]:
print("Go North")
elif Action_input in ["s","South"]:
print("Go South")
elif Action_input in ["e","East"]:
print("Go East")
elif Action_input in ["w","West"]:
print("Go West")
elif Action_input in ["i","I"]:
print("Inventory")
for i in inventory:
print(inventory)
else:
print("Not an availble direction. Use only n,e,w,s,North,South,East, or West")
class Resources:
def __init__(self):
self.name = name
self.description = description
self.health = health
def __str__(self):
return " Name: " + self.name + "Description: " + str(self.description) + " Damage: " + str(self.damage)
class bread(Resources):
def __init__(self):
self.name = "bread"
self.description = "A kind of food that is cheap and nice."
self.health = 4
class pako(Resources):
def __init__(self):
self.name = "pako"
self.description = "A long piece of wood that can be used as a weapon"
self.damage = 10
class punch(Resources):
def __init__(self):
self.name = "punch"
self.description = "Using the fist to strike"
self.damage = 6
class owo(Resources):
def __init__(self):
self.name = "owo"
self.description = "What you use to buy goods or services"
self.value = 10
def get_player_action():
return input("What is your move?")
def best_attack_move(inventory):
Max_Attack = 0
Best_attack_move = None
for item in inventory:
if item.damage > Max_Attack:
Best_attack_move = item
Max_Attack = item.damage
return Best_attack_move
inventory = [bread(),pako(),punch(),owo()]
play()
Error:
What is your move?i
Inventory
[<main.bread object at 0x02ADC418>, <main.pako object at 0x02ADC448>, <main.punch object at 0x02ADC478>, <main.owo object at 0x02ADC4A8>]
[<main.bread object at 0x02ADC418>, <main.pako object at 0x02ADC448>, <main.punch object at 0x02ADC478>, <main.owo object at 0x02ADC4A8>]
[<main.bread object at 0x02ADC418>, <main.pako object at 0x02ADC448>, <main.punch object at 0x02ADC478>, <main.owo object at 0x02ADC4A8>]
[<main.bread object at 0x02ADC418>, <main.pako object at 0x02ADC448>, <main.punch object at 0x02ADC478>, <main.owo object at 0x02ADC4A8>]
What is your move?
a simple solution to your problem is in for loop.
elif Action_input in ["i","I"]:
print("Inventory")
for i in inventory:
print(i)
Replace inventory by i. also there are few errors as described below.
In bread class
class bread(Resources):
def __init__(self):
self.name = "bread"
self.description = "A kind of food that is cheap and nice."
self.health = 4
replace self.health by self.damage
and same for owo class
class owo(Resources):
def __init__(self):
self.name = "owo"
self.description = "What you use to buy goods or services"
self.damage = 10
replace self.value by above
Your final code should look alike
def play():
while True:
Action_input = get_player_action()
if Action_input in ["n","North"]:
print("Go North")
elif Action_input in ["s","South"]:
print("Go South")
elif Action_input in ["e","East"]:
print("Go East")
elif Action_input in ["w","West"]:
print("Go West")
elif Action_input in ["i","I"]:
print("Inventory")
for i in inventory:
print(i)
else:
print("Not an availble direction. Use only n,e,w,s,North,South,East, or West")
class Resources:
def __init__(self):
self.name = name
self.description = description
self.health = health
def __str__(self):
return " Name: " + self.name + "\n Description: " + str(self.description) + "\n Damage: " + str(self.damage)
class bread(Resources):
def __init__(self):
self.name = "bread"
self.description = "A kind of food that is cheap and nice."
self.damage = 4
class pako(Resources):
def __init__(self):
self.name = "pako"
self.description = "A long piece of wood that can be used as a weapon"
self.damage = 10
class punch(Resources):
def __init__(self):
self.name = "punch"
self.description = "Using the fist to strike"
self.damage = 6
class owo(Resources):
def __init__(self):
self.name = "owo"
self.description = "What you use to buy goods or services"
self.damage = 10
def get_player_action():
return input("What is your move?")
def best_attack_move(inventory):
Max_Attack = 0
Best_attack_move = None
for item in inventory:
if item.damage > Max_Attack:
Best_attack_move = item
Max_Attack = item.damage
return Best_attack_move
inventory = [bread(),pako(),punch(),owo()]
play()
You need to put every instance of the inventory variable inside str(), and also.
inventory = [str(bread()),str(pako()),str(punch()),str(owo())]
(By the way, the bread and owo have no damage attribute, so you will get an error about it)
I am in need of help with an assignment I have been given.
I have been asked to modify the section below from a blackjack game so that a dealer deals a card to each player and the highest card wins unless there is a draw.
I am unable to get the code right for this.
This is what i have in place:
for player in self.still_playing:
if player.total > self.players.total:
player.win()
elif player.total < self.players.total:
player.lose()
else:
player.push()
here is the rest of the code:
import Cards, Games
class BJ_Card(Cards.Card):
# Defines a Blackjack card
ACE_VALUE = 1
#property
def value(self):
if self.is_face_up:
val = BJ_Card.CARDS.index(self.card) + 1
if val > 10:
val = 10
else:
val = None
return val
# This object returns a number between 1 and 10,
# representing the value of a Blackjack card
class BJ_Deck(Cards.Deck):
# Defines a Blackjack deck
def populate(self):
for suit in BJ_Card.SUITS:
for card in BJ_Card.CARDS:
self.cards.append(BJ_Card(card, suit))
class BJ_Hand(Cards.Hand):
# Defines a Blackjack hand
def __init__(self, name):
super(BJ_Hand, self).__init__()
self.name = name
def __str__(self):
rep = self.name + ":\t" + super(BJ_Hand, self).__str__()
if self.total:
rep += "(" + str(self.total) + ")"
return rep
#property
def total(self):
# If a card has the value None, then total is None
for card in self.cards:
if not card.value:
return None
# Add card values
t = 0
for card in self.cards:
t += card.value
# Check if hand contains an Ace
contains_ace = False
for card in self.cards:
if card.value == BJ_Card.ACE_VALUE:
contains_ace = True
# treat Ace as 1
contains_ace = 1
return t
def is_busted(self):
return self.total > 21
class BJ_Player(BJ_Hand):
# Defines a Blackjack player
def is_hitting(self):
response = Games.askYesNo("\n" + self.name + ", do you want another
card? (Y/N): ")
return response == "y"
def bust(self):
print(self.name, "busts.")
self.lose()
def lose(self):
print(self.name, "loses.")
def win(self):
print(self.name, "wins.")
def push(self):
print(self.name, "draws.")
class BJ_Dealer(BJ_Hand):
# Defines a Blackjack dealer
def is_hitting(self):
return self.total < 17
def bust(self):
print(self.name, "busts.")
def flip_first_card(self):
first_card = self.cards[0]
first_card.flip()
class BJ_Game(object):
# Defines a Blackjack game
def __init__(self, names):
self.players = []
for name in names:
player = BJ_Player(name)
self.players.append(player)
self.dealer = BJ_Dealer("Dealer")
self.deck = BJ_Deck()
self.deck.populate()
self.deck.shuffle()
#property
def still_playing(self):
sp = []
for player in self.players:
if not player.is_busted():
sp.append(player)
return sp
def __additional_cards(self, player):
while not player.is_busted() and player.is_hitting():
self.deck.deal([player])
print(player)
if player.is_busted():
player.bust()
def play(self):
# Deal initial 1 card to all players
self.deck.deal(self.players, per_hand = 1)
for player in self.players:
print(player)
for player in self.still_playing:
if player.total > self.players.total:
player.win()
elif player.total < self.players.total:
player.lose()
else:
player.push()
# Remove everyone's cards
for player in self.players:
player.clear()
def main():
print("\nWelcome to the Python Blackjack game.\n")
names = []
number = Games.askForNumber("How many players? (2-7): ", low = 2, high =
8)
print()
i = 1
for i in range(number):
name = input("Enter player name: ")
if name == "":
names.append("Anon")
print()
i += 1
else:
names.append(name)
print()
i += 1
game = BJ_Game(names)
again = "Y"
while again == "y" or again == "Y":
game.play()
again = Games.askYesNo("\nDo you want to play again?: ")
main()
self.players
is a list of BJ_Player classes / objects. You're calling self.players.total i.e trying to get the property total of a python list which does not exist as this is not a property of a list. I assume you're trying to do something more like;
for player in self.players:
print(player.total)
this way you would be accessing each players total. However, the class BJ_Player does not appear to have a total property either, so you will need to add this to the class and then use a loop like the one given above.
I am new to programming in python and, I started writing a simple text based adventure game. I came across a problem when passing an object from one function to another. Here is my code:
import random
import time
num = random.randint(0,2)
xp1 = random.randint(1,2)
class player:
def __init__ (self, name, health, strength, defense, potion, xp, level):
self.__health = health
self.__strength = strength
self.__defense = defense
self.__name = name
self.__potion = potion
self.__xp = xp
self.__level = level
def getName(self):
return self.__name
def getHealth(self):
return self.__health
def getStrength(self):
return self.__strength
def getDefense(self):
return self.__defense
def getPotion(self):
return self.__potion
def getXP(self):
return self.__xp
def getLevel(self):
return self.__level
def setHealth(self):
self.__health = 10
def setLevel(self):
self.__level = 1
def subHealth(self, num):
self.__health -= num
def subPotion(self):
self.__potion -= 1
return self.__health
def addPotion(self, num1):
self.__potion += num1
def addHealth(self):
self.__health +=2
def addStrength(self):
self.__strength += 1
def addDefense(self):
self.__defense += 1
def addXP(self):
self.__xp += xp1
def addLevel(self):
self.__level += 1
self.__addHealth += 1
self.__defense += 1
self.__strength += 1
def battle(enemy, player1, name1):
player1 = player(name1, player1.getHealth(), player1.getStrength(), player1.getDefense(), player1.getPotion(), player1.getXP(), player1.getLevel())
enemy = player('Dongus', enemy.getHealth(), enemy.getStrength(), enemy.getDefense(), enemy.getPotion(), enemy.getXP(), enemy.getLevel())
s = 0
while s == 0:
time.sleep(1)
attack =int(input("Type 1 to attack, type 2 to use a potion."))
if attack == 1:
time.sleep(1)
print("Dongus's health is", enemy.subHealth(num))
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
elif attack == 2:
time.sleep(1)
print("You used a potion.")
player1.addHealth(), player1.subPotion()
if player1.getHealth() > 10:
player1.setHealth()
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
if enemy.getHealth()<=0:
print("Congratulations, you won! You recieved", xp1, "xp!")
player.addXP()
s = 2
def main():
name1 = input("What would you like your name to be?")
time.sleep(1)
print("Hello,", name1, "you are on a quest to save otis from the evil Dongus. You must slay him, or Otis will poop.")
time.sleep(2)
player1 = player(name1, 10, 2, 1, 0, 0, 1)
enemy = player('Dongus', 8, 4, 0, 0, 0, 0)
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player1.getDefense())
time.sleep(2)
print("Fight!")
pick = input("You found a health potion! Press 'p' to pick it up.")
p = 0
while p == 0:
if pick == "p":
print("You added a potion to your inventory.")
player1.addPotion(1)
p = 2
else:
print("You have no potions, you should probably pick this one up.")
player1.addPotion(1)
p = 2
battle(enemy, player1, name1)
if self.__getXP() == 1:
print("You leveled up. You are now level 2.")
player1.addLevel()
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player.getDefense())
loot1 = int(input("Type ''1'' to loot the enemy chest."))
if loot1 == 1:
print("You recieved two potions!")
player1.__addPotion(2)
enemy.setHealth(10)
battle(enemy, player1, name1)
main()
Now the problem is when I run the game, I get to a point where I type "1" to attack the enemy, but it says, for some reason, that after attacking the enemy, the enemies health is at "None". This is the same case when the enemy attacks player1, it says player1's health is at "None". I assume that "None" is the default value in python 3.4.1, so my thinking is that the player1's object from def main() are not being transferred over to def battle() and I cannot see the reason why this is happening. I most likely am missing something here, or it is something I do not already know about Python that is causing the issue. Does anybody know what I can do to fix this, and why it is doing this?
BTW some of the terms I am using may be wrong, so please correct me if they are... I have only been coding for 2 weeks :p.
Thanks!!!
First, received not recieved
2nd yes, If you have a Python function that does not return a value, the result is None
# dummy will return "Positive" or None
def dummy(x):
if X > 0:
return "Positive"
So, you probably want to change
def subHealth(self, num):
self.__health -= num
to
def subHealth(self, num):
self.__health -= num
return self.__health
Your question re: the "player" classes from def main() are not being transferred over to def battle() does not really make sense to me.
But, I see that in the first 2 lines of battle, you are replacing the formal parameters player1 and enemy with local variables, this seems like odd usage in your program.