792 lines
26 KiB
Plaintext
792 lines
26 KiB
Plaintext
{
|
||||
|
|
"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",
|
|||
|
|
"<a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"><img alt=\"Licence Creative Commons\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\">Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International</a>."
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"metadata": {
|
|||
|
|
"kernelspec": {
|
|||
|
|
"display_name": "Python 3",
|
|||
|
|
"language": "python",
|
|||
|
|
"name": "python3"
|
|||
|
|
},
|
|||
|
|
"language_info": {
|
|||
|
|
"name": "python"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"nbformat": 4,
|
|||
|
|
"nbformat_minor": 5
|
|||
|
|
}
|