diff --git a/__pycache__/adventurers.cpython-312.pyc b/__pycache__/adventurers.cpython-312.pyc new file mode 100644 index 0000000..b1c4837 Binary files /dev/null and b/__pycache__/adventurers.cpython-312.pyc differ diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc index 84ed64d..f81ae2b 100644 Binary files a/__pycache__/app.cpython-312.pyc and b/__pycache__/app.cpython-312.pyc differ diff --git a/__pycache__/equipment.cpython-312.pyc b/__pycache__/equipment.cpython-312.pyc new file mode 100644 index 0000000..332fc70 Binary files /dev/null and b/__pycache__/equipment.cpython-312.pyc differ diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000..670a9af Binary files /dev/null and b/__pycache__/main.cpython-312.pyc differ diff --git a/__pycache__/ose.cpython-312.pyc b/__pycache__/ose.cpython-312.pyc index bc4aa9a..47b174e 100644 Binary files a/__pycache__/ose.cpython-312.pyc and b/__pycache__/ose.cpython-312.pyc differ diff --git a/adventurers.py b/adventurers.py new file mode 100755 index 0000000..59010bb --- /dev/null +++ b/adventurers.py @@ -0,0 +1,258 @@ +#!/usr/bin/python3 +import random +from equipment import * + +# functions +def roll_dice(count, sides): + return sum(random.randint(1,sides) for _ in range(count)) + +# Player Character Classes +class Adventurer: + def __init__(self, level=1, attributes={}) -> None: + # using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get + self.player_class = None + self.level = level + self.strength = attributes.get('strength', roll_dice(3,6)) + self.intelligence = attributes.get('intelligence', roll_dice(3,6)) + self.wisdom = attributes.get('wisdom', roll_dice(3,6)) + self.dexterity = attributes.get('dexterity', roll_dice(3,6)) + self.constitution = attributes.get('constitution', roll_dice(3,6)) + self.charisma = attributes.get('charisma', roll_dice(3,6)) + self.hp = 1 + self.torches = roll_dice(1,6) + self.rations = roll_dice(1,6) + self.equipment = [ 'backpack', 'tinderbox', 'waterskin' ] + # all armor, individual classes may have overrides + self.possible_armor = list(armor.keys()) + # all weapons, individual classes may have overrides + self.possible_weapons = weapons + self.possible_melee_weapons = list(filter(lambda d: 'melee' in d['traits'], weapons)) + self.possible_missile_weapons = list(filter(lambda d: 'missile' in d['traits'], weapons)) + # each character should get 1 melee and 1 random (missle or melee) + self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] + self.armor = random.choice(self.possible_armor) + + def __str__(self): + return f"{self.player_class}" + + def character_sheet(self): + sheet = [] + sheet.append('{0: <26}'.format(f"| {self.player_class.title()} - Level {self.level}")) + for key, val in self.get_attributes().items(): + key_string = "| " + '{0:12}'.format(f"{key}").capitalize() + f" {val}" + sheet += ['{0: <26}'.format(key_string)] + sheet.append('| ----------------------- ') + sheet.append('{0: <26}'.format(f"| HP: {self.hp} AC: {self.ac}")) + sheet.append('{0: <26}'.format(f"| Torches: {self.torches}")) + sheet.append('{0: <26}'.format(f"| Rations: {self.rations}")) + sheet.append('{0: <26}'.format(f"| Armor: {self.armor}")) + sheet.append('{0: <26}'.format(f"| Weapons:")) + sheet.append('{0: <26}'.format(f"| {self.weapons[0]['name'].title()}")) + sheet.append('{0: <26}'.format(f"| {self.weapons[1]['name'].title()}")) + sheet.append('{0: <26}'.format(f"| Equipment:")) + sheet.append('{0: <26}'.format(f"| ")) + sheet.append('{0: <26}'.format(f"| Gold:")) + sheet.append('| ----------------------- ') + for key, val in self.progression[self.level]['saves'].items(): + key_string = "| " + '{0:12}'.format(f"{key}").capitalize() + f" {val}" + sheet += ['{0: <26}'.format(key_string)] + sheet.append('| ----------------------- ') + # append a | to each string, after the formatted whitespace + sheet = [ line + "|" for line in sheet ] + return sheet + + def get_attributes(self): + attribute_list = ['strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma'] + return {k: self.__dict__[k] for k in attribute_list} + + def get_best_prime_attribute(self): + attribute_list = [ 'strength', 'intelligence', 'wisdom', 'dexterity' ] + prime_attributes = {k: self.__dict__[k] for k in attribute_list} + # return highest, found this at https://stackoverflow.com/a/280156 + return max(prime_attributes, key=prime_attributes.get) + + def roll_equipment(self): + print("testing!") + + +class Fighter(Adventurer): + prime_requisite = "strength" + requirements = None + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 14, "breath" : 15, "spells" : 16 }}, + { "level" : 2, "xp" : 2000, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 14, "breath" : 15, "spells" : 16 }}, + { "level" : 3, "xp" : 4000, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 14, "breath" : 15, "spells" : 16 }}, + { "level" : 4, "xp" : 8000, "hit-dice" : 4, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 12, "breath" : 13, "spells" : 14 }}, + { "level" : 5, "xp" : 16000, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 12, "breath" : 13, "spells" : 14 }}, + { "level" : 6, "xp" : 32000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 12, "breath" : 13, "spells" : 14 }}, + { "level" : 7, "xp" : 64000, "hit-dice" : 7, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 10, "spells" : 12 }}, + { "level" : 8, "xp" : 120000, "hit-dice" : 8, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 10, "spells" : 12 }}, + { "level" : 9, "xp" : 240000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 10, "spells" : 12 }}, + { "level" : 10, "xp" : 360000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 8, "spells" : 10 }}, + { "level" : 11, "xp" : 480000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 8, "spells" : 10 }}, + { "level" : 12, "xp" : 600000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 8, "spells" : 10 }}, + { "level" : 13, "xp" : 720000, "hit-dice" : 9, "thac0" : 10, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 5, "spells" : 8 }}, + { "level" : 14, "xp" : 840000, "hit-dice" : 9, "thac0" : 10, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 5, "spells" : 8 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "fighter" + self.progression = Fighter.progression + self.hp = roll_dice(self.level, 8) + self.ac = armor[self.armor] + +class MagicUser(Adventurer): + prime_requisite = "intelligence" + requirements = None + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 2, "xp" : 2500, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 3, "xp" : 5000, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 4, "xp" : 10000, "hit-dice" : 4, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 5, "xp" : 20000, "hit-dice" : 5, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 6, "xp" : 40000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 11, "breath" : 11, "spells" : 12 }}, + { "level" : 7, "xp" : 80000, "hit-dice" : 7, "thac0" : 17, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 11, "breath" : 11, "spells" : 12 }}, + { "level" : 8, "xp" : 150000, "hit-dice" : 8, "thac0" : 17, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 11, "breath" : 11, "spells" : 12 }}, + { "level" : 9, "xp" : 300000, "hit-dice" : 9, "thac0" : 17, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 11, "breath" : 11, "spells" : 12 }}, + { "level" : 10, "xp" : 450000, "hit-dice" : 9, "thac0" : 17, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 11, "breath" : 11, "spells" : 12 }}, + { "level" : 11, "xp" : 600000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 8, "breath" : 8, "spells" : 8 }}, + { "level" : 12, "xp" : 750000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 8, "breath" : 8, "spells" : 8 }}, + { "level" : 13, "xp" : 900000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 8, "breath" : 8, "spells" : 8 }}, + { "level" : 14, "xp" : 1050000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 8, "breath" : 8, "spells" : 8 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "magic user" + self.progression = MagicUser.progression + self.hp = roll_dice(self.level, 4) + self.armor = "None" + self.ac = armor[self.armor] + self.weapons = [ list(filter(lambda d: 'silver dagger' in d['name'],weapons))[0], { "name" : "" } ] + + +class Cleric(Adventurer): + prime_requisite = "wisdom" + requirements = None + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 14, "breath" : 16, "spells" : 15 }}, + { "level" : 2, "xp" : 1500, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 14, "breath" : 16, "spells" : 15 }}, + { "level" : 3, "xp" : 3000, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 14, "breath" : 16, "spells" : 15 }}, + { "level" : 4, "xp" : 6000, "hit-dice" : 4, "thac0" : 19, "saves" : { "death" : 11, "wands" : 12, "paralysis" : 14, "breath" : 16, "spells" : 15 }}, + { "level" : 5, "xp" : 12000, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 9, "wands" : 10, "paralysis" : 12, "breath" : 14, "spells" : 12 }}, + { "level" : 6, "xp" : 25000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 9, "wands" : 10, "paralysis" : 12, "breath" : 14, "spells" : 12 }}, + { "level" : 7, "xp" : 50000, "hit-dice" : 7, "thac0" : 17, "saves" : { "death" : 9, "wands" : 10, "paralysis" : 12, "breath" : 14, "spells" : 12 }}, + { "level" : 8, "xp" : 100000, "hit-dice" : 8, "thac0" : 17, "saves" : { "death" : 9, "wands" : 10, "paralysis" : 12, "breath" : 14, "spells" : 12 }}, + { "level" : 9, "xp" : 200000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 9, "breath" : 14, "spells" : 9 }}, + { "level" : 10, "xp" : 300000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 9, "breath" : 11, "spells" : 9 }}, + { "level" : 11, "xp" : 400000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 9, "breath" : 11, "spells" : 9 }}, + { "level" : 12, "xp" : 500000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 9, "breath" : 11, "spells" : 9 }}, + { "level" : 13, "xp" : 600000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 3, "wands" : 5, "paralysis" : 7, "breath" : 8, "spells" : 7 }}, + { "level" : 14, "xp" : 700000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 3, "wands" : 5, "paralysis" : 7, "breath" : 8, "spells" : 7 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "cleric" + self.progression = Cleric.progression + self.hp = roll_dice(self.level, 6) + self.armor = random.choice(list(armor.keys())) + self.ac = armor[self.armor] + # clerics can only wield blunt weapons + self.possible_melee_weapons = list(filter(lambda d: 'blunt' in d['traits'] and 'melee' in d['traits'], weapons)) + self.possible_weapons = list(filter(lambda d: 'blunt' in d['traits'], weapons)) + self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] + +class Thief(Adventurer): + prime_requisite = "dexterity" + requirements = None + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 2, "xp" : 1200, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 3, "xp" : 2400, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 4, "xp" : 4800, "hit-dice" : 4, "thac0" : 19, "saves" : { "death" : 13, "wands" : 14, "paralysis" : 13, "breath" : 16, "spells" : 15 }}, + { "level" : 5, "xp" : 9600, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 11, "breath" : 14, "spells" : 13 }}, + { "level" : 6, "xp" : 20000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 11, "breath" : 14, "spells" : 13 }}, + { "level" : 7, "xp" : 40000, "hit-dice" : 7, "thac0" : 17, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 11, "breath" : 14, "spells" : 13 }}, + { "level" : 8, "xp" : 80000, "hit-dice" : 8, "thac0" : 17, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 11, "breath" : 14, "spells" : 13 }}, + { "level" : 9, "xp" : 160000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 9, "breath" : 11, "spells" : 10 }}, + { "level" : 10, "xp" : 280000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 9, "breath" : 11, "spells" : 10 }}, + { "level" : 11, "xp" : 400000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 9, "breath" : 11, "spells" : 10 }}, + { "level" : 12, "xp" : 520000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 9, "breath" : 11, "spells" : 10 }}, + { "level" : 13, "xp" : 640000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 7, "breath" : 10, "spells" : 8 }}, + { "level" : 14, "xp" : 760000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 7, "breath" : 10, "spells" : 8 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "thief" + self.progression = Fighter.progression + self.hp = roll_dice(self.level, 4) + self.armor = random.choice(list(armor.keys())) + self.ac = armor[self.armor] + +class Dwarf(Adventurer): + prime_requisite = "strength" + requirements = {'constitution' : 9 } + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 2, "xp" : 2200, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 3, "xp" : 4400, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 4, "xp" : 8800, "hit-dice" : 4, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 5, "xp" : 17000, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 6, "xp" : 35000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 7, "xp" : 70000, "hit-dice" : 7, "thac0" : 14, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 7, "spells" : 8 }}, + { "level" : 8, "xp" : 140000, "hit-dice" : 8, "thac0" : 14, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 7, "spells" : 8 }}, + { "level" : 9, "xp" : 270000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 7, "spells" : 8 }}, + { "level" : 10, "xp" : 400000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 2, "wands" : 3, "paralysis" : 4, "breath" : 4, "spells" : 6 }}, + { "level" : 11, "xp" : 530000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 2, "wands" : 3, "paralysis" : 4, "breath" : 4, "spells" : 6 }}, + { "level" : 12, "xp" : 660000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 2, "wands" : 3, "paralysis" : 4, "breath" : 4, "spells" : 6 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "dwarf" + self.progression = Dwarf.progression + self.hp = roll_dice(self.level, 8) + self.armor = random.choice(list(armor.keys())) + self.ac = armor[self.armor] + +class Elf(Adventurer): + prime_requisite = "intellgence" + requirements = {'intelligence' : 9 } + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 13, "breath" : 15, "spells" : 15 }}, + { "level" : 2, "xp" : 4000, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 13, "breath" : 15, "spells" : 15 }}, + { "level" : 3, "xp" : 8000, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 12, "wands" : 13, "paralysis" : 13, "breath" : 15, "spells" : 15 }}, + { "level" : 4, "xp" : 16000, "hit-dice" : 4, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 11, "breath" : 13, "spells" : 12 }}, + { "level" : 5, "xp" : 32000, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 11, "breath" : 13, "spells" : 12 }}, + { "level" : 6, "xp" : 64000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 10, "wands" : 11, "paralysis" : 11, "breath" : 13, "spells" : 12 }}, + { "level" : 7, "xp" : 120000, "hit-dice" : 7, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 9, "breath" : 10, "spells" : 10 }}, + { "level" : 8, "xp" : 250000, "hit-dice" : 8, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 9, "breath" : 10, "spells" : 10 }}, + { "level" : 9, "xp" : 400000, "hit-dice" : 9, "thac0" : 14, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 9, "breath" : 10, "spells" : 10 }}, + { "level" : 10, "xp" : 600000, "hit-dice" : 9, "thac0" : 12, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 8, "spells" : 8 }} + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "elf" + self.progression = Elf.progression + self.hp = roll_dice(self.level, 6) + self.armor = random.choice(list(armor.keys())) + self.ac = armor[self.armor] + +class Halfling(Adventurer): + prime_requisite = "dexterity" + requirements = {'constitution' : 9, 'dexterity' : 9 } + progression = [ + { "level" : 1, "xp" : 0, "hit-dice" : 1, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 2, "xp" : 2000, "hit-dice" : 2, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 3, "xp" : 4000, "hit-dice" : 3, "thac0" : 19, "saves" : { "death" : 8, "wands" : 9, "paralysis" : 10, "breath" : 13, "spells" : 12 }}, + { "level" : 4, "xp" : 8000, "hit-dice" : 4, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 5, "xp" : 16000, "hit-dice" : 5, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 6, "xp" : 32000, "hit-dice" : 6, "thac0" : 17, "saves" : { "death" : 6, "wands" : 7, "paralysis" : 8, "breath" : 10, "spells" : 10 }}, + { "level" : 7, "xp" : 64000, "hit-dice" : 7, "thac0" : 14, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 7, "spells" : 8 }}, + { "level" : 8, "xp" : 120000, "hit-dice" : 8, "thac0" : 14, "saves" : { "death" : 4, "wands" : 5, "paralysis" : 6, "breath" : 7, "spells" : 8 }}, + ] + def __init__(self, level, attributes={}) -> None: + Adventurer.__init__(self, level, attributes) + self.player_class = "halfling" + self.progression = Halfling.progression + self.hp = roll_dice(self.level, 6) + self.armor = random.choice(list(armor.keys())) + self.ac = armor[self.armor] diff --git a/app.py b/app.py index 26f379e..de65d7f 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,11 @@ #!/usr/bin/python3 -from ose import * +from main import * from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): - htmlBody = returnSheets('test') - return render_template("sheet.html", htmlBody=htmlBody) + sheets = returnSheets('test') + return render_template("sheet.html", sheets=sheets) diff --git a/equipment.py b/equipment.py new file mode 100755 index 0000000..f163945 --- /dev/null +++ b/equipment.py @@ -0,0 +1,21 @@ +#!/usr/bin/python3 + +armor= { 'None' : 9, 'Leather' : 7, 'Leather, Shield' : 6, 'Chain' : 5, 'Chain, Shield' : 4, 'Plate' : 3, 'Plate, Shield' : 2 } + +weapons = [ + { 'name' : 'battle axe', 'damage-dice' : 8, 'traits' : [ 'melee', 'slow', 'two-handed' ] }, + { 'name' : 'club', 'damage-dice' : 4, 'traits' : [ 'melee', 'blunt' ] }, + { 'name' : 'crossbow', 'damage-dice' : 6, 'traits' : [ 'missile', 'reload','slow','two-handed'], 'ammo' : '20 bolts'}, + { 'name' : 'hand axe', 'damage-dice' : 6, 'traits' : [ 'melee', 'missile'] }, + { 'name' : 'mace', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] }, + { 'name' : 'pole arm', 'damage-dice' : 10, 'traits' : [ 'melee', 'brace', 'slow', 'two-handed' ] }, + { 'name' : 'short bow', 'damage-dice' : 6, 'traits' : [ 'missile', 'two-handed' ], 'ammo' : '20 arrows'}, + { 'name' : 'short sword', 'damage-dice' : 6, 'traits' : [ 'melee' ] }, + { 'name' : 'silver dagger','damage-dice' : 4, 'traits' : [ 'melee', 'missile' ] }, + { 'name' : 'sling', 'damage-dice' : 4, 'traits' : [ 'missile', 'blunt' ], 'ammo' : '20 stones'}, + { 'name' : 'staff', 'damage-dice' : 4, 'traits' : [ 'melee', 'blunt', 'slow', 'two-handed' ] }, + { 'name' : 'spear', 'damage-dice' : 6, 'traits' : [ 'melee', 'missile', 'brace' ] }, + { 'name' : 'sword', 'damage-dice' : 8, 'traits' : [ 'melee' ] }, + { 'name' : 'war hammer', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] } +] + diff --git a/main.py b/main.py index 36c1f85..7733e84 100755 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ #!/usr/bin/python3 +from adventurers import * import random armor= { 'None' : 9, 'Leather' : 7, 'Leather, Shield' : 6, 'Chain' : 5, 'Chain, Shield' : 4, 'Plate' : 3, 'Plate, Shield' : 2 } @@ -19,140 +20,6 @@ weapons = [ { 'name' : 'war hammer', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] } ] -# Player Character Classes -class Adventurer: - def __init__(self, level=1, attributes={}) -> None: - # using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get - self.player_class = None - self.level = level - self.strength = attributes.get('strength', roll_dice(3,6)) - self.intelligence = attributes.get('intelligence', roll_dice(3,6)) - self.wisdom = attributes.get('wisdom', roll_dice(3,6)) - self.dexterity = attributes.get('dexterity', roll_dice(3,6)) - self.constitution = attributes.get('constitution', roll_dice(3,6)) - self.charisma = attributes.get('charisma', roll_dice(3,6)) - self.hp = 1 - self.torches = roll_dice(1,6) - self.rations = roll_dice(1,6) - self.equipment = [ 'backpack', 'tinderbox', 'waterskin' ] - # all armor, individual classes may have overrides - self.possible_armor = list(armor.keys()) - # all weapons, individual classes may have overrides - self.possible_weapons = weapons - self.possible_melee_weapons = list(filter(lambda d: 'melee' in d['traits'], weapons)) - self.possible_missile_weapons = list(filter(lambda d: 'missile' in d['traits'], weapons)) - # each character should get 1 melee and 1 random (missle or melee) - self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] - self.armor = random.choice(self.possible_armor) - - def __str__(self): - return f"{self.player_class}" - - def character_sheet(self): - sheet = [] - sheet.append('{0: <26}'.format(f"| {self.player_class.title()} - Level {self.level}")) - for key, val in self.get_attributes().items(): - key_string = "| " + '{0:12}'.format(f"{key}").capitalize() + f" {val}" - sheet += ['{0: <26}'.format(key_string)] - sheet.append('| ----------------------- ') - sheet.append('{0: <26}'.format(f"| HP: {self.hp} AC: {self.ac}")) - sheet.append('{0: <26}'.format(f"| Torches: {self.torches}")) - sheet.append('{0: <26}'.format(f"| Rations: {self.rations}")) - sheet.append('{0: <26}'.format(f"| Armor: {self.armor}")) - sheet.append('{0: <26}'.format(f"| Weapons:")) - sheet.append('{0: <26}'.format(f"| {self.weapons[0]['name'].title()}")) - sheet.append('{0: <26}'.format(f"| {self.weapons[1]['name'].title()}")) - return sheet - - def get_attributes(self): - attribute_list = ['strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma'] - return {k: self.__dict__[k] for k in attribute_list} - - def get_best_prime_attribute(self): - attribute_list = [ 'strength', 'intelligence', 'wisdom', 'dexterity' ] - prime_attributes = {k: self.__dict__[k] for k in attribute_list} - # return highest, found this at https://stackoverflow.com/a/280156 - return max(prime_attributes, key=prime_attributes.get) - - def roll_equipment(self): - print("testing!") - - -class Fighter(Adventurer): - prime_requisite = "strength" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "fighter" - self.hp = roll_dice(self.level, 8) - self.ac = armor[self.armor] - -class MagicUser(Adventurer): - prime_requisite = "intelligence" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "magic user" - self.hp = roll_dice(self.level, 4) - self.armor = "None" - self.ac = armor[self.armor] - self.weapons = [ list(filter(lambda d: 'silver dagger' in d['name'],weapons))[0], { "name" : "" } ] - - -class Cleric(Adventurer): - prime_requisite = "wisdom" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "cleric" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - # clerics can only wield blunt weapons - self.possible_melee_weapons = list(filter(lambda d: 'blunt' in d['traits'] and 'melee' in d['traits'], weapons)) - self.possible_weapons = list(filter(lambda d: 'blunt' in d['traits'], weapons)) - self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] - -class Thief(Adventurer): - prime_requisite = "dexterity" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "thief" - self.hp = roll_dice(self.level, 4) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Dwarf(Adventurer): - prime_requisite = "strength" - requirements = {'constitution' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "dwarf" - self.hp = roll_dice(self.level, 8) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Elf(Adventurer): - prime_requisite = "intellgence" - requirements = {'intelligence' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "elf" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Halfling(Adventurer): - prime_requisite = "dexterity" - requirements = {'constitution' : 9, 'dexterity' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "halfling" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - # Player Class Selector class ClassSelector(): def __init__(self, player: Adventurer) -> None: @@ -210,11 +77,16 @@ class PartyGenerator(): self.adventurer_types.append(new_player.player_class) def get_character_sheets(self): + sheet_string = "" + character_sheets = [] + for c in self.adventurers: + character_sheets.append(c.character_sheet()) for i in range(15): for j in range(len(self.adventurers)): adv = self.adventurers[j] - print(adv.character_sheet()[i],end='') - print('|\n',end='') + sheet_string += adv.character_sheet()[i] + sheet_string += '|\n' + return character_sheets def __str__(self): return f"{self.adventurers}" @@ -223,9 +95,17 @@ class PartyGenerator(): def roll_dice(count, sides): return sum(random.randint(1,sides) for _ in range(count)) -def main(): +def returnSheets(foo): new_party = PartyGenerator() new_party.gen_party() - new_party.get_character_sheets() + return new_party.get_character_sheets() -main() +def main(): + character_sheets = returnSheets('foo') + for c in character_sheets: + for l in c: + print(f"{l}|") + print() + +if __name__ == "__main__": + main() diff --git a/ose.py b/ose.py deleted file mode 100755 index d767a88..0000000 --- a/ose.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/python3 -import random - -armor= { 'None' : 9, 'Leather' : 7, 'Leather, Shield' : 6, 'Chain' : 5, 'Chain, Shield' : 4, 'Plate' : 3, 'Plate, Shield' : 2 } -weapons = [ - { 'name' : 'battle axe', 'damage-dice' : 8, 'traits' : [ 'melee', 'slow', 'two-handed' ] }, - { 'name' : 'club', 'damage-dice' : 4, 'traits' : [ 'melee', 'blunt' ] }, - { 'name' : 'crossbow', 'damage-dice' : 6, 'traits' : [ 'missile', 'reload','slow','two-handed'], 'ammo' : '20 bolts'}, - { 'name' : 'hand axe', 'damage-dice' : 6, 'traits' : [ 'melee', 'missile'] }, - { 'name' : 'mace', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] }, - { 'name' : 'pole arm', 'damage-dice' : 10, 'traits' : [ 'melee', 'brace', 'slow', 'two-handed' ] }, - { 'name' : 'short bow', 'damage-dice' : 6, 'traits' : [ 'missile', 'two-handed' ], 'ammo' : '20 arrows'}, - { 'name' : 'short sword', 'damage-dice' : 6, 'traits' : [ 'melee' ] }, - { 'name' : 'silver dagger','damage-dice' : 4, 'traits' : [ 'melee', 'missile' ] }, - { 'name' : 'sling', 'damage-dice' : 4, 'traits' : [ 'missile', 'blunt' ], 'ammo' : '20 stones'}, - { 'name' : 'staff', 'damage-dice' : 4, 'traits' : [ 'melee', 'blunt', 'slow', 'two-handed' ] }, - { 'name' : 'spear', 'damage-dice' : 6, 'traits' : [ 'melee', 'missile', 'brace' ] }, - { 'name' : 'sword', 'damage-dice' : 8, 'traits' : [ 'melee' ] }, - { 'name' : 'war hammer', 'damage-dice' : 6, 'traits' : [ 'melee', 'blunt' ] } -] - -# Player Character Classes -class Adventurer: - def __init__(self, level=1, attributes={}) -> None: - # using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get - self.player_class = None - self.level = level - self.strength = attributes.get('strength', roll_dice(3,6)) - self.intelligence = attributes.get('intelligence', roll_dice(3,6)) - self.wisdom = attributes.get('wisdom', roll_dice(3,6)) - self.dexterity = attributes.get('dexterity', roll_dice(3,6)) - self.constitution = attributes.get('constitution', roll_dice(3,6)) - self.charisma = attributes.get('charisma', roll_dice(3,6)) - self.hp = 1 - self.torches = roll_dice(1,6) - self.rations = roll_dice(1,6) - self.equipment = [ 'backpack', 'tinderbox', 'waterskin' ] - # all armor, individual classes may have overrides - self.possible_armor = list(armor.keys()) - # all weapons, individual classes may have overrides - self.possible_weapons = weapons - self.possible_melee_weapons = list(filter(lambda d: 'melee' in d['traits'], weapons)) - self.possible_missile_weapons = list(filter(lambda d: 'missile' in d['traits'], weapons)) - # each character should get 1 melee and 1 random (missle or melee) - self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] - self.armor = random.choice(self.possible_armor) - - def __str__(self): - return f"{self.player_class}" - - def character_sheet(self): - sheet = [] - sheet.append('{0: <26}'.format(f"| {self.player_class.title()} - Level {self.level}")) - for key, val in self.get_attributes().items(): - key_string = "| " + '{0:12}'.format(f"{key}").capitalize() + f" {val}" - sheet += ['{0: <26}'.format(key_string)] - sheet.append('| ----------------------- ') - sheet.append('{0: <26}'.format(f"| HP: {self.hp} AC: {self.ac}")) - sheet.append('{0: <26}'.format(f"| Torches: {self.torches}")) - sheet.append('{0: <26}'.format(f"| Rations: {self.rations}")) - sheet.append('{0: <26}'.format(f"| Armor: {self.armor}")) - sheet.append('{0: <26}'.format(f"| Weapons:")) - sheet.append('{0: <26}'.format(f"| {self.weapons[0]['name'].title()}")) - sheet.append('{0: <26}'.format(f"| {self.weapons[1]['name'].title()}")) - return sheet - - def get_attributes(self): - attribute_list = ['strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma'] - return {k: self.__dict__[k] for k in attribute_list} - - def get_best_prime_attribute(self): - attribute_list = [ 'strength', 'intelligence', 'wisdom', 'dexterity' ] - prime_attributes = {k: self.__dict__[k] for k in attribute_list} - # return highest, found this at https://stackoverflow.com/a/280156 - return max(prime_attributes, key=prime_attributes.get) - - def roll_equipment(self): - print("testing!") - - -class Fighter(Adventurer): - prime_requisite = "strength" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "fighter" - self.hp = roll_dice(self.level, 8) - self.ac = armor[self.armor] - -class MagicUser(Adventurer): - prime_requisite = "intelligence" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "magic user" - self.hp = roll_dice(self.level, 4) - self.armor = "None" - self.ac = armor[self.armor] - self.weapons = [ list(filter(lambda d: 'silver dagger' in d['name'],weapons))[0], { "name" : "" } ] - - -class Cleric(Adventurer): - prime_requisite = "wisdom" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "cleric" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - # clerics can only wield blunt weapons - self.possible_melee_weapons = list(filter(lambda d: 'blunt' in d['traits'] and 'melee' in d['traits'], weapons)) - self.possible_weapons = list(filter(lambda d: 'blunt' in d['traits'], weapons)) - self.weapons = [ random.choice(self.possible_melee_weapons), random.choice(self.possible_weapons) ] - -class Thief(Adventurer): - prime_requisite = "dexterity" - requirements = None - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "thief" - self.hp = roll_dice(self.level, 4) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Dwarf(Adventurer): - prime_requisite = "strength" - requirements = {'constitution' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "dwarf" - self.hp = roll_dice(self.level, 8) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Elf(Adventurer): - prime_requisite = "intellgence" - requirements = {'intelligence' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "elf" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -class Halfling(Adventurer): - prime_requisite = "dexterity" - requirements = {'constitution' : 9, 'dexterity' : 9 } - def __init__(self, level, attributes={}) -> None: - Adventurer.__init__(self, level, attributes) - self.player_class = "halfling" - self.hp = roll_dice(self.level, 6) - self.armor = random.choice(list(armor.keys())) - self.ac = armor[self.armor] - -# Player Class Selector -class ClassSelector(): - def __init__(self, player: Adventurer) -> None: - self.player = player - # https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name - # pull classes that do not have requirements - self.available_classes = [cls for cls in Adventurer.__subclasses__() if not cls.requirements] - # pull classes that do have requirements - self.classes_with_reqs = [cls for cls in Adventurer.__subclasses__() if cls.requirements] - # run function to randomly select an adventurer class - self.selected_class = self.selection() - - def return_class_by_best_attribute(self): - # for adventurer classes in available classes, return the one where that classes' prime requisite is equal to the players best attribute - return [adv_class for adv_class in self.available_classes if adv_class.prime_requisite == self.player.get_best_prime_attribute()][0] - - def return_classes_with_requirements(self): - p_attrs = self.player.get_attributes() - possible_classes = [] - for c in self.classes_with_reqs: - match_count = 0 - for r in c.requirements: - if p_attrs[r] >= c.requirements[r]: - match_count += 1 - if match_count >= len(c.requirements): - possible_classes.append(c) - return possible_classes - - def selection(self): - best_prime_attribute = self.player.get_best_prime_attribute() - # create an array of possible player classes, add the best choice per player's best core attributes - possible_classes = [ self.return_class_by_best_attribute() ] - possible_classes += self.return_classes_with_requirements() - # randomly select class - selected_class = random.choice(possible_classes) - return selected_class - -class PartyGenerator(): - def __init__(self, party_size=4) -> None: - self.size = party_size - self.adventurers = [] - self.adventurer_types = [] - - def gen_party(self): - while len(self.adventurers) < self.size: - new_player = Adventurer() - attempts = 0 - while new_player.player_class not in self.adventurer_types: - attempts += 1 - selected_class = ClassSelector(new_player).selection() - new_player = selected_class(new_player.level, new_player.get_attributes()) - # i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off - if (new_player.player_class not in self.adventurer_types) or (attempts > 10): - self.adventurers.append(new_player) - self.adventurer_types.append(new_player.player_class) - - def get_character_sheets(self): - sheet_string = "" - for i in range(15): - for j in range(len(self.adventurers)): - adv = self.adventurers[j] - sheet_string += adv.character_sheet()[i] - sheet_string += '|\n' - return sheet_string - - def __str__(self): - return f"{self.adventurers}" - -# functions -def roll_dice(count, sides): - return sum(random.randint(1,sides) for _ in range(count)) - -def returnSheets(foo): - print('foo') - new_party = PartyGenerator() - new_party.gen_party() - return new_party.get_character_sheets() - -def main(): - sheet_string = returnSheets(foo) - -if __name__ == "__main__": - main() diff --git a/templates/sheet.html b/templates/sheet.html index 588a46e..8d9c8ab 100644 --- a/templates/sheet.html +++ b/templates/sheet.html @@ -1,10 +1,8 @@ - - - FlaskTest + D&D Characters -
-
-

-

{{htmlBody}}
-

-
+
+ {%for character in sheets%} +
+

+

{{character | join("\n")}}
+

+
+ {%endfor%}