Text-Based Pokemon Game: How do I implement an evolution system? - python

I have starting working on this Text-Based Pokemon game and I am stuck on trying to figure an evolution system that can change one class object into another class object, if that makes sense.
I've attempted to do this just by simply making the class object equal to the one I want to change:
# Trainer
new_trainer = Trainer('Trainer', 'Male')
# Test pokemon (the parameter is just a level value)
bulbasaur = Bulbasaur(10)
ivysaur = Ivysaur(20)
# Adding pokemon to party
new_trainer.add_pokemon(bulbasaur)
new_trainer.add_pokemon(ivysaur)
# Display pokemon lists
print(new_trainer.pokemon_list)
new_trainer.display_party()
# Attempting to 'evolve' bulbasuar
bulbasaur = Ivysaur(bulbasaur.lvl)
# Displaying results again to see if it worked
print(new_trainer.pokemon_list)
new_trainer.display_party()
But by looking at the output, it shows that nothing has happened:
Bulbasaur was added to your party!
Ivysaur was added to your party!
[<__main__.Bulbasaur object at 0x0000023587EDA080>, <__main__.Ivysaur object at 0x0000023587EDA0F0>]
1. Bulbasaur
2. Ivysaur
[<__main__.Bulbasaur object at 0x0000023587EDA080>, <__main__.Ivysaur object at 0x0000023587EDA0F0>]
1. Bulbasaur
2. Ivysaur
EDIT:
It turns that that the variable value DOES indeed change, but I simply need to update the Trainer's pokemon list. However, I am still unsure on how to do this.
The display_party function in the Trainer class looks like this:
def display_party(self): # Displays pokemon party list
if not self.pokemon_list:
return print("There are no pokemon in your party.")
else:
for pokemon in range(len(self.pokemon_list)):
print("{0}. {1}".format(pokemon + 1, self.pokemon_list[pokemon].name))
I was just thinking of adding an update_party function, which goes into the list, deletes the old value and inserts the new value, but how will it know what value to delete?
Perhaps there is a better way to do this? And sorry if my question doesn't include that much information, I will add more of my code if it doesn't make much sense already. This is my first time asking a question here :D
EDIT 2:
For those who don't understand how the code works, this is basically how it works so far:
# Formula used to calculate pokemon health
def health_stat_calculation(base_stat, lvl):
return int(((base_stat * 3 * lvl) / 100) + lvl + 10)
# Formula used to calculate pokemon stats
def stat_calculation(base_stat, lvl):
return int(((base_stat * 3 * lvl) / 100) + 5)
# Trainer class
class Trainer:
def __init__(self, name, gender):
self.name = name
self.gender = gender
self.pokemon_list = []
self.item_list = []
def add_badge(self, badge): # Gives player a badge
self.player_badges.append(badge)
def add_pokemon(self, pokemon): # Adds a pokemon to party
for poke in self.pokemon_list:
if pokemon is poke:
return print("You already have this pokemon in your party!")
if len(self.pokemon_list) > 5:
return print("You have too much pokemon in your party!")
else:
self.pokemon_list.append(pokemon)
return print("{} was added to your party!".format(pokemon.name))
def display_party(self): # Displays pokemon party list
if not self.pokemon_list:
return print("There are no pokemon in your party.")
else:
for pokemon in range(len(self.pokemon_list)):
print("{0}. {1}".format(pokemon + 1, self.pokemon_list[pokemon].name))
def add_item(self, item): # Adds an item to player's inventory
if len(self.item_list) > 50:
print("You have too much items in your inventory!")
else:
self.item_list.append(item)
print("{} was added to your inventory!")
# Generic pokemon class
class Pokemon:
def __init__(self, name, lvl, exp, id_number, health, attack, defence, sp_attack, sp_defense, speed):
self.name = name
self.lvl = lvl
self.exp = exp
self.id_number = id_number
self.health = health
self.attack = attack
self.defence = defence
self.sp_attack = sp_attack
self.sp_defense = sp_defense
self.speed = speed
def get_pokemon_name(self):
return self.name
# User friendly stat display
def display_stats(self):
print("\nStats for {}\n---------------".format(self.name))
print("Level: {}".format(self.lvl))
print("Index No.{}".format(self.id_number))
print("Health: {}".format(self.health))
print("Attack: {}".format(self.attack))
print("Defense: {}".format(self.defense))
print("Sp. Attack: {}".format(self.sp_attack))
print("Sp. Defense: {}".format(self.sp_defense))
print("Speed: {}\n".format(self.speed))
# Level up pokemon and show change in stats
def level_up(self):
self.display_stats()
self.lvl += 1
print("\n{} has leveled up!\n".format(self.name))
self.calculate_stats()
self.display_stats()
# Calculate generic pokemon stats
def calculate_stats(self):
self.health = health_stat_calculation(self.base_health, self.lvl)
self.attack = stat_calculation(self.base_attack, self.lvl)
self.defense = stat_calculation(self.base_defense, self.lvl)
self.sp_attack = stat_calculation(self.base_sp_attack, self.lvl)
self.sp_defense = stat_calculation(self.base_sp_defense, self.lvl)
self.speed = stat_calculation(self.base_speed, self.lvl)
# Bulbasaur class
class Bulbasaur(Pokemon):
def __init__(self, lvl, name="Bulbasaur"):
self.name = name
self.lvl = 16
self.exp = 0
self.id_number = 1
# Bulbasaur Base stats
self.base_health = 45
self.base_attack = 49
self.base_defense = 49
self.base_sp_attack = 65
self.base_sp_defense = 65
self.base_speed = 45
self.calculate_stats()
# Ivysaur class
class Ivysaur(Pokemon):
def __init__(self, lvl, name="Ivysaur"):
self.name = name
self.lvl = 16
self.exp = 0
self.id_number = 2
# Bulbasaur Base stats
self.base_health = 60
self.base_attack = 62
self.base_defense = 63
self.base_sp_attack = 80
self.base_sp_defense = 80
self.base_speed = 60
self.calculate_stats()

