Files
TermNSI/POO/TP/Corrige_TP_Pokemon.py

359 lines
11 KiB
Python

"""
Corrigé du TP Pokémon Arena — Programmation Orientée Objet
"""
# =============================================================================
# Dictionnaire des faiblesses (Bonus Exercice 3)
# =============================================================================
FAIBLESSES = {
"Eau": ["Feu"],
"Feu": ["Plante"],
"Plante": ["Eau"],
"Electrik": ["Eau"],
"Roche": ["Eau", "Plante"]
}
# =============================================================================
# PARTIE 1 : Classe Pokemon
# =============================================================================
class Pokemon:
def __init__(self, nom, type_pokemon, niveau=1, pv_max=100, attaque=10):
"""
Constructeur de la classe Pokemon.
:param nom: (str) Nom du Pokémon
:param type_pokemon: (str) Type élémentaire
:param niveau: (int) Niveau du Pokémon
:param pv_max: (int) Points de vie maximum
:param attaque: (int) Puissance d'attaque
"""
self.nom = nom
self.type_pokemon = type_pokemon
self.niveau = niveau
self.pv_max = pv_max
self.pv = pv_max
self.attaque = attaque
def __repr__(self):
"""Représentation textuelle du Pokémon."""
return f"{self.nom} ({self.type_pokemon}) - Nv.{self.niveau} - {self.pv}/{self.pv_max} PV"
def est_ko(self):
"""
Vérifie si le Pokémon est KO.
:return: (bool) True si PV <= 0, False sinon
"""
return self.pv <= 0
def subir_degats(self, degats):
"""
Inflige des dégâts au Pokémon.
Les PV ne peuvent pas descendre en dessous de 0.
:param degats: (int) Nombre de dégâts subis
"""
self.pv = max(0, self.pv - degats)
def attaquer(self, cible):
"""
Attaque un autre Pokémon avec prise en compte des faiblesses.
:param cible: (Pokemon) Pokémon ciblé par l'attaque
"""
degats = self.attaque
# Vérifier si le type de la cible est faible contre notre type
if self.type_pokemon in FAIBLESSES:
if cible.type_pokemon in FAIBLESSES[self.type_pokemon]:
degats *= 2
print(f"C'est super efficace !")
print(f"{self.nom} attaque {cible.nom} et inflige {degats} dégâts !")
cible.subir_degats(degats)
def soigner(self, soin):
"""
Soigne le Pokémon.
Les PV ne peuvent pas dépasser pv_max.
:param soin: (int) Nombre de PV récupérés
"""
self.pv = min(self.pv_max, self.pv + soin)
# =============================================================================
# PARTIE 2 : Classe Dresseur
# =============================================================================
class Dresseur:
def __init__(self, nom):
"""
Constructeur de la classe Dresseur.
:param nom: (str) Nom du dresseur
"""
self.nom = nom
self.equipe = []
def ajouter_pokemon(self, pokemon):
"""
Ajoute un Pokémon à l'équipe si possible (max 6).
:param pokemon: (Pokemon) Pokémon à ajouter
:return: (bool) True si ajouté, False sinon
"""
if len(self.equipe) < 6:
self.equipe.append(pokemon)
return True
else:
print("L'équipe est complète (6 Pokémon maximum) !")
return False
def pokemon_disponibles(self):
"""
Renvoie la liste des Pokémon non KO.
:return: (list) Liste des Pokémon encore en état de combattre
"""
disponibles = []
for pokemon in self.equipe:
if not pokemon.est_ko():
disponibles.append(pokemon)
return disponibles
def premier_pokemon_dispo(self):
"""
Renvoie le premier Pokémon non KO.
:return: (Pokemon/None) Premier Pokémon dispo ou None
"""
for pokemon in self.equipe:
if not pokemon.est_ko():
return pokemon
return None
def tous_ko(self):
"""
Vérifie si tous les Pokémon sont KO.
:return: (bool) True si tous KO, False sinon
"""
for pokemon in self.equipe:
if not pokemon.est_ko():
return False
return True
def __repr__(self):
"""Représentation du dresseur."""
result = f"Dresseur {self.nom} - {len(self.equipe)} Pokémon"
for pokemon in self.equipe:
result += f"\n - {pokemon}"
return result
# =============================================================================
# PARTIE 3 : Classe Combat
# =============================================================================
class Combat:
def __init__(self, dresseur1, dresseur2):
"""
Constructeur de la classe Combat.
:param dresseur1: (Dresseur) Premier dresseur
:param dresseur2: (Dresseur) Second dresseur
"""
self.dresseur1 = dresseur1
self.dresseur2 = dresseur2
self.tour = 0
def afficher_etat(self):
"""Affiche l'état actuel du combat."""
print(f"\n{'='*40}")
print(f"Tour {self.tour}")
print(f"{'='*40}")
poke1 = self.dresseur1.premier_pokemon_dispo()
poke2 = self.dresseur2.premier_pokemon_dispo()
if poke1:
print(f"{self.dresseur1.nom}: {poke1.nom} ({poke1.pv}/{poke1.pv_max} PV)")
if poke2:
print(f"{self.dresseur2.nom}: {poke2.nom} ({poke2.pv}/{poke2.pv_max} PV)")
print()
def lancer_combat(self):
"""
Lance le combat tour par tour.
Chaque tour, les deux Pokémon actifs s'attaquent.
Quand un Pokémon est KO, le suivant prend sa place.
Le combat s'arrête quand un dresseur n'a plus de Pokémon.
"""
print(f"\n*** COMBAT : {self.dresseur1.nom} VS {self.dresseur2.nom} ***")
while not self.dresseur1.tous_ko() and not self.dresseur2.tous_ko():
self.tour += 1
self.afficher_etat()
# Récupérer les Pokémon actifs
poke1 = self.dresseur1.premier_pokemon_dispo()
poke2 = self.dresseur2.premier_pokemon_dispo()
# Le Pokémon 1 attaque
poke1.attaquer(poke2)
# Vérifier si Pokémon 2 est KO
if poke2.est_ko():
print(f"\n{poke2.nom} est KO !")
nouveau = self.dresseur2.premier_pokemon_dispo()
if nouveau:
print(f"{self.dresseur2.nom} envoie {nouveau.nom} !")
continue # Passer au tour suivant
# Le Pokémon 2 attaque
poke2.attaquer(poke1)
# Vérifier si Pokémon 1 est KO
if poke1.est_ko():
print(f"\n{poke1.nom} est KO !")
nouveau = self.dresseur1.premier_pokemon_dispo()
if nouveau:
print(f"{self.dresseur1.nom} envoie {nouveau.nom} !")
# Afficher le vainqueur
print(f"\n{'='*40}")
if self.dresseur1.tous_ko():
print(f"Tous les Pokémon de {self.dresseur1.nom} sont KO !")
print(f"*** {self.dresseur2.nom.upper()} REMPORTE LE COMBAT ! ***")
else:
print(f"Tous les Pokémon de {self.dresseur2.nom} sont KO !")
print(f"*** {self.dresseur1.nom.upper()} REMPORTE LE COMBAT ! ***")
print(f"{'='*40}")
# =============================================================================
# PARTIE 4 : Centre Pokémon
# =============================================================================
class CentrePokemon:
def __init__(self, ville):
"""
:param ville: (str) Ville où se trouve le centre
"""
self.ville = ville
def soigner_equipe(self, dresseur):
"""
Soigne tous les Pokémon d'un dresseur à 100% de leurs PV.
:param dresseur: (Dresseur) Dresseur dont l'équipe doit être soignée
"""
print(f"\n*** Centre Pokémon de {self.ville} ***")
print(f"Bienvenue {dresseur.nom} !")
print("Nous allons soigner vos Pokémon...")
for pokemon in dresseur.equipe:
pokemon.pv = pokemon.pv_max
print("Vos Pokémon sont en pleine forme !")
print("À bientôt !\n")
# =============================================================================
# BONUS : Classe Capacite
# =============================================================================
class Capacite:
def __init__(self, nom, puissance, type_capacite, pp_max):
"""
:param nom: (str) Nom de la capacité
:param puissance: (int) Puissance de base
:param type_capacite: (str) Type de la capacité
:param pp_max: (int) Nombre d'utilisations max
"""
self.nom = nom
self.puissance = puissance
self.type_capacite = type_capacite
self.pp_max = pp_max
self.pp = pp_max
def utiliser(self):
"""Utilise la capacité si PP disponibles."""
if self.pp > 0:
self.pp -= 1
return True
else:
print(f"{self.nom} : plus de PP !")
return False
def __repr__(self):
return f"{self.nom} ({self.type_capacite}) - {self.puissance} DMG - {self.pp}/{self.pp_max} PP"
# =============================================================================
# TESTS
# =============================================================================
if __name__ == "__main__":
print("=" * 50)
print("TEST DES CLASSES POKEMON")
print("=" * 50)
# Création des Pokémon
pikachu = Pokemon("Pikachu", "Electrik", 25, 80, 15)
dracaufeu = Pokemon("Dracaufeu", "Feu", 50, 150, 25)
tortank = Pokemon("Tortank", "Eau", 45, 140, 22)
onix = Pokemon("Onix", "Roche", 30, 120, 18)
racaillou = Pokemon("Racaillou", "Roche", 20, 80, 12)
print("\nPokémon créés :")
print(f" - {pikachu}")
print(f" - {dracaufeu}")
print(f" - {tortank}")
print(f" - {onix}")
print(f" - {racaillou}")
# Test des attaques avec faiblesses
print("\n--- Test attaque avec faiblesse ---")
print(f"Avant : {onix}")
tortank.attaquer(onix) # Eau bat Roche -> x2
print(f"Après : {onix}")
# Création des dresseurs
print("\n" + "=" * 50)
print("CREATION DES DRESSEURS")
print("=" * 50)
sacha = Dresseur("Sacha")
sacha.ajouter_pokemon(Pokemon("Pikachu", "Electrik", 25, 80, 15))
sacha.ajouter_pokemon(Pokemon("Dracaufeu", "Feu", 50, 150, 25))
sacha.ajouter_pokemon(Pokemon("Tortank", "Eau", 45, 140, 22))
pierre = Dresseur("Pierre")
pierre.ajouter_pokemon(Pokemon("Onix", "Roche", 30, 120, 18))
pierre.ajouter_pokemon(Pokemon("Racaillou", "Roche", 20, 80, 12))
print(f"\n{sacha}")
print(f"\n{pierre}")
# Lancement du combat
print("\n" + "=" * 50)
print("LANCEMENT DU COMBAT")
print("=" * 50)
combat = Combat(sacha, pierre)
combat.lancer_combat()
# Soins au Centre Pokémon
print("\n" + "=" * 50)
print("SOINS AU CENTRE POKEMON")
print("=" * 50)
centre = CentrePokemon("Argenta")
centre.soigner_equipe(sacha)
print(sacha)