Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from pathlib import Path
- import json
- class RPG_Character:
- def __init__(self, **stats_dict):
- for stat in stats_dict:
- setattr(self, stat, stats_dict[stat])
- # need to convert self.inventory
- # it's a list of dictionaries if we have recreated this from JSON
- if self.inventory and isinstance(self.inventory[0], dict):
- self.inventory = [Item(**kwargs) for kwargs in self.inventory]
- def label2attribute(self, label):
- """Return the attribute value given the N character label."""
- for attr in dir(self):
- if attr.startswith(label):
- return getattr(self, attr)
- return '~' # error, not found, return this rather than None
- def __str__(self):
- """Return values in instance in a more compact display form.
- More work, but it's easier to check output for correctness.
- This could be done in a better way, but this is more readable.
- """
- result = []
- # do name and inventory
- inv = [item.name for item in self.inventory]
- line = f'Name:{self.name} Inventory: {', '.join(inv)}'
- result.append(line)
- # header line for the other attributes
- line = []
- for (label, width) in char_display:
- line.append(f'{label:^{width}}')
- result.append('|'.join(line) )
- # divider line
- line = []
- for (_, width) in char_display:
- line.append('-' * width)
- result.append('+'.join(line) )
- # now put the attribute values under the header line
- # this is a bit of a fudge, uses label2attribute() helper
- line = []
- for (label, width) in char_display:
- value = self.label2attribute(label)
- line.append(f'{value:^{width}}')
- result.append('|'.join(line))
- result.append('') # to get ending newline
- return "\n".join(result)
- def add_gold(self, amount):
- self.gold += amount
- def remove_gold(self, amount):
- self.gold -= amount
- if self.gold < 0:
- print("Gold amount can't be below zero.")
- self.gold += amount
- def increase_level(self):
- self.level += 1
- self.strength += self.growth[0]
- self.dexterity += self.growth[1]
- self.agility += self.growth[2]
- self.endurance += self.growth[3]
- self.intelligence += self.growth[4]
- self.wisdom += self.growth[5]
- self.health += self.growth[6]
- self.mana += self.growth[7]
- def add_item(self, item):
- self.inventory.append(item)
- # probably not needed now
- # def show_inventory(self):
- # print("=====Inventory=====")
- # for item in self.inventory:
- # print(item)
- # print("=====Inventory=====")
- def to_dict(self):
- # saved_inventory = []
- # for item in self.inventory:
- # saved_inventory.append(item.to_dict())
- return {'name': self.name,
- 'job': self.job,
- 'level': self.level,
- 'health': self.health,
- 'mana': self.mana,
- 'strength': self.strength,
- 'dexterity': self.dexterity,
- 'agility': self.agility,
- 'endurance': self.endurance,
- 'intelligence': self.intelligence,
- 'wisdom': self.wisdom,
- 'gold': self.gold,
- # use comprehension to handle inventory
- # 'inventory': saved_inventory
- 'inventory': [item.to_dict() for item in self.inventory]
- }
- class Item:
- def __init__(self, **kwargs):
- # handle dictionary a different way than used for RPG_Character
- # you decide which is better
- for (key, value) in kwargs.items():
- setattr(self, key, value)
- self.sell_price = self.buy_price // 4
- def __str__(self):
- # the (f"..." f"...") thing is a way of handling lines too long
- return (f'Item:{self.name} Type:{self.item_type} '
- f'Buy:{self.buy_price} Sell:{self.sell_price}'
- )
- def to_dict(self):
- return {'name': self.name,
- 'type': self.type, # we know it's an Item, no need for 'item_type'
- 'buy_price': self.buy_price,
- 'sell_price': self.sell_price
- }
- def convert_dict_to_obj_inv(list_of_dicts):
- return [Item(**d) for d in list_of_dicts]
- # list_of_items = []
- # for temp_dict in list_of_dicts:
- # current_item = Item(temp_dict['name'], temp_dict['type'], temp_dict['buy_price'])
- # list_of_items.append(current_item)
- # return list_of_items
- ######### start of code
- # it's better to keep all top-level CODE at the bottom of a file
- # otherwise it's hard to see where the code is in the file
- path = Path('data.json')
- list_of_characters = []
- # List of jobs
- warrior_class = {'job': 'Warrior', 'strength': 5, 'dexterity': 4, 'agility': 3,
- 'endurance': 5, 'intelligence': 3, 'wisdom': 4, 'health': 50,
- 'mana': 30, 'growth': [3, 2, 1, 3, 1, 2, 10, 4],
- 'inventory': []}
- rogue_class = {'job': 'Rogue', 'strength': 4, 'dexterity': 5, 'agility': 5,
- 'endurance': 3, 'intelligence': 4, 'wisdom': 3, 'health': 40,
- 'mana': 40, 'growth': [2, 3, 3, 1, 2, 1, 7, 7], 'inventory': []}
- mage_class = {'job': 'Mage', 'strength': 3, 'dexterity': 3, 'agility': 4,
- 'endurance': 4, 'intelligence': 5, 'wisdom': 5, 'health': 30,
- 'mana': 50, 'growth': [1, 1, 2, 2, 3, 3, 4, 10], 'inventory': []}
- # character display data for .__str__()
- # each tuple is (<label>, <width>)
- # <label> MUST BE first N characters of attribute name
- char_display = (('job', 7), ('leve', 4), ('heal', 4), ('mana', 4), ('stre', 4),
- ('dext', 4), ('agil', 4), ('endu', 4), ('inte', 4), ('wisd', 4),
- ('gold', 4),
- )
- # create the items
- # no need for 'item_type', it's an attribute of Item so no need for 'item'
- health_data = {'name': 'Basic Health Potion', 'type': 'Consumable',
- 'buy_price': 16}
- mana_data = {'name': 'Basic Mana Potion', 'type': 'Consumable',
- 'buy_price': 20}
- shield_data = {'name': 'Wooden Shield', 'type': 'Equipment',
- 'buy_price': 40}
- basic_health_potion = Item(**health_data)
- basic_mana_potion = Item(**mana_data)
- wooden_shield = Item(**shield_data)
- if path.exists():
- contents = path.read_text()
- temp_list_of_characters = json.loads(contents)
- print('File successfully retrieved')
- # for character in temp_list_of_characters:
- # new_character = RPG_Character(**character)
- ## new_character.inventory = convert_dict_to_obj_inv(new_character.inventory)
- # list_of_characters.append(new_character)
- list_of_characters = [RPG_Character(**char) for char in temp_list_of_characters]
- print('Retrieved characters:')
- for character in list_of_characters:
- print(character)
- # print(character.show_inventory())
- else:
- # Adds new characters
- john_data = {'name': 'John', 'gold': 50, 'level': 1}
- new_warrior = RPG_Character(**(warrior_class | john_data))
- list_of_characters.append(new_warrior)
- print('New warrior - John:')
- print(new_warrior)
- new_warrior.add_gold(100)
- print('After adding 100 gold')
- print(new_warrior)
- new_warrior.remove_gold(80)
- print('After removing 80 gold')
- print(new_warrior)
- toby_data = {'name': 'Toby', 'gold': 50, 'level': 1}
- new_rogue = RPG_Character(**(rogue_class | toby_data))
- list_of_characters.append(new_rogue)
- print('New rogue - Toby:')
- print(new_rogue)
- mage_data = {'name': 'Harris', 'gold': 50, 'level': 1}
- new_mage = RPG_Character(**(mage_class | mage_data))
- list_of_characters.append(new_mage)
- print('New mage - Harris:')
- print(new_mage)
- new_mage.increase_level()
- print(f'After increasing level of mage {new_mage.name}')
- print(new_mage)
- print(f'Adding health and mana potions to rogue {new_rogue.name}')
- new_rogue.add_item(basic_health_potion)
- new_rogue.add_item(basic_mana_potion)
- print(f'Adding shield to warrior {new_warrior.name}')
- new_warrior.add_item(wooden_shield)
- # new_rogue.show_inventory() # due to inventory being show in the character
- # new_warrior.show_inventory()
- print('\nFinal state of the characters')
- for ch in list_of_characters:
- print(ch)
- # print(list_of_characters)
- contents = json.dumps([ob.to_dict() for ob in list_of_characters])
- path.write_text(contents)
- print('File saved')
Advertisement
Add Comment
Please, Sign In to add comment