Casting from one class to another makes no sense in your case.
Just go with
class Pokemon():
def __init__(self, name, level=0):
self.level = level
self.name = name
def evolve(self):
self.level += 1
def __str__(self):
return 'Pokemon: {}, Level: {}'.format(self.name, self.level)
p1 = Pokemon('Bulbasaur')
p2 = Pokemon('Ivysaur')
print(p1)
print(p2)
p1.evolve()
p2.evolve()
print(p1)
print(p2)

You could turn the kind, Bulbasaur, Ivysaur, etc., into a component of the Pokemon class. The Bulbasaur has its next evolution stage as an attribute and in the evolve method of the Pokemon you can just set the kind to the next evolution stage.
class Pokemon:
def __init__(self, kind, level):
self.level = level
self.kind = kind # The kind is just a component now.
def evolve(self):
# Create a new instance of the next evolution stage
# and use it to replace the previous kind.
self.kind = self.kind.evolution_stage()
class Bulbasaur:
def __init__(self):
self.base_health = 45
# A reference to the next evolution stage class.
self.evolution_stage = Ivysaur
class Ivysaur:
def __init__(self):
self.base_health = 60
# self.evolution_stage = Venusaur
# Pass a Bulbasaur instance as the `kind` argument.
pokemons = [Pokemon(Bulbasaur(), 3)]
print(pokemons[0].kind, pokemons[0].kind.base_health)
pokemons[0].evolve() # Changes the .kind attribute.
print(pokemons[0].kind, pokemons[0].kind.base_health)

I don't know if this is the cleanest way, but somehow it worked when I added this function into the Pokemon class and used the dict dunder to update the contents of the old object to the new one. The temp_pos was used as a temporary placeholder for the current object's name so it didn't get changed when updating it to the new_pokemon object.
# Evolve function
def evolve(self, evln, trainer):
temp_name = self.name
new_pokemon = evln(self.lvl)
self.__dict__.update(new_pokemon.__dict__)
self.name = temp_name

