Ressource

Solutions

Corrections de tous les exercices du chapitre POO

Sommaire

  1. Séance 1 — L'inventaire mal rangé
  2. Séance 2 — Monstre et Objet_magique
  3. Séance 3 — se_soigner et est_vivant
  4. Séance 4 — Boucle de combat + quiz
  5. Séance 5 — Encapsulation
  6. Séance 6 — La classe Mage
  7. Séances 7-8 — Le donjon (proposition complète)
  8. Annale — Sujet 1 (Laser Game)
  9. Annale — Sujet 2 (La bataille)
  10. Annale — Sujet 3 (Antennes)
  11. Annale — Sujet 4 (Personnel)
Annales bac — Les énoncés complets sont sur la page Annales. Les corrections ci-dessous s'y réfèrent.

Séance 1 L'inventaire mal rangé

  1. 3 objets : l'épée, la potion, le bouclier.
  2. Attributs : nom, degats, rare.
  3. "On crée un objet de la classe ObjetMagique en lui donnant le nom 'Excalibur', les dégâts 25, et rare = True."
  4. 150 variables à gérer pour 50 objets, risque de confusion, aucune boucle simple possible sur "tous les objets".

Séance 2 Monstre et Objet_magique

monstre.py
class Monstre:
    def __init__(self, nom, pv, degats, butin):
        self.nom = nom
        self.pv = pv
        self.degats = degats
        self.butin = butin

class Objet_magique:
    def __init__(self, nom, effet, valeur):
        self.nom = nom
        self.effet = effet
        self.valeur = valeur

epee = Objet_magique("Excalibur", "attaque", 25)

Séance 3 se_soigner et est_vivant

personnage.py
    def se_soigner(self, quantite):
        self.pv = self.pv + quantite

    def est_vivant(self):
        return self.pv > 0

Séance 4 Boucle de combat + quiz

combat.py
hero = Personnage("Aria", 100, 15)
monstre = Personnage("Gobelin", 30, 12)

while hero.est_vivant() and monstre.est_vivant():
    hero.attaquer(monstre)
    if monstre.est_vivant():
        monstre.attaquer(hero)

if hero.est_vivant():
    print(f"{hero.nom} a gagné !")
else:
    print(f"{monstre.nom} a gagné !")

Quiz : 1. c)   2. orc.pv   3. Faux   4. L'objet qui reçoit l'attaque   5. Pour éviter de répéter la logique partout et centraliser une règle qui pourrait changer.

Séance 5 Encapsulation

personnage_protege.py
class Personnage:
    def __init__(self, nom, pv, force):
        self.nom = nom
        self._pv = pv
        self.force = force

    @property
    def pv(self):
        return self._pv

    @pv.setter
    def pv(self, valeur):
        self._pv = max(0, min(100, valeur))

Séance 6 La classe Mage

mage.py
class Mage(Personnage):
    def __init__(self, nom, pv, force, mana):
        super().__init__(nom, pv, force)
        self.mana = mana

    def lancer_sort(self, cible):
        self.mana = self.mana - 10
        cible.pv = cible.pv - self.force * 2
        print(f"{self.nom} lance un sort sur {cible.nom} !")

Séances 7-8 Le donjon — proposition complète

Couvre les 5 contraintes obligatoires + 2 bonus (inventaire, historique). À adapter, pas à distribuer telle quelle aux élèves.

donjon.py
class Personnage:
    def __init__(self, nom, pv_max, force):
        self.nom = nom
        self.pv_max = pv_max
        self._pv = pv_max
        self.force = force
        self.historique = []

    @property
    def pv(self):
        return self._pv

    @pv.setter
    def pv(self, valeur):
        self._pv = max(0, min(self.pv_max, valeur))

    def attaquer(self, cible):
        cible.pv = cible.pv - self.force
        self.historique.append(f"{self.nom} attaque {cible.nom}")

    def est_vivant(self):
        return self.pv > 0


