diff --git a/.gitignore b/.gitignore index b24d71e..6884755 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,9 @@ Thumbs.db *.mov *.wmv +__pycache__/ +.spyproject/ +.pydevproject + + + diff --git a/.project b/.project new file mode 100644 index 0000000..0c2300d --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + elironwars + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/Hector.json b/Hector.json new file mode 100644 index 0000000..6177436 --- /dev/null +++ b/Hector.json @@ -0,0 +1,9 @@ +{ + "name": "Hector", + "max_pv": 20, + "current_pv": 20, + "strength": 5, + "protection": 3, + "speed": 2, + "mob_type": 0 +} \ No newline at end of file diff --git a/Jamin.json b/Jamin.json new file mode 100644 index 0000000..0e2354c --- /dev/null +++ b/Jamin.json @@ -0,0 +1,9 @@ +{ + "name": "Jamin", + "max_pv": 30, + "current_pv": 30, + "strength": 5, + "protection": 1, + "speed": 2, + "mob_type": 0 +} \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..3cc0d3c --- /dev/null +++ b/app.py @@ -0,0 +1,58 @@ +from character_builder import CharacterBuilder +from level_one import Level +import os + + +def action_menu(): + """ Menu Action du niveau """ + print("\n------ Menu Action ------\n") + print("Pièce Suivante :\t 1") + print("Combat : \t\t\t 2") + print("Fuir : \t\t\t\t 3") + print("Quitter :\t\t\t 4") + return int(input("\nChoix : ")) + + +# Exemple d'utilisation +if __name__ == "__main__": + loaded_character = CharacterBuilder.load_character("Jamin") + if loaded_character: + print(loaded_character) + + level = Level(2, CharacterBuilder.load_character("Jamin")) + player = level.player + rooms = level.rooms + number_room = len(rooms) + print(f"Nombre de pièce dans le donjon : {number_room}") + + while level.exit_level: + os.system('cls' if os.name == 'nt' else 'clear') + match action_menu(): + case 1: + if level.current_room_index >= number_room: + print("fin du donjon !") + break + room = rooms[level.current_room_index] + print(f"Pièce actuelle : {level.current_room_index}") + if room is not None: + for mob in room: + print(f"Un {mob.name} est devant toi !") + match action_menu(): + case 2: + level.combat(mob, player) + if player.current_pv <= 0: + print("!!!!!!!!! Joueur mort !!!!!!!!!!") + break + if mob.current_pv == 0: + print(f"Le {mob.name} est mort !!") + case 3: + print("Tu fuis la pièce") + else: + print("\n ------ Pièce vide ------ \n") + player.current_pv = player.max_pv + level.current_room_index += 1 + case 4: + level.exit_level = False + print(f"Au revoir {player.name} !") + case _: + print("Mauvais choix") diff --git a/base_mob.py b/base_mob.py new file mode 100644 index 0000000..a863a14 --- /dev/null +++ b/base_mob.py @@ -0,0 +1,65 @@ +class BaseMob: + """Classe de base représentant un mob avec différentes caractéristiques.""" + + # Types possibles + FRIEND = 0 + NEUTRAL = 1 + ENEMY = 2 + + def __init__(self, name, max_pv, strength, protection, speed, mob_type): + """ + Initialisation d'un nouveau mob. + + :param name: Nom du mob + :param max_pv: Points de vie maximum + :param strength: Force d'attaque + :param protection: Protection contre les dommages + :param speed: Vitesse d'attaque (nombre d'attaques par tour) + :param mob_type: Type de mob (0 = Ami, 1 = Neutre, 2 = Ennemi) + """ + self.name = name + self.max_pv = max_pv + self.current_pv = max_pv + self.strength = strength + self.protection = protection + self.speed = speed + self.mob_type = mob_type + + def change_type(self, new_type): + """ + Change le type du mob. + + :param new_type: Nouveau type (0 = Ami, 1 = Neutre, 2 = Ennemi) + """ + self.mob_type = new_type + + def change_pv(self, pv_modifier): + """ + Modifie les points de vie actuels du mob. + + :param pv_modifier: Valeur par laquelle modifier les PV (positive pour guérir, négative pour infliger des dégâts) + """ + if pv_modifier > 0: + # Ajout de PV (guérison) + self.current_pv = min(self.max_pv, self.current_pv + pv_modifier) + else: + # Retrait de PV (dommages) + damage = pv_modifier + self.protection + self.current_pv = max(0, self.current_pv + damage) + + def perform_attack(self, target): + """ + Le mob attaque une cible. + + :param target: Le mob cible de l'attaque + """ + for _ in range(self.speed): + if target.current_pv <= 0: + break + target.change_pv(-self.strength) + + def __str__(self): + """Retourne une représentation sous forme de chaîne du mob.""" + return (f"{self.name} - PV: {self.current_pv}/{self.max_pv}, " + f"Force: {self.strength}, Protection: {self.protection}, " + f"Vitesse: {self.speed}") \ No newline at end of file diff --git a/character_builder.py b/character_builder.py new file mode 100644 index 0000000..f8e8dbf --- /dev/null +++ b/character_builder.py @@ -0,0 +1,66 @@ +from base_mob import BaseMob +import json +import os + + +class CharacterBuilder: + @staticmethod + def build_character(): + """Demande à l'utilisateur de saisir les attributs du personnage.""" + print("Création d'un nouveau personnage :") + name = input("Nom du personnage : ") + max_pv = int(input("Points de vie maximum : ")) + strength = int(input("Force : ")) + protection = int(input("Protection : ")) + speed = int(input("Vitesse : ")) + mob_type = 0 + return BaseMob(name, max_pv, strength, protection, speed, mob_type) + + @staticmethod + def save_character(character): + """Enregistre un personnage dans un fichier JSON.""" + character_data = { + "name": character.name, + "max_pv": character.max_pv, + "current_pv": character.current_pv, + "strength": character.strength, + "protection": character.protection, + "speed": character.speed, + "mob_type": character.mob_type + } + filename = character.name + ".json" + with open(filename, "w",encoding='UTF-8') as file: + json.dump(character_data, file, indent=4) + print(f"Personnage enregistré dans {filename}.") + + @staticmethod + def load_character(name): + """Charge un personnage à partir d'un fichier JSON.""" + filename = name + ".json" + if not os.path.exists(filename): + print(f"Erreur : Le fichier {filename} n'existe pas.") + return None + + try: + with open(filename, "r",encoding='UTF-8') as file: + character_data = json.load(file) + + # Vérification des clés essentielles dans le JSON pour éviter les erreurs + required_keys = ["name", "max_pv", "current_pv", + "strength", "protection", "speed", "mob_type"] + if not all(key in character_data for key in required_keys): + print(f"Erreur : Le fichier {filename} ne contient pas toutes les clés nécessaires.") + return None + + # Construction du personnage + return BaseMob( + name=character_data["name"], + max_pv=character_data["max_pv"], + strength=character_data["strength"], + protection=character_data["protection"], + speed=character_data["speed"], + mob_type=character_data["mob_type"] + ) + except json.JSONDecodeError: + print(f"Erreur : Le fichier {filename} n'est pas un JSON valide.") + return None diff --git a/level_one.py b/level_one.py new file mode 100644 index 0000000..d3d12ab --- /dev/null +++ b/level_one.py @@ -0,0 +1,71 @@ +""" Class Level """ +import random +import mobs_utils +from character_builder import CharacterBuilder + + +class Level(): + """ Class Level """ + + def __init__(self, difficulty, player): + """ Chargement du niveau """ + print("Loading Level") + self.mobs_in_level = mobs_utils.generate_random_mob_list( + random.randint(2, difficulty)) + self.exit_level = True + self.player = player + self.rooms = mobs_utils.generate_random_rooms( + self.mobs_in_level, difficulty) # Liste des pièces du niveau + self.current_room_index = 0 # Index de la pièce actuelle + + print("Level Loaded") + + def combat(self, mob, player): + while (mob.current_pv > 0 and player.current_pv > 0): + if mob.speed > player.speed: + mob.perform_attack(player) + player.perform_attack(mob) + else: + player.perform_attack(mob) + mob.perform_attack(player) + print(f"{player.name} - {player.current_pv} PV") + print(f"{mob.name} - {mob.current_pv} PV") + + +def action_menu(): + """ Menu Action du niveau """ + print("Pièce Suivante :\t1") + print("Quitter :\t\t4") + return int(input("Choix : ")) + +# Exemple d'utilisation +if __name__ == "__main__": + level = Level(2, CharacterBuilder.load_character("Jamin")) + player = level.player + rooms = level.rooms + number_room = len(rooms) + print(f"Nombre de pièce dans le donjon : {number_room}") + + while level.exit_level: + match action_menu(): + case 1: + if level.current_room_index >= number_room: + print("fin du donjon !") + break + room = rooms[level.current_room_index] + print(f"Pièce actuelle : {level.current_room_index}") + if room: + for mob in room: + level.combat(mob, player) + if player.current_pv <= 0: + print("!!!!!!!!! Joueur mort !!!!!!!!!!") + break + else: + print("Pièce vide") + player.current_pv = player.max_pv + level.current_room_index += 1 + case 4: + level.exit_level = False + print(f"Au revoir {player.name} !") + case _: + print("Mauvais choix") diff --git a/menu.py b/menu.py new file mode 100644 index 0000000..ab2ce58 --- /dev/null +++ b/menu.py @@ -0,0 +1,26 @@ + +# def main_loop(breaker:bool): +# pass + +# def menu (): +# print("Nouvelle partie :\t1") +# print("Charger :\t\t2") +# print("Option :\t\t3") +# print("Quitter :\t\t4") +# return int(input("Choix : ")) + + +# choix = menu() + +# match choix: +# case 1: +# print("Nouvelle partie") +# case 2: +# print("Charger") +# case 3: +# print("Option") +# case 4: +# print("Quitter") +# case _: +# print("Mauvais choix") + diff --git a/mobs_utils.py b/mobs_utils.py new file mode 100644 index 0000000..76a5044 --- /dev/null +++ b/mobs_utils.py @@ -0,0 +1,49 @@ +import random +from base_mob import BaseMob + +# Créer des instances de BaseMob +yanaar = BaseMob("Yanaar", 15, 2, 1, 3, 2) +ulnarain = BaseMob("Ulnarain", 20, 3, 3, 2, 2) +skroll = BaseMob("Skroll", 25, 5, 3, 1, 2) + +# Liste d'instances de BaseMob (au lieu d'un ensemble pour autoriser des doublons) +mobs_list = [yanaar, skroll, ulnarain] + + +def generate_random_mob_list(max_mobs): + """ + Génère une liste aléatoire de mobs à partir de la liste des instances disponibles. + + :param max_mobs: Le nombre maximum de mobs dans la liste générée. + :return: Une liste de mobs sélectionnés aléatoirement. + """ + if max_mobs <= 0: + return [] + + num_mobs = random.randint(2, max_mobs) + selected_mobs = [random.choice(mobs_list) for _ in range(num_mobs)] + return selected_mobs + + +def generate_random_rooms(mobs_in_level, num_rooms): + """ + Génère un nombre spécifié de pièces et y distribue les mobs disponibles. + + :param mobs_in_level: Liste des mobs disponibles pour le niveau. + :param num_rooms: Nombre total de pièces à générer. + :return: Une liste de pièces, chaque pièce contenant un ou plusieurs mobs, ou étant vide si aucun mob n'est disponible. + """ + rooms = [] + + for _ in range(num_rooms): + if len(mobs_in_level) > 0: + # Si des mobs sont disponibles, ajouter le premier mob à la pièce + new_room = [] + for x in range(random.randint(1, len(mobs_in_level))): + new_room.append(mobs_in_level.pop(0)) + rooms.append(new_room) + else: + # Ajouter une pièce vide si aucun mob n'est disponible + rooms.append(None) + + return rooms \ No newline at end of file