Related

Problems with switching players and keeping track of each of their score when making a Cricket game

I want to create a very simple text-based Cricket game. But I am quite stuck.
from random import randint
class Player():
def __init__(self):
pass
def run(self, player, score):
# some code that will take a player and a score and associate that
# score with the player and store it (in a dictionary)
def switch(self, player):
# some code that will take a player name and change the current
# batsmen to the next one, for e.g this should change "a" to "b" or
# vice versa but not "c"
team_players = ["a", "b", "c"]
player = Player()
position = 0
run = randint(0,6)
current_batsman = team_players[position]
if run%2 == 0: # which means run is even
player.run(current_batsman, run) # sending the current player and their run
else: # if the run is odd
player.run(current_batsman, run) # still doing the same stuff as before but...
player.switch(current_batsman) # the current batsman should now be switched
Maybe tweaking position in the Player class somehow might help.
I hope my code explains my problem thoroughly. And by the way, in Cricket scores are called run and if a player (batsman) makes an odd run (1, 3, 5) the next batsman comes to play, and there are only two batsmen in the field until one gets out but I want my game to be really simple, for now. Any help is greatly appreciated. Thanks.
I don't know Cricket's rules but in class Player I would keep player's name and his score. It could have also function run() which adds random value to his score (or create method with parameter - value which you want to add to score)
class Player():
def __init__(self, name):
self.name = name
self.score = 0
def run(self):
self.score += random.randint(0, 6)
def __str__(self):
return "{} (score: {})".format(self.name, self.score)
I also added __str__ to easily display player.
Next I would create class Team which keeps all players, keep information which player is current batsman, switch batsman, and use run() for current batsman
class Team():
def __init__(self, players):
self.players = players
self.current_batsman = 0
self.current_run = 0
def set_next_batsman(self):
self.current_batsman += 1
if self.current_batsman >= len(self.players):
self.current_batsman = 0
def get_current_batsman(self):
return self.players[self.current_batsman]
def run(self):
self.players[self.current_batsman].run()
if self.current_run % 2 != 0:
self.set_next_batsman()
self.current_run += 1
def __str__(self):
return "Player: " + ", ".join(str(p) for p in self.players)
def total_score(self):
return sum(p.score for p in self.players)
And then two teams can play:
team1 = Team( [Player("a"), Player("b"), Player("c")] )
team2 = Team( [Player("x"), Player("y"), Player("z")] )
print('Team1:', team1)
print('Team2:', team2)
for number in range(1, 5):
print('Round:', number)
print('Team1 current batsman:', team1.get_current_batsman())
team1.run()
print('Team2 current batsman:', team2.get_current_batsman())
team2.run()
print('Team1:', team1)
print('Team2:', team2)
print('Team1 total score:', team1.total_score())
print('Team2 total score:', team2.total_score())

Python class attributes missing

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

Unsure how to access the integer values from the dictionary python

I'm not even sure you can do this. I am trying to get the integer values from attack_moves: fighter: sword punch kick in the hope that I can use these values later in an attack on a monster.
from random import randint
class Human(object):
# Question is
# Is there a way of getting sword, punch and kick interger values?
attack_moves = {
'fighter': {'sword': randint(1,8),'punch': randint(1,4),
'kick': randint(1,5)},
'Wizard': {'fire ball': randint (1,7),'staff': randint(1,6)},
}
def __init__(self, name,
present_human_hit_points, max_human_hit_points):
self.name = name
self.present_human_hit_points = present_human_hit_points
self.max_human_hit_points = max_human_hit_points
def decrease_health(self, amount):
self.amount = amount
death = False
while not death:
if self.present_human_hit_points > 0:
self.present_human_hit_points -= amount
print self.present_human_hit_points
else:
death = True
class Fighter(Human):
def __init__(self, name,
present_human_hit_points, max_human_hit_points):
Human.__init__(self, name,
present_human_hit_points, max_human_hit_points)
Human.attack_moves = Human.attack_moves.get('fighter')
#def attack_type(self, attack_moves):
# self.attack_moves = Human.attack_moves
# print attack_moves
human = Fighter("bob", 50, 100)
print human.name, human.present_human_hit_points,
print human.max_human_hit_points
print human.attack_moves

