#!/usr/bin/python3 from adventurers import * import base64 import json import random # Player Class Selector class AdventurerGen(): 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) -> Adventurer: # 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) -> list: 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) -> Adventurer: 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 def create_from_dict(character_dict) -> Adventurer: chosen_class = character_dict['player_class'] c_id = character_dict['identifier'] level = character_dict['level'] adv_dict = Adventurer.get_subclass_dict() chosen_class = adv_dict[chosen_class] new_char = chosen_class(c_id=c_id, level=level) for k, v in character_dict.items(): setattr(new_char,k, v) return new_char class PartyGen(): def __init__(self, party_size: int, party_level: int) -> None: self.size = party_size self.level = party_level self.adventurers = [] self.adventurer_types = [] def gen_party(self) -> None: c_id = 1 while len(self.adventurers) < self.size: identifier = "adv-" + str(c_id) new_player = Adventurer(identifier, self.level) attempts = 0 while new_player.player_class not in self.adventurer_types: attempts += 1 selected_class = AdventurerGen(new_player).selection() new_player = selected_class(new_player.identifier, 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): c_id += 1 self.adventurers.append(new_player) self.adventurer_types.append(new_player.player_class) def set_party(self, adventurers: list, count: int, level: int): self.size = count self.level = level self.adventurers = adventurers self.adventurer_types = [] def get_new_party(party_size: int, party_level: int): # keep variables within expected ranges if party_size <= 0 or party_size > 5: party_size = 1 if party_level < 1 or party_level > 5: party_level = 1 # generate an aventuring party per size and level new_party = PartyGen(party_size, party_level) # for adventurers select classes new_party.gen_party() # return the created adventurer party return new_party def get_character(self, identifer: str) -> Adventurer: for adv in self.adventurers: if adv.identifier == identifier: return adv def get_character_sheets(self) -> list: sheet_string = "" character_sheets = [] for c in self.adventurers: character_sheets.append(c.vertical_sheet()) return character_sheets def get_json(self) -> str: party_list = [] for c in self.adventurers: party_list.append(c.get_json()) party_json = json.dumps(party_list) return party_json def __str__(self) -> str: return f"{self.adventurers}" # used for local testing def main(): adv_dict = Adventurer.get_subclass_dict() test_class = adv_dict['cleric'] new_char = test_class(c_id="adv-1",level=2) for line in new_char.vertical_sheet(): print(line) if __name__ == "__main__": main()