From f4d8511ab6a221cd9b1a5c4bb37d931b92fbc554 Mon Sep 17 00:00:00 2001 From: Zachary Watts Date: Sun, 26 Apr 2026 01:31:43 -0400 Subject: [PATCH] template improved, using multiple .py files now --- __pycache__/adventurers.cpython-312.pyc | Bin 0 -> 20362 bytes __pycache__/app.cpython-312.pyc | Bin 557 -> 565 bytes __pycache__/equipment.cpython-312.pyc | Bin 0 -> 1102 bytes __pycache__/main.cpython-312.pyc | Bin 0 -> 6963 bytes __pycache__/ose.cpython-312.pyc | Bin 17314 -> 17574 bytes adventurers.py | 258 ++++++++++++++++++++++++ app.py | 6 +- equipment.py | 21 ++ main.py | 158 ++------------- ose.py | 238 ---------------------- templates/sheet.html | 18 +- 11 files changed, 310 insertions(+), 389 deletions(-) create mode 100644 __pycache__/adventurers.cpython-312.pyc create mode 100644 __pycache__/equipment.cpython-312.pyc create mode 100644 __pycache__/main.cpython-312.pyc create mode 100755 adventurers.py create mode 100755 equipment.py delete mode 100755 ose.py diff --git a/__pycache__/adventurers.cpython-312.pyc b/__pycache__/adventurers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1c48379f58f9fc42002fea0ca6cb2e188bb1060 GIT binary patch literal 20362 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 delta 115 zcmdnWvX+JSG%qg~0}x!F`6~0_MqV~XPL7O{+#IL;l*-9cjEda)`WgATsrprk$=Q?r z8Eut$C1iLDdwT^#6urM$lPp68zDdC&P;t5pqrjxGQ42Bu;BP|fI> z$``-C1{9zOB_LqJ7+BlZssUxFI0jTd6<~b31V<37!Gu%Poef3ACJ~#0>1_ft zc)A9&IXb7i5%(y}BllRYvw+wv97pB}eR5H8ouS7`?J-h0h25-nJgu2^AgFUD*Ey>b zoXflOQ2DEJ;jp_iv08Y!)L0%=aL|FJ%9tv6A;y5HQc|UerD0{{HV;{5-C{IynTYLt zaj|~i^_UNtdEKR67}xac-|iisMl7!B*JwAcwrLdktWICBL0QR{GBaR4V;PY??;TX5 z9$#^32n-M+Ar08UIM9GPYz4dy%f=!>y+~%H<8QUa1WIIP+usVKtlSY?$~NycNM;3| zl%9`t!F*0Z*hmzUSmN@P%k?(*BiSHAeQ+_Y$_$o_&>-M(S=p8)NgOwM^*XiQzB3V+T>QNG zt+kdC+PCLEZ|+)q^GWMoN*?s>1%Hz`;_)TnFlF()VGgn@>Oh;we^&2=$(-gg5O$CQ?fSXjU-NJ Ri9F{1NqfBb-V*0=*gpfCSFZp7 literal 0 HcmV?d00001 diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..670a9af1a12771eb1575c2a65a0edd7d8e64a205 GIT binary patch literal 6963 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 literal 0 HcmV?d00001 diff --git a/__pycache__/ose.cpython-312.pyc b/__pycache__/ose.cpython-312.pyc index bc4aa9a614edf0cc606b650ae79faa9fd276296e..47b174ee45de35bff26beef7fdf4d62aa653fb15 100644 GIT binary patch delta 819 zcmYLGO-xfk5Z-xjTV9*jLa|tCB|I!BB_=4bSVAdOlmiFkCmJtAnzlkwAl)`5lGoUS z#+pDl4W_78;Ds?K@dBA}Q<5wa>4in4S-daoGU>mH*XVyPX*ysC zpHm%tso4PrOn+R}4NfFdMjdqHQSx4$io_|Lhc3G&U;rU+V4=~$D0_vzr-;Y>_S%y0P>6-X$tb&-7>Y)d2{t2y5X-}GUJga> zCd5}XjX(2u1_YHRIfpZ&=3EuaN_oy!wr;Chu~iian3^)doO*Iyb+4%I>EL>`cct39 zR(f4c#-QwH+7}b`QO8!J`=1*Ii;45Ej>3{`(EYM^y8?-;=^F4t&fNxxHZHEth zq16dnJm1>DXB$nf>sWk>BoDhu$SlUfQlRs=wMV)Yw$sH+82`YPs6j{*{=Lo17u_c4xdRfL;lDQc_0kzUk6) z9Po>OBgWyEQZnJBDOE1v3TLj!LMS8DEv1U#Rl1V@D?R J1Z%|le*poa&9?vm delta 619 zcmZ41$+)PUk?%AwFBbz4+?f3;vr~H`-$M>=ef^C5+*JLl#N_PF%$zMoMn{11(-~42 zYZ*%zL25xDg=saE?ZOc2&%jX2gpey?p6p{FH+g{($K*9C99%#J>Ocj|H4Kvj#YA{& zm?eSwYguX-Ygi^v8V9a zfNG02f`|klp~+h01Eg;86lbKSmc$pA6lLb6-(t+X#h7)AIWeWIm=!2HS>D!*rxeI& zV7MVJ*}-#X@^afu7MTki(vxTLSWou1vt+zGxzo;#asT8Cc9yK{tTLa4HuKqQF)}`y zZ0X?4cx-a5gCyg_$$$K3oB^Vh>Ks+#54W(-tfo^`tA~KnukAsB~ z)?EK{S sPD+dyHw!r@GfK%as(xeu5}zCx85!+9v9U1feBxnbRQ 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%}