these are 2 parts of my misbehaving text based adventure code that I'm trying to learn how to do with a youtube tutorial. I believe that most of my problems arise because the tutorial I'm pretty sure is using python2.something and I'm using 3.
My problem is I'm trying to list the "Player" class attributes on the start screen, which I have successfully done with Playername, but I'm having trouble getting the numbers listed as self.attack and self.health etc to print.
I downloaded python for the first time about 5 days ago, so bear with a noob if you can, please.
Let me know what I can change, and thank you in advance!
class Player:
def _init_(self, name):
self.name = name
self.maxhealth = 100
self.health = self.health
self.attack = 10
self.gold = 0
self.bandages = 0
def start1():
os.system("cls")
print("Name: %s" % (PlayerIG))
print("Attack: {}".format (PlayerIG.attack))
print('Health: {}/{}'.format(PlayerIG.health, PlayerIG.maxhealth))
print("Gold: %i") % PlayerIG.gold
print("Bandages: %i") % PlayerIG.bandages
A few things immediately:
def _init_ needs to be def __init__ (note the double underscores).
self.health = self.health doesn't make sense - whatever is on the right side of an = needs to exist before you can assign some other variable to it, and self.health doesn't exist until that line.
The variable PlayerIG was never assigned to anything, so none of the code in start1 will work (unless it was done somewhere else, that you haven't included in the question).
A working version of what you have in your question would be something like
class Player:
def __init__(self, name, maxhealth, health, attack, gold, bandages):
self.name = name
self.maxhealth = maxhealth
self.health = health
self.attack = attack
self.gold = gold
self.bandages = bandages
def start1():
PlayerIG = Player('foo', 100, 50, 10, 0, 0)
print('Name: {}'.format(PlayerIG.name))
print('Health: {}/{}'.format(PlayerIG.health, PlayerIG.maxhealth))
print('Attack: {}'.format(PlayerIG.attack))
print('Gold: {}'.format(PlayerIG.gold))
print('Bandages: {}'.format(PlayerIG.bandages))
start1()
There are many improvements you could make from there, like defining a __str__ function for Player or using keyword arguments in your __init__ method.
Related
I am making a game in python. I ran into some issues with the code. I defined my mobs as different classes, making it easy to edit later on. The issues I ran into is that I cannot call upon the health to deal damage on it.
class spaceStalker(object):
def __init__(self, name, hp):
self.name = name
self.hp = hp
mobList = [spaceStalker]
mob = random.choice(mobList)
killList = ["not killed the beast!", "killed the beast!"]
kill = random.choice(killList)
def game():
if mob == spaceStalker:
fleeAtt = input("A Space Stalker has appeared! Attack or flee? ")
if fleeAtt == "Attack":
hitPass = input("Attack or Pass? ")
if hitPass == "Attack":
spaceStalker.hp -= 50
print(spaceStalker.hp)
else:
print("1")```
Use an instance of the class
mobList = [SpaceStalker('some name', 54)]
And when you do the type of mob checking, you can do it with isinstance(object, classname) :
so instead of:
if mob == spaceStalker:
#dosomething
use:
if isinstance(mob, SpaceStalker):
#dosomething
I also suggest you to use getters and setters for your class:
class SpaceStalker(object):
def __init__(self, name, hp):
self.name = name
self.hp = hp
#property
def hp(self):
return self.__hp
#hp.setter
def hp(self, hp):
#some validation here
self.__hp = hp
Also, maybe you want to use the classname convention (camelcase) so I've written it as SpaceStalker
class Player:
def __init__(self):
self.speed
self.hp
def Berserker(self):
self.speed == 12
self.hp == 6
print("Berserkers stats are: " + Berserker())
So, What have I done wrong? As you can see, I'm very new to Python.
The error I'm getting is: TypeError: Berserker() missing 1 required positional argument: 'self'
You're missing quite a few things, but I'll help you out!
Your __init__ function doesn't do anything. Let's give it some base stats. I'll say that a Player's default speed and health will be 10 and 100, respectively. Then we'll make Berserker a subclass of Player (I think that's what you were going for?). And lastly, I'll give Player a method that will allow you to get a string-formatted output for its values.
First, the new Player:
class Player:
def __init__(self, speed=10, health=100):
self.speed = speed
self.health = health
def __str__(self):
return "A player with speed {} and health {}.".format(self.speed, self.health)
And now for the Berserker. I'll give it a base speed of 15 and health of 85. (Obviously the specifics are up to you!)
class Berserker(Player):
def __init__(self):
super().__init__(speed=15, health=85)
Lastly, we can create these and print the value. I'll make a couple different versions so you can see how it works. (And I'll use the regular Python interpreter for this).
>>> p1 = Player()
>>> p2 = Player(7, 120)
>>> b = Berserker()
>>> print(p1)
A player with speed 10 and health 100.
>>> print(p2)
A player with speed 7 and health 120.
>>> print(b)
A player with speed 15 and health 85.
Hopefully this gives you a good place to start!
You did a bunch of mistakes there :
Indent your Berserker method to be part of the class
Assignement in python is with one "=" not with "==" ( like most programming languages actually )
Give speed and hp initial values or don't put them in the constructor at all , in python variables are created when they're assigned a value.
Make your Berserker method return a string to be able to print it
Create an instance of your class
a working version of you code should be like this :
class Player:
def __init__(self):
self.speed = 0
self.hp = 0
def Berserker(self):
self.speed = 12
self.hp = 6
return "speed {} hp {}".format(self.speed,self.hp)
m = Player()
print("Berserkers stats are: " + m.Berserker())
Now that's a working version but it's still poorly designed IMO ,this is better :
class Player:
def __init__(self):
self.speed = 0
self.hp = 0
def Berserker(self):
self.speed = 12
self.hp = 6
def __str__(self):
return "speed {} hp {}".format(self.speed,self.hp)
m = Player()
m.Berserker()
print(m)
So i'm trying to make a very simple text-based RPG as my semester project for my programming class. I just recently learned (which is probably pretty apparent by my code) how to define classes and felt they would work much better than a function.
However, i'm having trouble with the 'character' class. Instead of having the player name predefined, I want the user to be able input their own name, which i've done in the 'Intro' function. Now my problem is taking the variable 'pName' and setting as the player's name, which I havent been able to do.
My questions are:
1. Can I do this? (use a function variable as a class attribute?)
2. Is there a better, more efficient way of doing this? And
3. Is there any additional information you guys could give me about classes or about how I can go about finishing this program?
Anything is well-appreciated and thanks in advance for the help!
import random, time
#I'm not at all hellbent on keeping this same format, it's just
#the way i've been taught and i'm most comfortable with.
def Intro():
print('Welcome puny warrior, to my Dungeon of DOOM, and stuff.')
pName = input('Tell me your name, puny warrior: ')
playResponse = input('Do you want to begin puny warrior who calls himself ' + pName + '? Y/N: ')
playResponse = playResponse.upper()
if playResponse[0:1] == 'Y':
pass
else:
print('You die now', pName)
class character(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
#this part obviously doesn't work, but I decided to leave it as a visual aid
player = character(pName, 25, 5)
#should I just make this class a child of the 'character' class?
class foes(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
zombie = foes('Zombie', 10, 3)
dragon = foes('Dragon',20, 5)
skeleton = foes('Skeleton', 8, 4)
You are trying to call internal Intro() variable - fast fix could be like this:
def Intro():
print('Welcome puny warrior, to my Dungeon of DOOM, and stuff.')
pName = input('Tell me your name, puny warrior: ')
playResponse = input('Do you want to begin puny warrior who calls himself ' + pName + '? Y/N: ')
playResponse = playResponse.upper()
if playResponse[0:1] == 'Y':
pass
else:
print('You die now', pName)
return pName
class character(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
#this part obviously doesn't work, but I decided to leave it as a visual aid
player = character(Intro(), 25, 5)
#should I just make this class a child of the 'character' class?
class foes(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
zombie = foes('Zombie', 10, 3)
dragon = foes('Dragon',20, 5)
skeleton = foes('Skeleton', 8, 4)
Some Pointers
Take a look at PEP8, the Style Guide for Python.
Use the Character Class to define both the player, and foes.
Implement a main() method and use it appropriately. For more information about this topic, visit this discussion.
Make use of Python dictionaries, as they are very powerful.
#!/usr/bin/env python
"""Simple, text-based RPG."""
import random # Generate pseudo-random numbers.
import time # Time access and conversions.
class Character(object):
"""Define the character."""
def __init__(self, name, health, attack):
self.name = str(name) # Expecting a string.
self.health = int(health) # Expecting an integer.
self.attack = int(attack) # Expecting an integer.
def properties(self):
"""Returns dictionary containing the character properties."""
# Because using dictionaries is awesome.
characteristics = {
'name': self.name,
'health': self.health,
'attack': self.attack
}
return characteristics # Returns a dictionary
def get_player():
"""Acquire the name of the player, and begin the game."""
# Newline characters should improve readability on the command line.
print('\nWelcome puny warrior, to my Dungeon of DOOM, and stuff.\n')
# Variable names should be easy to read and understand.
player_name = input(
"""
Welcome puny warrior, to my Dungeon of DOOM... and stuff.
Tell me your name: """
)
# Get and store the player's response.
player_response = input(
"""
Do you want to begin puny warrior who calls himself %s? (Y/N): \
""" % player_name
)
if player_response.upper() == "Y":
pass
else:
print('\nYou die now\n', player_name)
return player_name
def score():
"""Assign a score between 1 and 100."""
return random.randint(1, 100)
def main():
"""Where the automagic happens."""
# Assuming you want random integers.
player = Character(get_player(), score(), score()).properties()
zombie = Character('Zombie', score(), score()).properties()
dragon = Character('Dragon', score(), score()).properties()
skeleton = Character('Skeleton', score(), score()).properties()
# Since you're working with a dictictionary, you can now do things like:
print(player['name'])
print(zombie['name'], zombie['health'])
print("%s: %s, %s" % (dragon['name'], dragon['health'], dragon['attack']))
# The correct methodology.
if __name__ == "__main__":
main()
I'm not really sure what your question is. There's no difference to Python between using a variable like pName and a string like "Zombie" in a class instantiation. The only thing wrong with your code
is that you're doing that instantiation outside Intro(), so pName is not defined.
I keep getting this error 'Character_Creation' object has no attribute 'choice' but i clearly defined choice as, choice = input(">") and made the object character creation. Any help on how to fix this?
class Character_Creation():
def __init__(self):
print("""Character Creation
Whats your name?""")
Name = input(">")
print("""Chose your career
Type b for Blacksmith, a weapon-smith
Type bo for BodyBuilder, a Russian strong man
Type m for Merchant , a man with strong trade skills
""")
choice = input(">")
class Classes():
def Blacksmith():
health = 100
attack = 30
defence = 10
money = 100
def Bodybuilder():
health = 150
attack = 10
defense = 30
money = 100
def Merchant():
health = 100
attack = 5
defence = 5
money = 500
class Stats():
def __init__(self):
if c.choice == "m":
cl.Merchant()
print(attack)
t=Title_Screen()
c=Character_Creation()
cl=Classes()
s=Stats()
JBernardo is correct that you aren't using self correctly. More broadly, though, your use of classes is a bit odd. CharacterCreation seems better suited to a class method than a whole class, and having a class Classes with instance methods that define then discard local variables is a bit odd. I think want you are trying to do looks more like:
class Character(object):
def __init__(self, name, health, attack, defence, money):
self.name = name
self.health = health
self.attack = attack
self.defence = defence
self.money = money
#classmethod
def create(cls, name):
characters = {"bodybuilder": (150, 10, 30, 100), ...}
return cls(name, *characters[name])
...
if choice.lower() == "bo":
character = Character.create("bodybuilder")
If you need the different types of Character to have different instance methods and attributes, use inheritance:
def Blacksmith(Character):
def hammer_metal(self):
Im teaching myself python and I've come upon a snag in a simple game project I'm working on.
I would like to keep the players stats in a different module from the rooms that are being run by the game engine. Problem is when I try to set a Playerattribute from a different module, it doesn't save the new attribute and instantiates the original attribute.
here is the Playerclass in the entities module
class Player(object):
def __init__(self):
self.name = ' '
self.hp = 0
self.current_hp = 0
self.strength = 0
self.dexterity = 0
self.constitution = 0
And here is how im trying to manipulate and test the attributes in the rooms module
class CharacterCreation(Scene):
def enter(self):
character = entities.Player()
character.hp = 10
print character.hp
return 'barracks'
class Barracks(Scene):
def enter(self):
character = entities.Player()
print character.hp
return 'shop'
When I test this with the rest of my code, here is what I get.
-------------------------------------------------------------------------------
10
-------------------------------------------------------------------------------
0
-------------------------------------------------------------------------------
So what am I missing here? I thought I could set that attribute using =but it seems I'm mistaken? the first time I did it, it worked, but then how do i get python to set the new value of hp to 10?
You're creating a new Player object in each scene, changing its attributes, and then throwing it away.
You should be explicitly passing one single player into each scene:
def enter(self, player):
... do something with player ...
It looks like you're creating a new Player instance on every enter method...
If you're going to have only one player in the game, you could have it as a global variable (usually not very good idea) or even better, as a singleton class:
http://blog.amir.rachum.com/post/21850841339/implementing-the-singleton-pattern-in-python
I made some tweakings to the code. It adds the PlayerPool class (which is more like a cache, actually). It may give you some ideas :)
#!/usr/bin/env python
#http://stackoverflow.com/questions/14629710/python-setting-attributes-from-module-to-module/14629838#14629838
class Player(object):
def __init__(self):
self.name = ' '
self.hp = 0
self.current_hp = 0
self.strength = 0
self.dexterity = 0
self.constitution = 0
class PlayerPool(object):
_players = dict()
#classmethod
def getPlayerByName(cls, name):
if not name in cls._players:
newPlayer = Player()
newPlayer.name = name
cls._players[newPlayer.name] = newPlayer
return cls._players[name]
class Scene(object):
pass
class CharacterCreation(Scene):
def enter(self):
character = PlayerPool.getPlayerByName("foobar-hero")
character.hp = 10
print "%s has %s points of hp" % (character.name, character.hp)
return 'barracks'
class Barracks(Scene):
def enter(self):
character = PlayerPool.getPlayerByName("foobar-hero")
print "%s has %s points of hp" % (character.name, character.hp)
return 'shop'
if __name__ == "__main__":
step1 = CharacterCreation()
if step1.enter() == "barracks":
step2 = Barracks()
step2.enter()
That outputs:
borrajax#borrajax-comp:~/Tests/Python/Stack Overflow$ python ./players.py
foobar-hero has 10 points of hp
foobar-hero has 10 points of hp
Welcome to python. I'm sure you'll find it has really cool features... such as the ability to return functions, or pass functions as parameters, inspect the classes defined in any module... Looks like things you could find useful.