#!/usr/bin/python3 import random # Player Character Classes class Adventurer: def __init__(self, attributes={}) -> None: # using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get 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.player_class = None class Fighter(Adventurer): prime_requisite = "strength" def __init__(self, attributes: dict) -> None: PlayerCharacter.__init__(self, attributes) self.player_class = "fighter" self.hp = roll_dice(1, 8) class MagicUser(Adventurer): prime_requisite = "intelligence" def __init__(self, attributes: dict) -> None: PlayerCharacter.__init__(self, name, attributes) self.player_class = "magic-user" self.hp = roll_dice(1, 4) class Cleric(Adventurer): prime_requisite = "wisdom" def __init__(self, attributes: dict) -> None: PlayerCharacter.__init__(self, name, attributes) self.player_class = "cleric" self.hp = roll_dice(1, 6) class Thief(Adventurer): prime_requisite = "dexterity" def __init__(self, attributes: dict) -> None: PlayerCharacter.__init__(self, name, attributes) self.player_class = "thief" self.hp = roll_dice(1, 6) # Player Class Selector class ClassSelector(): def __init__(self, player: Adventurer) -> None: self.player = player self.prime_requisites = { "strength" : "Fighter", "intelligence" : "Magic User", "wisdom" : "Cleric", "dexterity" : "Thief" } self.selected_class = self.selection() def get_best_prime_attribute(self): attributes = self.player.__dict__.copy() del attributes['player_class'] # we should not evaluate these two stats del attributes['constitution'] del attributes['charisma'] # of those remaining, return highest, found this at https://stackoverflow.com/a/280156 return max(attributes, key=attributes.get) def selection(self): best_prime_attribute = self.get_best_prime_attribute() # create an array of possible player classes, add the best choice per player's best core attributes class_to_add = self.prime_requisites[best_prime_attribute] possible_classes = [class_to_add] # check if player qualifies for other classes if self.player.constitution >= 9 : possible_classes.append("Dwarf") if self.player.intelligence >= 9 : possible_classes.append("Elf") if self.player.constitution >= 9 and self.player.dexterity >= 9 : possible_classes.append("Halfling") # randomly select class selected_class = random.choice(possible_classes) return f"{selected_class}" class PartyGenerator(): def __init__(self, party_size=4) -> None: self.size = party_size self.adventurers = [] def gen_party(self): while len(self.adventurers) < self.size: new_player = Adventurer() attempts = 0 while new_player.player_class not in self.adventurers: attempts += 1 my_adv = ClassSelector(new_player).selected_class new_player.player_class = my_adv if new_player.player_class not in self.adventurers: self.adventurers.append(new_player.player_class) # i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off elif attempts > 10: self.adventurers.append(new_player.player_class) def __str__(self): return f"{self.adventurers}" # functions def roll_dice(count, sides): return sum(random.randint(1,sides) for _ in range(count)) def main(): new_party = PartyGenerator() new_party.gen_party() print(new_party) main()