class Guerrier(Personnage):
    def __init__(self, nom, pv_max, force, armure):
        super().__init__(nom, pv_max, force)
        self.armure = armure

    def attaquer(self, cible):
        print(f"{self.nom} charge avec son armure !")
        super().attaquer(cible)


class Mage(Personnage):
    def __init__(self, nom, pv_max, force, mana):
        super().__init__(nom, pv_max, force)
        self.mana = mana

    def lancer_sort(self, cible):
        if self.mana >= 10:
            self.mana -= 10
            cible.pv = cible.pv - self.force * 2
            self.historique.append(f"{self.nom} lance un sort sur {cible.nom}")
        else:
            self.attaquer(cible)


class Inventaire:
    def __init__(self):
        self.objets = []

    def ajouter(self, objet):
        self.objets.append(objet)


def descente(hero, monstres):
    inventaire = Inventaire()
    for monstre in monstres:
        print(f"--- {hero.nom} affronte {monstre.nom} ---")
        while hero.est_vivant() and monstre.est_vivant():
            hero.attaquer(monstre)
            if monstre.est_vivant():
                monstre.attaquer(hero)
        if not hero.est_vivant():
            print(f"{hero.nom} est tombé au combat...")
            return False
        print(f"{monstre.nom} est vaincu !")
        inventaire.ajouter(f"Butin de {monstre.nom}")
    print(f"{hero.nom} a traversé le donjon !")
    return True
À noter — pv_max est ici configurable par personnage (au lieu du 100 fixe de la séance 5) — une petite évolution naturelle si un binôme veut des monstres avec des maximums différents. L'historique est stocké directement sur chaque personnage plutôt que dans une liste globale, ce qui évite de la faire circuler en paramètre partout.

Annale · Sujet 1 Le jeu de tir laser

joueur_corrige.py
# 1. Réponse c) joueur_1 = Joueur("Sniper", 319, "A")

def redevenir_actif(self):
    if not self.est_actif:
        self.est_actif = True

def nb_tirs_recus(self):
    return len(self.liste_id_tirs_recus)

# 4. Bonus de 40 points pour chaque joueur déterminé :
if participant.est_determine():
    self.decremente_score(-40)

Annale · Sujet 2 La bataille de cartes

carte_corrige.py
class Carte:
    def __init__(self, val, coul):
        self.valeur = val
        self.couleur = coul

# 2. Réponse c) c7 = Carte(7, "coeur")

def initialiser():
    jeu = []
    for coul in ["coeur", "carreau", "trefle", "pique"]:
        for val in range(2, 15):
            jeu.append(Carte(val, coul))
    return jeu

def comparer(carte_1, carte_2):
    if carte_1.valeur > carte_2.valeur:
        return 1
    elif carte_1.valeur < carte_2.valeur:
        return -1
    else:
        return 0

Bonus (5) — On retire d'un côté (le dessus) et on ajoute de l'autre (le dessous) : c'est le principe premier entré, premier sorti, donc la File modélise le mieux ce tas de cartes.

Annale · Sujet 3 Couverture réseau

antenne_corrige.py
m1 = Maison(1)
m2 = Maison(3.5)
a = Antenne(2.5, 1)

def couvre(self, maison):
    return abs(self.get_pos_antenne() - maison.get_pos_maison()) <= self.get_rayon()

def creation_rue(positions):
    positions.sort()
    maisons = []
    for p in positions:
        maisons.append(Maison(p))
    return maisons

Annale · Sujet 4 Le personnel

personnel_corrige.py
personneA = Personne(112, "LESIEUR", "Isabelle", 1982, 2005)
# personneA.num_badge

def annee_anciennete(self):
    return 2026 - self.annee_entree

def ajouter(self, personne):
    self.liste.append(personne)

def effectif(self):
    return len(self.liste)

def donne_nom(self, num):
    for elt in self.liste:
        if elt.num_badge == num:
            return elt.nom
    return None

# Question défi
def plus_anciens(self):
    max_anciennete = max(p.annee_anciennete() for p in self.liste)
    return [p.num_badge for p in self.liste if p.annee_anciennete() == max_anciennete]