Aller au contenu

TP : Pokémon Arena — Programmation Orientée Objet

Thème : Classes, attributs, méthodes, interactions entre objets


Contexte

Depuis 1996, Pokémon est l'une des franchises les plus populaires au monde. En 2026, avec la sortie de Pokémon Legends: Z-A, la licence bat tous les records.

Dans ce TP, vous allez créer un simulateur de combat Pokémon en utilisant la Programmation Orientée Objet. Vous modéliserez des Pokémon, des dresseurs et des combats.


Partie 1 : La classe Pokémon

Exercice 1 : Créer la classe de base

Créez une classe Pokemon avec les caractéristiques suivantes :

Attributs : - nom : nom du Pokémon (str) - type_pokemon : type élémentaire (str) — "Feu", "Eau", "Plante", "Electrik", etc. - niveau : niveau du Pokémon (int, par défaut 1) - pv_max : points de vie maximum (int, par défaut 100) - pv : points de vie actuels (int, initialisé à pv_max) - attaque : puissance d'attaque (int, par défaut 10)

Méthodes : - __init__ : constructeur - __repr__ : affiche le Pokémon sous la forme "Pikachu (Electrik) - Nv.25 - 80/100 PV"

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
        """
        # À compléter
        pass

    def __repr__(self):
        """Représentation textuelle du Pokémon."""
        # À compléter
        pass

Tests :

>>> pikachu = Pokemon("Pikachu", "Electrik", niveau=25, pv_max=80, attaque=15)
>>> print(pikachu)
Pikachu (Electrik) - Nv.25 - 80/80 PV


Exercice 2 : Méthodes de combat

Ajoutez les méthodes suivantes à la classe Pokemon :

def est_ko(self):
    """
    Vérifie si le Pokémon est KO.

    :return: (bool) True si PV <= 0, False sinon
    """
    # À compléter
    pass

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
    """
    # À compléter
    pass

def attaquer(self, cible):
    """
    Attaque un autre Pokémon.
    Affiche un message et inflige des dégâts à la cible.

    :param cible: (Pokemon) Pokémon ciblé par l'attaque
    """
    # À compléter
    pass

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
    """
    # À compléter
    pass

Tests :

>>> pikachu = Pokemon("Pikachu", "Electrik", niveau=25, pv_max=80, attaque=15)
>>> salameche = Pokemon("Salamèche", "Feu", niveau=20, pv_max=70, attaque=12)
>>> pikachu.attaquer(salameche)
Pikachu attaque Salamèche et inflige 15 dégâts !
>>> print(salameche)
Salamèche (Feu) - Nv.20 - 55/70 PV
>>> salameche.est_ko()
False


Exercice 3 : Système de faiblesses (Bonus)

En Pokémon, certains types sont plus efficaces contre d'autres : - Eau bat Feu (×2 dégâts) - Feu bat Plante (×2 dégâts) - Plante bat Eau (×2 dégâts) - Electrik bat Eau (×2 dégâts)

Modifiez la méthode attaquer pour prendre en compte les faiblesses :

# Dictionnaire des faiblesses : type_attaquant -> liste des types faibles
FAIBLESSES = {
    "Eau": ["Feu"],
    "Feu": ["Plante"],
    "Plante": ["Eau"],
    "Electrik": ["Eau"]
}

def attaquer(self, cible):
    """
    Attaque un autre Pokémon avec prise en compte des faiblesses.
    """
    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)

Partie 2 : La classe Dresseur

Exercice 4 : Créer la classe Dresseur

Un dresseur possède une équipe de Pokémon (maximum 6).

Attributs : - nom : nom du dresseur (str) - equipe : liste de Pokémon (list, vide par défaut)

Méthodes : - __init__ : constructeur - ajouter_pokemon(pokemon) : ajoute un Pokémon à l'équipe (max 6) - pokemon_disponibles() : renvoie la liste des Pokémon non KO - premier_pokemon_dispo() : renvoie le premier Pokémon non KO ou None - tous_ko() : renvoie True si tous les Pokémon sont KO - __repr__ : affiche le dresseur et son équipe

class Dresseur:
    def __init__(self, nom):
        """
        Constructeur de la classe Dresseur.

        :param nom: (str) Nom du dresseur
        """
        # À compléter
        pass

    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
        """
        # À compléter
        pass

    def pokemon_disponibles(self):
        """
        Renvoie la liste des Pokémon non KO.

        :return: (list) Liste des Pokémon encore en état de combattre
        """
        # À compléter
        pass

    def premier_pokemon_dispo(self):
        """
        Renvoie le premier Pokémon non KO.

        :return: (Pokemon/None) Premier Pokémon dispo ou None
        """
        # À compléter
        pass

    def tous_ko(self):
        """
        Vérifie si tous les Pokémon sont KO.

        :return: (bool) True si tous KO, False sinon
        """
        # À compléter
        pass

    def __repr__(self):
        """Représentation du dresseur."""
        # À compléter
        pass

