From 977fa778e99a508f786e01a9fa961bfdc249ed6b Mon Sep 17 00:00:00 2001 From: Florian Mathieu Date: Mon, 28 Sep 2026 10:53:48 +0200 Subject: [PATCH] =?UTF-8?q?TP=20Pok=C3=A9mon=20:=20version=20notebook,=20e?= =?UTF-8?q?xemple=20de=20combat=20corrig=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- POO/TP/TP_Pokemon.md | 4 +- POO/TP/TP_Pokemon_notebook.ipynb | 791 +++++++++++++++++++++++++++++++ 2 files changed, 793 insertions(+), 2 deletions(-) create mode 100644 POO/TP/TP_Pokemon_notebook.ipynb diff --git a/POO/TP/TP_Pokemon.md b/POO/TP/TP_Pokemon.md index 0fcec21..9b263eb 100644 --- a/POO/TP/TP_Pokemon.md +++ b/POO/TP/TP_Pokemon.md @@ -327,12 +327,12 @@ 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 ! +Onix attaque Pikachu et inflige 18 dégâts ! ======================================== Tour 2 ======================================== -Sacha: Pikachu (60/80 PV) +Sacha: Pikachu (62/80 PV) Pierre: Onix (105/120 PV) ... diff --git a/POO/TP/TP_Pokemon_notebook.ipynb b/POO/TP/TP_Pokemon_notebook.ipynb new file mode 100644 index 0000000..2b50be9 --- /dev/null +++ b/POO/TP/TP_Pokemon_notebook.ipynb @@ -0,0 +1,791 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8cc139ef", + "metadata": {}, + "source": [ + "# TP : Pokémon Arena - Programmation Orientée Objet\n", + "\n", + "> **Thème** : Classes, attributs, méthodes, interactions entre objets\n", + "\n", + "---\n", + "\n", + "## Contexte\n", + "\n", + "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.\n", + "\n", + "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.\n", + "\n", + "---\n", + "\n", + "## Mode d'emploi du notebook\n", + "\n", + "- Complétez les cellules marquées `# À compléter`, puis exécutez-les (`Maj + Entrée`).\n", + "- Après chaque exercice, une cellule **Vérification** teste votre code. Si un test échoue, lisez la dernière ligne du message d'erreur : pour une `AssertionError`, elle indique ce qui ne va pas ; une `AttributeError` signale en général un attribut ou une méthode pas encore écrits.\n", + "- Quand vous modifiez une classe, **réexécutez sa cellule** avant de relancer les vérifications. En cas de doute : menu *Noyau* puis *Redémarrer et tout exécuter*." + ] + }, + { + "cell_type": "markdown", + "id": "145f2f74", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Partie 1 : La classe Pokémon\n", + "\n", + "### Exercice 1 : Créer la classe de base\n", + "\n", + "Complétez le constructeur et la méthode `__repr__` de la classe `Pokemon`.\n", + "\n", + "**Attributs :**\n", + "- `nom` : nom du Pokémon (str)\n", + "- `type_pokemon` : type élémentaire (str) : \"Feu\", \"Eau\", \"Plante\", \"Electrik\", etc.\n", + "- `niveau` : niveau du Pokémon (int, par défaut 1)\n", + "- `pv_max` : points de vie maximum (int, par défaut 100)\n", + "- `pv` : points de vie actuels (int, initialisé à `pv_max`)\n", + "- `attaque` : puissance d'attaque (int, par défaut 10)\n", + "\n", + "**Méthodes :**\n", + "- `__init__` : constructeur\n", + "- `__repr__` : renvoie le Pokémon sous la forme `\"Pikachu (Electrik) - Nv.25 - 80/100 PV\"`\n", + "\n", + "Les méthodes de l'exercice 2 sont déjà présentes dans la classe : vous les compléterez ensuite, dans **la même cellule**." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "649474f4", + "metadata": {}, + "outputs": [], + "source": [ + "class Pokemon:\n", + " def __init__(self, nom, type_pokemon, niveau=1, pv_max=100, attaque=10):\n", + " \"\"\"\n", + " Constructeur de la classe Pokemon.\n", + "\n", + " :param nom: (str) Nom du Pokémon\n", + " :param type_pokemon: (str) Type élémentaire\n", + " :param niveau: (int) Niveau du Pokémon\n", + " :param pv_max: (int) Points de vie maximum\n", + " :param attaque: (int) Puissance d'attaque\n", + " \"\"\"\n", + " # À compléter (exercice 1)\n", + " pass\n", + "\n", + " def __repr__(self):\n", + " \"\"\"Représentation textuelle du Pokémon.\"\"\"\n", + " # À compléter (exercice 1)\n", + " pass\n", + "\n", + " def est_ko(self):\n", + " \"\"\"\n", + " Vérifie si le Pokémon est KO.\n", + "\n", + " :return: (bool) True si PV <= 0, False sinon\n", + " \"\"\"\n", + " # À compléter (exercice 2)\n", + " pass\n", + "\n", + " def subir_degats(self, degats):\n", + " \"\"\"\n", + " Inflige des dégâts au Pokémon.\n", + " Les PV ne peuvent pas descendre en dessous de 0.\n", + "\n", + " :param degats: (int) Nombre de dégâts subis\n", + " \"\"\"\n", + " # À compléter (exercice 2)\n", + " pass\n", + "\n", + " def attaquer(self, cible):\n", + " \"\"\"\n", + " Attaque un autre Pokémon.\n", + " Affiche un message et inflige des dégâts à la cible.\n", + "\n", + " :param cible: (Pokemon) Pokémon ciblé par l'attaque\n", + " \"\"\"\n", + " # À compléter (exercice 2, puis exercice 3 en bonus)\n", + " pass\n", + "\n", + " def soigner(self, soin):\n", + " \"\"\"\n", + " Soigne le Pokémon.\n", + " Les PV ne peuvent pas dépasser pv_max.\n", + "\n", + " :param soin: (int) Nombre de PV récupérés\n", + " \"\"\"\n", + " # À compléter (exercice 2)\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "99482193", + "metadata": {}, + "source": [ + "**Vérification de l'exercice 1**\n", + "\n", + "Affichage attendu : `Pikachu (Electrik) - Nv.25 - 80/80 PV`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e050c69", + "metadata": {}, + "outputs": [], + "source": [ + "pikachu = Pokemon(\"Pikachu\", \"Electrik\", niveau=25, pv_max=80, attaque=15)\n", + "\n", + "assert pikachu.nom == \"Pikachu\", \"L'attribut nom est incorrect\"\n", + "assert pikachu.type_pokemon == \"Electrik\", \"L'attribut type_pokemon est incorrect\"\n", + "assert pikachu.niveau == 25, \"L'attribut niveau est incorrect\"\n", + "assert pikachu.pv_max == 80, \"L'attribut pv_max est incorrect\"\n", + "assert pikachu.pv == 80, \"Les PV doivent être initialisés à pv_max\"\n", + "assert pikachu.attaque == 15, \"L'attribut attaque est incorrect\"\n", + "assert repr(pikachu) == \"Pikachu (Electrik) - Nv.25 - 80/80 PV\", \"__repr__ ne renvoie pas le bon texte\"\n", + "\n", + "magicarpe = Pokemon(\"Magicarpe\", \"Eau\")\n", + "assert magicarpe.niveau == 1 and magicarpe.pv_max == 100 and magicarpe.pv == 100 and magicarpe.attaque == 10, \\\n", + " \"Les valeurs par défaut sont incorrectes\"\n", + "\n", + "print(pikachu)\n", + "print(\"Exercice 1 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "247ab7c0", + "metadata": {}, + "source": [ + "---\n", + "\n", + "### Exercice 2 : Méthodes de combat\n", + "\n", + "Revenez dans la cellule de la classe `Pokemon` et complétez les méthodes `est_ko`, `subir_degats`, `attaquer` et `soigner`, en suivant leur docstring. Réexécutez ensuite la cellule de la classe.\n", + "\n", + "La méthode `attaquer` inflige à la cible autant de dégâts que la valeur d'`attaque` du Pokémon, et affiche un message de la forme :\n", + "\n", + "```\n", + "Pikachu attaque Salamèche et inflige 15 dégâts !\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "06394e37", + "metadata": {}, + "source": [ + "**Vérification de l'exercice 2**\n", + "\n", + "Affichage attendu :\n", + "\n", + "```\n", + "Pikachu attaque Salamèche et inflige 15 dégâts !\n", + "Salamèche (Feu) - Nv.20 - 55/70 PV\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0799edc6", + "metadata": {}, + "outputs": [], + "source": [ + "pikachu = Pokemon(\"Pikachu\", \"Electrik\", niveau=25, pv_max=80, attaque=15)\n", + "salameche = Pokemon(\"Salamèche\", \"Feu\", niveau=20, pv_max=70, attaque=12)\n", + "\n", + "pikachu.attaquer(salameche)\n", + "print(salameche)\n", + "\n", + "assert salameche.pv == 55, \"attaquer doit retirer attaque PV à la cible\"\n", + "assert pikachu.pv == 80, \"attaquer ne doit pas modifier les PV de l'attaquant\"\n", + "assert salameche.est_ko() is False, \"est_ko doit renvoyer False quand il reste des PV\"\n", + "\n", + "salameche.subir_degats(100)\n", + "assert salameche.pv == 0, \"Les PV ne doivent pas descendre en dessous de 0\"\n", + "assert salameche.est_ko() is True, \"est_ko doit renvoyer True quand les PV sont à 0\"\n", + "\n", + "salameche.soigner(30)\n", + "assert salameche.pv == 30, \"soigner doit ajouter les PV indiqués\"\n", + "salameche.soigner(100)\n", + "assert salameche.pv == 70, \"Les PV ne doivent pas dépasser pv_max\"\n", + "\n", + "print(\"Exercice 2 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "907d0e25", + "metadata": {}, + "source": [ + "---\n", + "\n", + "### Exercice 3 : Système de faiblesses (Bonus)\n", + "\n", + "En Pokémon, certains types sont plus efficaces contre d'autres :\n", + "- **Eau** bat **Feu** (×2 dégâts)\n", + "- **Feu** bat **Plante** (×2 dégâts)\n", + "- **Plante** bat **Eau** (×2 dégâts)\n", + "- **Electrik** bat **Eau** (×2 dégâts)\n", + "\n", + "Exécutez la cellule ci-dessous, qui définit le dictionnaire des faiblesses." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11d5c707", + "metadata": {}, + "outputs": [], + "source": [ + "# Dictionnaire des faiblesses : type_attaquant -> liste des types faibles\n", + "FAIBLESSES = {\n", + " \"Eau\": [\"Feu\"],\n", + " \"Feu\": [\"Plante\"],\n", + " \"Plante\": [\"Eau\"],\n", + " \"Electrik\": [\"Eau\"]\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "f2e0fc37", + "metadata": {}, + "source": [ + "Modifiez ensuite la méthode `attaquer` de la classe `Pokemon` : si le type de la cible est faible contre celui de l'attaquant, les dégâts sont doublés et le message `C'est super efficace !` s'affiche avant le message d'attaque.\n", + "\n", + "```python\n", + "def attaquer(self, cible):\n", + " \"\"\"\n", + " Attaque un autre Pokémon avec prise en compte des faiblesses.\n", + " \"\"\"\n", + " degats = self.attaque\n", + "\n", + " # Vérifier si le type de la cible est faible contre notre type\n", + " if self.type_pokemon in FAIBLESSES:\n", + " if cible.type_pokemon in FAIBLESSES[self.type_pokemon]:\n", + " degats *= 2\n", + " print(\"C'est super efficace !\")\n", + "\n", + " print(f\"{self.nom} attaque {cible.nom} et inflige {degats} dégâts !\")\n", + " cible.subir_degats(degats)\n", + "```\n", + "\n", + "Réexécutez la cellule de la classe `Pokemon`, puis la vérification ci-dessous.\n", + "\n", + "**Vérification de l'exercice 3**\n", + "\n", + "Affichage attendu :\n", + "\n", + "```\n", + "C'est super efficace !\n", + "Carapuce attaque Salamèche et inflige 20 dégâts !\n", + "Salamèche attaque Carapuce et inflige 12 dégâts !\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dcc9de27", + "metadata": {}, + "outputs": [], + "source": [ + "carapuce = Pokemon(\"Carapuce\", \"Eau\", niveau=15, pv_max=75, attaque=10)\n", + "salameche = Pokemon(\"Salamèche\", \"Feu\", niveau=15, pv_max=70, attaque=12)\n", + "\n", + "carapuce.attaquer(salameche)\n", + "assert salameche.pv == 50, \"Eau contre Feu : les dégâts doivent être doublés\"\n", + "\n", + "salameche.attaquer(carapuce)\n", + "assert carapuce.pv == 63, \"Feu contre Eau : les dégâts ne doivent pas être doublés\"\n", + "\n", + "print(\"Exercice 3 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "babba110", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Partie 2 : La classe Dresseur\n", + "\n", + "### Exercice 4 : Créer la classe Dresseur\n", + "\n", + "Un dresseur possède une équipe de Pokémon (maximum 6).\n", + "\n", + "**Attributs :**\n", + "- `nom` : nom du dresseur (str)\n", + "- `equipe` : liste de Pokémon (list, vide au départ)\n", + "\n", + "**Méthodes :**\n", + "- `__init__` : constructeur\n", + "- `ajouter_pokemon(pokemon)` : ajoute un Pokémon à l'équipe (max 6)\n", + "- `pokemon_disponibles()` : renvoie la liste des Pokémon non KO\n", + "- `premier_pokemon_dispo()` : renvoie le premier Pokémon non KO ou `None`\n", + "- `tous_ko()` : renvoie `True` si tous les Pokémon sont KO\n", + "- `__repr__` : renvoie le dresseur et son équipe, un Pokémon par ligne" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e51328d", + "metadata": {}, + "outputs": [], + "source": [ + "class Dresseur:\n", + " def __init__(self, nom):\n", + " \"\"\"\n", + " Constructeur de la classe Dresseur.\n", + "\n", + " :param nom: (str) Nom du dresseur\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def ajouter_pokemon(self, pokemon):\n", + " \"\"\"\n", + " Ajoute un Pokémon à l'équipe si possible (max 6).\n", + "\n", + " :param pokemon: (Pokemon) Pokémon à ajouter\n", + " :return: (bool) True si ajouté, False sinon\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def pokemon_disponibles(self):\n", + " \"\"\"\n", + " Renvoie la liste des Pokémon non KO.\n", + "\n", + " :return: (list) Liste des Pokémon encore en état de combattre\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def premier_pokemon_dispo(self):\n", + " \"\"\"\n", + " Renvoie le premier Pokémon non KO.\n", + "\n", + " :return: (Pokemon/None) Premier Pokémon dispo ou None\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def tous_ko(self):\n", + " \"\"\"\n", + " Vérifie si tous les Pokémon sont KO.\n", + "\n", + " :return: (bool) True si tous KO, False sinon\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def __repr__(self):\n", + " \"\"\"Représentation du dresseur.\"\"\"\n", + " # À compléter\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "5f99837d", + "metadata": {}, + "source": [ + "**Vérification de l'exercice 4**\n", + "\n", + "Affichage attendu :\n", + "\n", + "```\n", + "Dresseur Sacha - 2 Pokémon\n", + " - Pikachu (Electrik) - Nv.25 - 80/80 PV\n", + " - Dracaufeu (Feu) - Nv.50 - 150/150 PV\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e735fc8f", + "metadata": {}, + "outputs": [], + "source": [ + "sacha = Dresseur(\"Sacha\")\n", + "assert sacha.nom == \"Sacha\" and sacha.equipe == [], \"Un dresseur commence avec une équipe vide\"\n", + "\n", + "assert sacha.ajouter_pokemon(Pokemon(\"Pikachu\", \"Electrik\", 25, 80, 15)) is True\n", + "assert sacha.ajouter_pokemon(Pokemon(\"Dracaufeu\", \"Feu\", 50, 150, 25)) is True\n", + "\n", + "assert repr(sacha) == \"Dresseur Sacha - 2 Pokémon\\n - Pikachu (Electrik) - Nv.25 - 80/80 PV\\n - Dracaufeu (Feu) - Nv.50 - 150/150 PV\", \\\n", + " \"__repr__ ne renvoie pas le bon texte\"\n", + "print(sacha)\n", + "assert sacha.tous_ko() is False\n", + "\n", + "sacha.equipe[0].subir_degats(100)\n", + "assert sacha.premier_pokemon_dispo().nom == \"Dracaufeu\", \"Pikachu est KO, le premier disponible est Dracaufeu\"\n", + "assert len(sacha.pokemon_disponibles()) == 1, \"Un seul Pokémon est encore disponible\"\n", + "\n", + "sacha.equipe[1].subir_degats(200)\n", + "assert sacha.tous_ko() is True, \"Tous les Pokémon sont KO\"\n", + "assert sacha.premier_pokemon_dispo() is None, \"Aucun Pokémon disponible : il faut renvoyer None\"\n", + "\n", + "for i in range(4):\n", + " sacha.ajouter_pokemon(Pokemon(f\"Pokémon {i}\", \"Normal\"))\n", + "assert sacha.ajouter_pokemon(Pokemon(\"Septième\", \"Normal\")) is False, \"Une équipe est limitée à 6 Pokémon\"\n", + "assert len(sacha.equipe) == 6\n", + "\n", + "print(\"Exercice 4 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "fa138c5d", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Partie 3 : La classe Combat\n", + "\n", + "### Exercice 5 : Simulateur de combat\n", + "\n", + "Créez une classe `Combat` qui simule un affrontement entre deux dresseurs.\n", + "\n", + "**Attributs :**\n", + "- `dresseur1` : premier dresseur (Dresseur)\n", + "- `dresseur2` : second dresseur (Dresseur)\n", + "- `tour` : numéro du tour actuel (int, 0 au départ)\n", + "\n", + "**Méthodes :**\n", + "- `__init__` : constructeur\n", + "- `afficher_etat()` : affiche le numéro du tour et les Pokémon actifs des deux dresseurs\n", + "- `lancer_combat()` : lance le combat jusqu'à ce qu'un dresseur n'ait plus de Pokémon" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b189d40", + "metadata": {}, + "outputs": [], + "source": [ + "class Combat:\n", + " def __init__(self, dresseur1, dresseur2):\n", + " \"\"\"\n", + " Constructeur de la classe Combat.\n", + "\n", + " :param dresseur1: (Dresseur) Premier dresseur\n", + " :param dresseur2: (Dresseur) Second dresseur\n", + " \"\"\"\n", + " # À compléter\n", + " pass\n", + "\n", + " def afficher_etat(self):\n", + " \"\"\"Affiche l'état actuel du combat.\"\"\"\n", + " print(f\"\\n{'='*40}\")\n", + " print(f\"Tour {self.tour}\")\n", + " print(f\"{'='*40}\")\n", + " # Afficher les Pokémon actifs\n", + " # À compléter\n", + " pass\n", + "\n", + " def lancer_combat(self):\n", + " \"\"\"\n", + " Lance le combat tour par tour.\n", + " Chaque tour, les deux Pokémon actifs s'attaquent.\n", + " Quand un Pokémon est KO, le suivant prend sa place.\n", + " Le combat s'arrête quand un dresseur n'a plus de Pokémon.\n", + " \"\"\"\n", + " print(f\"\\n*** COMBAT : {self.dresseur1.nom} VS {self.dresseur2.nom} ***\")\n", + "\n", + " while not self.dresseur1.tous_ko() and not self.dresseur2.tous_ko():\n", + " self.tour += 1\n", + " self.afficher_etat()\n", + "\n", + " # Récupérer les Pokémon actifs\n", + " poke1 = self.dresseur1.premier_pokemon_dispo()\n", + " poke2 = self.dresseur2.premier_pokemon_dispo()\n", + "\n", + " # Le Pokémon 1 attaque\n", + " # À compléter\n", + "\n", + " # Vérifier si Pokémon 2 est KO\n", + " # À compléter\n", + "\n", + " # Le Pokémon 2 attaque (s'il n'est pas KO)\n", + " # À compléter\n", + "\n", + " # Vérifier si Pokémon 1 est KO\n", + " # À compléter\n", + "\n", + " # Afficher le vainqueur\n", + " # À compléter\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "9585a7c3", + "metadata": {}, + "source": [ + "**Vérification de l'exercice 5**\n", + "\n", + "Début de l'affichage attendu :\n", + "\n", + "```\n", + "*** COMBAT : Sacha VS Pierre ***\n", + "\n", + "========================================\n", + "Tour 1\n", + "========================================\n", + "Sacha: Pikachu (80/80 PV)\n", + "Pierre: Onix (120/120 PV)\n", + "\n", + "Pikachu attaque Onix et inflige 15 dégâts !\n", + "Onix attaque Pikachu et inflige 18 dégâts !\n", + "\n", + "========================================\n", + "Tour 2\n", + "========================================\n", + "Sacha: Pikachu (62/80 PV)\n", + "Pierre: Onix (105/120 PV)\n", + "\n", + "Pikachu attaque Onix et inflige 15 dégâts !\n", + "Onix attaque Pikachu et inflige 18 dégâts !\n", + "\n", + "...\n", + "\n", + "Pikachu est KO !\n", + "Sacha envoie Dracaufeu !\n", + "\n", + "...\n", + "\n", + "Tous les Pokémon de Pierre sont KO !\n", + "*** SACHA REMPORTE LE COMBAT ! ***\n", + "```\n", + "\n", + "Le combat doit durer **11 tours** et se terminer par la victoire de Sacha." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a214d66b", + "metadata": {}, + "outputs": [], + "source": [ + "sacha = Dresseur(\"Sacha\")\n", + "sacha.ajouter_pokemon(Pokemon(\"Pikachu\", \"Electrik\", 25, 80, 15))\n", + "sacha.ajouter_pokemon(Pokemon(\"Dracaufeu\", \"Feu\", 50, 150, 25))\n", + "sacha.ajouter_pokemon(Pokemon(\"Tortank\", \"Eau\", 45, 140, 22))\n", + "\n", + "pierre = Dresseur(\"Pierre\")\n", + "pierre.ajouter_pokemon(Pokemon(\"Onix\", \"Roche\", 30, 120, 18))\n", + "pierre.ajouter_pokemon(Pokemon(\"Racaillou\", \"Roche\", 20, 80, 12))\n", + "\n", + "combat = Combat(sacha, pierre)\n", + "combat.lancer_combat()\n", + "\n", + "assert pierre.tous_ko() is True, \"Pierre doit avoir perdu tous ses Pokémon\"\n", + "assert sacha.tous_ko() is False, \"Sacha doit avoir encore au moins un Pokémon\"\n", + "assert combat.tour == 11, \"Le nombre de tours n'est pas le bon\"\n", + "\n", + "print(\"\\nExercice 5 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "89552429", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Partie 4 : Améliorations\n", + "\n", + "### Exercice 6 : Centre Pokémon\n", + "\n", + "Complétez la classe `CentrePokemon`, qui permet de soigner toute l'équipe d'un dresseur." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "051b5163", + "metadata": {}, + "outputs": [], + "source": [ + "class CentrePokemon:\n", + " def __init__(self, ville):\n", + " \"\"\"\n", + " :param ville: (str) Ville où se trouve le centre\n", + " \"\"\"\n", + " self.ville = ville\n", + "\n", + " def soigner_equipe(self, dresseur):\n", + " \"\"\"\n", + " Soigne tous les Pokémon d'un dresseur à 100% de leurs PV.\n", + "\n", + " :param dresseur: (Dresseur) Dresseur dont l'équipe doit être soignée\n", + " \"\"\"\n", + " # À compléter\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "641f5123", + "metadata": {}, + "source": [ + "**Vérification de l'exercice 6**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1bb51d5", + "metadata": {}, + "outputs": [], + "source": [ + "sacha = Dresseur(\"Sacha\")\n", + "sacha.ajouter_pokemon(Pokemon(\"Pikachu\", \"Electrik\", 25, 80, 15))\n", + "sacha.ajouter_pokemon(Pokemon(\"Dracaufeu\", \"Feu\", 50, 150, 25))\n", + "sacha.equipe[0].subir_degats(100)\n", + "sacha.equipe[1].subir_degats(40)\n", + "\n", + "centre = CentrePokemon(\"Argenta\")\n", + "centre.soigner_equipe(sacha)\n", + "print(sacha)\n", + "\n", + "assert sacha.equipe[0].pv == 80, \"Pikachu doit retrouver tous ses PV\"\n", + "assert sacha.equipe[1].pv == 150, \"Dracaufeu doit retrouver tous ses PV\"\n", + "\n", + "print(\"Exercice 6 : tous les tests sont passés.\")" + ] + }, + { + "cell_type": "markdown", + "id": "22be32db", + "metadata": {}, + "source": [ + "---\n", + "\n", + "### Exercice 7 : Capacités spéciales (Pour aller plus loin)\n", + "\n", + "Voici une classe `Capacite` pour donner des attaques spéciales aux Pokémon.\n", + "\n", + "Modifiez la classe `Pokemon` pour qu'un Pokémon possède une liste de capacités (max 4) et puisse choisir son attaque. Vous pouvez aussi ajouter des méthodes à la classe `Capacite` (par exemple une méthode qui décrémente les PP à chaque utilisation)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32a0e896", + "metadata": {}, + "outputs": [], + "source": [ + "class Capacite:\n", + " def __init__(self, nom, puissance, type_capacite, pp_max):\n", + " \"\"\"\n", + " :param nom: (str) Nom de la capacité\n", + " :param puissance: (int) Puissance de base\n", + " :param type_capacite: (str) Type de la capacité\n", + " :param pp_max: (int) Nombre d'utilisations max\n", + " \"\"\"\n", + " self.nom = nom\n", + " self.puissance = puissance\n", + " self.type_capacite = type_capacite\n", + " self.pp_max = pp_max\n", + " self.pp = pp_max" + ] + }, + { + "cell_type": "markdown", + "id": "7d856e73", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Résumé des classes\n", + "\n", + "| Classe | Attributs | Méthodes principales |\n", + "|--------|-----------|----------------------|\n", + "| `Pokemon` | nom, type_pokemon, niveau, pv_max, pv, attaque | attaquer(), subir_degats(), est_ko(), soigner() |\n", + "| `Dresseur` | nom, equipe | ajouter_pokemon(), premier_pokemon_dispo(), tous_ko() |\n", + "| `Combat` | dresseur1, dresseur2, tour | afficher_etat(), lancer_combat() |\n", + "| `CentrePokemon` | ville | soigner_equipe() |\n", + "\n", + "---\n", + "\n", + "## Code de test final\n", + "\n", + "Toutes vos classes sont prêtes ? Lancez le combat complet." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd1fa15a", + "metadata": {}, + "outputs": [], + "source": [ + "# Création des Pokémon\n", + "pikachu = Pokemon(\"Pikachu\", \"Electrik\", 25, 80, 15)\n", + "dracaufeu = Pokemon(\"Dracaufeu\", \"Feu\", 50, 150, 25)\n", + "tortank = Pokemon(\"Tortank\", \"Eau\", 45, 140, 22)\n", + "onix = Pokemon(\"Onix\", \"Roche\", 30, 120, 18)\n", + "racaillou = Pokemon(\"Racaillou\", \"Roche\", 20, 80, 12)\n", + "\n", + "# Création des dresseurs\n", + "sacha = Dresseur(\"Sacha\")\n", + "sacha.ajouter_pokemon(pikachu)\n", + "sacha.ajouter_pokemon(dracaufeu)\n", + "sacha.ajouter_pokemon(tortank)\n", + "\n", + "pierre = Dresseur(\"Pierre\")\n", + "pierre.ajouter_pokemon(onix)\n", + "pierre.ajouter_pokemon(racaillou)\n", + "\n", + "# Lancement du combat\n", + "combat = Combat(sacha, pierre)\n", + "combat.lancer_combat()\n", + "\n", + "# Soins au Centre Pokémon\n", + "centre = CentrePokemon(\"Argenta\")\n", + "centre.soigner_equipe(sacha)\n", + "print()\n", + "print(sacha)" + ] + }, + { + "cell_type": "markdown", + "id": "e44fab5c", + "metadata": {}, + "source": [ + "---\n", + "\n", + "Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster\n", + "\n", + "Licence CC BY-SA\n", + "\n", + "\"Licence
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}