Skill creation in a python text based RPG

I am in the process of creating a text-based RPG for the purpose of learning more about OOP in Python. Right now things are going well, but I'm facing a problem that I don't exactly can find a good answer: Skill implementation. I also think that I'm going to face similar problem with the Items.
At this moment I have 3 classes(professions): Fighter, Rogue, and Mage. Each of these classes should have their own skills, but, skills have similar things(name, description, MP usage), so I created a BasicSkill class, and 3 subclasses: PassiveSkill, ActiveSkill and ChanelledSkill.
Explaining: PassiveSkill are skills that doesn't require MP to use, are always active, and in most of cases, give the player buffs, like dual-wielding, more resistance, etc. ActiveSkill are skills that require MP to be used, and, in majority, cause damage or a instant buff. Finally, ChanelledSkill are skills that require more than one turn to be used, cost more MP than the others, and can be interrupted
But, when comes to the skill creation, I can only think in something like this:
def hack_and_slash(self):
"""This is a Fighter skill, it's melee and has no cool down."""
from skills import ActiveSkill
hack_and_slash = ActiveSkill("Hack n' Slash", "A powerful double attack that has a chance of causing bleeding.",
8, 3)
self.mp -= hack_and_slash.
# more about the skill goes here, like what it does in terms of damaging, buffing, etc.
Which I think is not exactly what I'm aiming for, since I have to instantiate it every time I use, or something in the same lines.
I want to create the skills in a way that would require less instantiation, and also make more possible to cast. Also, all characters(player, npc, and enemies) can cast skills.
There's a bunch of files in this project, so I will post the ones I think are more relevant here, and, if you want, you can check out the project here.
This is my Player class:
from character import Character
# TODO implementation of player basic attacks and abilities
# TODO implementation of a D&D style skill system(diplomacy, stealth, streetwise, etc)
class Player(Character):
LEVEL_UP = 100 # initial XP to lvl up
COMMANDS = {'attack': 'a', 'character': 'c', 'inventory': 'i'} # commands available for the player
# in future this skills will be used inside and outside combat situations, for like take out an enemy in stealth,
# or convince a guard to let you in a closed door
SKILLS = {'persuasion': 0, 'intimidation': 0, 'stealth': 0, 'perception': 0}
DAILY_SELF_HEALS = 4 # each ingame day player can use 4 self heals, it resets after getting the rested status
ATTRIBUTES = {'strenght': 0, 'constitution': 0, 'dexterity': 0, 'intelligence': 0, 'wisdom': 0, 'charisma': 0}
def __init__(self, armor_class):
super().__init__(input("Tell us your name, hero:\n>"), 20, 10, {'gold': 10, 'torch': 1}, armor_class, 1)
self.exp = 0
self.max_hp = self.hp # max HP of the player
self.max_mp = self.mp # max MP of the player
self._strength = 0 # should I change it to dictionary with the attributes instead?
self._constitution = 0
self._dexterity = 0
self._intelligence = 0
self._wisdom = 0
self._charisma = 0
def level_up(self):
if self.exp >= self.LEVEL_UP:
self.lvl += 1
self.LEVEL_UP *= 1.25
self.LEVEL_UP = int(self.LEVEL_UP)
self.exp = 0
stat_choice = input(
"You have 2 points to spend in your attributes!\nType which attributes you want to raise up: ")
stat_choice = stat_choice.split(',')
self.ATTRIBUTES[stat_choice[0]] += 1
self.ATTRIBUTES[stat_choice[1]] += 1
self.max_hp = int(self.max_hp * 1.1)
self.max_mp = int(self.max_mp * 1.1)
return True
else:
return False
def gain_exp(self, exp):
self.exp += exp
print("You gained %d XP" % exp)
if self.level_up():
print("Congratulations, you gained a level!\nYour current level is %d\n" % self.lvl)
else:
print("Your current XP is %d/%d\n" % (self.exp, self.LEVEL_UP))
def get_loot(self, enemy):
# buggy right now, problem with remove inventory from dead enemy
for item in enemy.inventory:
while True:
get_item = input("You found %s! do you want to get it?(Y=yes/N=no/A=all items)" % item)
if get_item.lower() == "a":
self.inventory.update(enemy.inventory)
enemy.inventory = {}
return
elif get_item.lower() == "y":
self.inventory[item] = enemy.inventory[item]
enemy.inventory.pop(item, None)
break
elif get_item.lower() == "n":
break
else:
print("Unfortunately, you don't have this choice hero, take a look again...")
def combat(self, enemy):
"""
the combat between two entities(player and enemy)
:param enemy: the enemy of current character
:return:
"""
if super().combat(enemy):
self.gain_exp(10)
self.get_loot(enemy)
else:
print("\t\t[GAME OVER...]\t\t")
def self_heal(self):
if self.DAILY_SELF_HEALS > 0:
self.DAILY_SELF_HEALS -= 1
self.hp += int(self.max_hp / 4)
def rest(self):
rest_time = input("\tHow much time would you like to rest? ")
if rest_time >= 6:
self.STATUS['rested'] = True
def __str__(self):
str_info = "\tName: [%s]\tLEVEL: %d\n\tHP: %2d\t\tMP: %2d" % (self.name, self.lvl, self.hp, self.mp)
str_stats = "\t\tSTR: %2d\n\t\tCON: %2d\n\t\tDEX: %2d\n\t\tINT: %2d\n\t\tWIS: %2d\n\t\tCHA: %2d\n" % (
self._strength, self._constitution, self._dexterity, self._intelligence, self._wisdom,
self._charisma)
return "|%s|\n%s" % (str_info, str_stats)
This, my Character class:
# all character, being Player, NPC, or Enemy content should be implemented here
from utils import Dice
class Character:
"""
Main character class, all living entities derivate from it
"""
# a dictionary of possible status of player, the idea is that this status change gameplay/combat in the future.
# By default all characters are rested.
STATUS = {'rested': True, 'hunger': False, 'poisoned': False, 'bleeding': False, 'blind': False, 'frozen': False,
'paralyzed': False, 'dead': False}
# Right now there are only four equipment slot, which one should receive an armor object, not yet implemented
EQUIPMENT_SLOTS = {'head': None, 'chest': None, 'legs': None, 'boots': None}
def __init__(self, name, hp, mp, inventory, armor_class, lvl):
"""
Constructor for a character
:param name: name for the character
:type name: str
:param hp: hit points(health) for the character
:type hp: int
:param mp: magic points(mana) for the character
:type mp: int
:param inventory: inventory of character(gold, items, equips)
:type inventory: dict
:param armor_class: main defense
:type armor_class: int
:param lvl: level of character
:type lvl: int
:return: Character object
"""
self.name = name
self.hp = hp
self.mp = mp
self.inventory = inventory
self.armor_class = armor_class
self.lvl = lvl
self.atk_bonus = 1
self.atk_dmg = 4
self.movement_speed = 6
def take_dmg(self, dmg):
self.hp -= dmg
if self.hp <= 0:
print("\n[%s has died!]" % self.name)
self.STATUS['dead'] = True
else:
print("\n[%s has %d health left" % (self.name, self.hp))
def attack(self, enemy):
"""
All characters can attack, so this is the main attack(physical) method
:param enemy: Enemy that is in combat with character
:return:
"""
d20 = Dice(20)
dmg = self.atk_dmg
if d20.roll() + self.atk_bonus >= enemy.armor_class:
if d20 == 20:
print("CRITICAL HIT!")
dmg *= 2
else:
dice_dmg = Dice(self.atk_dmg)
dmg = dice_dmg.roll()
print("\n[%s hit %s for %d damage]" % (self.name, enemy.name, dmg))
enemy.take_dmg(dmg)
if enemy.STATUS['dead']:
return
else:
print("\n[%s missed]" % self.name)
def combat(self, enemy):
while True:
self.attack(enemy)
if enemy.STATUS['dead']:
return True
enemy.attack(self)
if self.STATUS['dead']:
break
return False
def equip_armor(self, armor_piece):
"""
Equip a piece of armor in the correspondent slot
:param armor_piece: armor piece to equip
:type armor_piece: object
:return:
"""
replace_equip = input(
"Would you like to replace %s with %s?(Y/N)" % (self.EQUIPMENT_SLOTS['head'], armor_piece.name))
if replace_equip.lower() == "y":
self.EQUIPMENT_SLOTS['head'] = armor_piece
return
else:
return
def list_inventory(self):
"""
list a character's inventory
:return:
"""
print("\t\t[%s] INVENTORY:\t\t\n" % self.name)
for item in self.inventory:
print("%s:\t%d" % (item, self.inventory[item]))
The Skill class:
# All basic skill implementation should be here
class BasicSkill:
SKILL_TYPE = {'passive': False, 'active': False, 'channeled': False}
def __init__(self, name, description, skill_type, skill_dmg=0, skill_range=0):
"""
Basic Skill class
:param name: skill name
:type name: string
:param description: description
:type description: string
:param skill_type: passive, active or channeled
:type skill_type: string
:param skill_dmg: default=0, meaning it's passive
:type skill_dmg: int
:param skill_range: default=0, meaning it's personal
:type skill_range: int
:return:
"""
self._name = name
self._description = description
self.SKILL_TYPE[skill_type] = True
self.skill_dmg = skill_dmg
self.skill_range = skill_range
class PassiveSkill(BasicSkill):
def __init__(self, name, description, skill_type='passive'):
super().__init__(name, description, skill_type)
class ActiveSkill(BasicSkill):
def __init__(self, name, description, skill_dmg, mp_use, cooldown=1, skill_type='active', skill_range=1):
super().__init__(name, description, skill_type, skill_dmg, skill_range)
self.mp_use = mp_use
self.cooldown = cooldown
class ChanneledSkill(BasicSkill):
def __init__(self, name, description, skill_dmg, channeling_time, cooldown=2, skill_type='chanelled',
skill_range=1):
super().__init__(name, description, skill_type, skill_dmg, skill_range)
self.channeling_time = channeling_time
self.cooldown = cooldown
and, as example, the Fighter class, all the classes/professions are implemented in similar way:
from player import Player
# TODO implement fighter stats and attacks
class Fighter(Player):
"""
Fighter class, a strong warrior that uses meele attacks to face his opponents
"""
def __init__(self):
super().__init__(armor_class=10)
print("\nYou have chosen the path of strength!")
self._strength += 2
self._constitution += 2
self.atk_bonus += 1
self.atk_dmg += 3
def hack_and_slash(self):
from skills import ActiveSkill
hack_and_slash = ActiveSkill("Hack n' Slash", "A powerful double attack that has a chance of causing bleeding.",
8, 3)
self.mp -= hack_and_slash.mp_use
def __str__(self):
super().__str__()
Any ideas are welcome, as well as code improvement tips. I tried to figure out a good way to make this skill implementation system, but I couldn't exactly find one. The only alternative I tough was a dictionary of skills, but I don't know how would it work. Anyway, thanks for the help.

'Character_Creation' object has no attribute 'choice'

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

Categories