Tests :

>>> sacha = Dresseur("Sacha")
>>> sacha.ajouter_pokemon(Pokemon("Pikachu", "Electrik", 25, 80, 15))
True
>>> sacha.ajouter_pokemon(Pokemon("Dracaufeu", "Feu", 50, 150, 25))
True
>>> print(sacha)
Dresseur Sacha - 2 Pokémon
  - Pikachu (Electrik) - Nv.25 - 80/80 PV
  - Dracaufeu (Feu) - Nv.50 - 150/150 PV
>>> sacha.tous_ko()
False


Partie 3 : La classe Combat

Exercice 5 : Simulateur de combat

Créez une classe Combat qui simule un affrontement entre deux dresseurs.

Attributs : - dresseur1 : premier dresseur (Dresseur) - dresseur2 : second dresseur (Dresseur) - tour : numéro du tour actuel (int)

Méthodes : - __init__ : constructeur - lancer_combat() : lance le combat jusqu'à ce qu'un dresseur n'ait plus de Pokémon - afficher_etat() : affiche l'état actuel du combat

class Combat:
    def __init__(self, dresseur1, dresseur2):
        """
        Constructeur de la classe Combat.

        :param dresseur1: (Dresseur) Premier dresseur
        :param dresseur2: (Dresseur) Second dresseur
        """
        # À compléter
        pass

    def afficher_etat(self):
        """Affiche l'état actuel du combat."""
        print(f"\n{'='*40}")
        print(f"Tour {self.tour}")
        print(f"{'='*40}")
        # Afficher les Pokémon actifs
        # À compléter
        pass

    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} ***\n")

        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
            # À compléter

            # Vérifier si Pokémon 2 est KO
            # À compléter

            # Le Pokémon 2 attaque (s'il n'est pas KO)
            # À compléter

            # Vérifier si Pokémon 1 est KO
            # À compléter

        # Afficher le vainqueur
        # À compléter
        pass

Exemple d'exécution :

*** COMBAT : Sacha VS Pierre ***

========================================
Tour 1
========================================
Sacha: Pikachu (80/80 PV)
Pierre: Onix (120/120 PV)

Pikachu attaque Onix et inflige 15 dégâts !
Onix attaque Pikachu et inflige 20 dégâts !

========================================
Tour 2
========================================
Sacha: Pikachu (60/80 PV)
Pierre: Onix (105/120 PV)

...

Pikachu est KO !
Sacha envoie Dracaufeu !

...

Tous les Pokémon de Pierre sont KO !
*** SACHA REMPORTE LE COMBAT ! ***


Partie 4 : Améliorations

Exercice 6 : Centre Pokémon

Créez une classe CentrePokemon qui permet de soigner une équipe :

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
        """
        # À compléter
        pass

Exercice 7 : Capacités spéciales (Pour aller plus loin)

Créez une classe Capacite pour donner des attaques spéciales aux Pokémon :

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

Modifiez la classe Pokemon pour qu'un Pokémon possède une liste de capacités (max 4) et puisse choisir son attaque.


Résumé des classes

Classe Attributs Méthodes principales
Pokemon nom, type, niveau, pv, attaque attaquer(), subir_degats(), est_ko()
Dresseur nom, equipe ajouter_pokemon(), tous_ko()
Combat dresseur1, dresseur2, tour lancer_combat()
CentrePokemon ville soigner_equipe()

Code de test final

# 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)

# Création des dresseurs
sacha = Dresseur("Sacha")
sacha.ajouter_pokemon(pikachu)
sacha.ajouter_pokemon(dracaufeu)
sacha.ajouter_pokemon(tortank)

pierre = Dresseur("Pierre")
pierre.ajouter_pokemon(onix)
pierre.ajouter_pokemon(racaillou)

# Lancement du combat
combat = Combat(sacha, pierre)
combat.lancer_combat()

# Soins au Centre Pokémon
centre = CentrePokemon("Argenta")
centre.soigner_equipe(sacha)
print(sacha)

Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster

Licence CC BY NC

Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.