Programmer en Python
Leçon 3 - Projet Python : ton propre Pokédex
Construire un bestiaire de Pokémon avec des fonctions et des listes
Projet Python : ton propre Pokédex
Construire un bestiaire de Pokémon avec des fonctions et des listes
Ce projet fait suite aux cours « Débuter en Python » et « Python : fonctions et listes ». Il n’apporte pas de notion nouvelle : il te propose de réunir tout ce que tu sais déjà faire pour fabriquer quelque chose d’amusant et de réellement utile, un bestiaire de Pokémon que tu composes toi-même. À la fin, tu disposeras d’un petit programme capable de garder tes Pokémon en mémoire, de les afficher proprement, d’en ajouter de nouveaux et de retrouver celui que tu cherches.
Chaque chapitre suit le même rythme : une courte leçon rappelle une notion, puis un exercice te demande d’écrire le code toi-même. Les corrigés sont rassemblés à la fin de la fiche. Le bon réflexe : tenter l’exercice seul, exécuter son programme, puis le comparer au corrigé. C’est en essayant, et parfois en se trompant, que l’on progresse.
🎒 Avant de te lancer
Ce projet suppose acquis : afficher avec print, lire une réponse avec input, manipuler des variables et leurs types (int, str), écrire des conditions if / elif / else, répéter avec une boucle for et une boucle while, créer tes propres fonctions avec def et return, et travailler avec des listes (créer, accéder par l’index, mesurer avec len, ajouter avec append, tester la présence avec in, parcourir avec for). Si l’un de ces mots te semble lointain, rouvre le cours correspondant avant de continuer.
Garde un éditeur Python ouvert : tu y écriras et exécuteras chaque exercice.
🎯 Objectifs du projet
- Rassembler les informations d’un Pokémon dans une fonction d’affichage.
- Ranger plusieurs Pokémon à l’aide de listes parallèles.
- Agrandir ta collection en cours de route.
- Écrire un petit moteur de recherche pour retrouver un Pokémon par son nom.
🐛 Une histoire vraie
Le créateur de Pokémon se nomme Satoshi Tajiri. Né en 1965 dans la banlieue de Tokyo, il passa son enfance à capturer des insectes dans les mares et les champs des environs ; il y mettait une telle ardeur que ses camarades le surnommèrent « Docteur Insecte », et il rêvait de devenir entomologiste. Lorsque les terrains de son enfance furent peu à peu recouverts d’immeubles, ce monde disparut.
Devenu passionné de jeux d’arcade, Tajiri fonda avec son ami Ken Sugimori un magazine, puis le studio Game Freak, en 1989. Un jour, en voyant deux consoles Game Boy reliées par un câble, une idée lui vint : et si de petites créatures pouvaient voyager d’une console à l’autre ? Il y retrouvait le plaisir de ses chasses d’autrefois, capturer, collectionner, échanger. Le concept de Pokémon était né.
Soutenu par Nintendo et guidé par son mentor Shigeru Miyamoto, le projet demanda près de six années de travail et faillit ruiner le studio. Le 27 février 1996, les jeux Pokémon Rouge et Pokémon Vert parurent au Japon sur Game Boy. Tout le succès qui suivit découle de cette idée simple, née d’un loisir d’enfant et d’un câble tendu entre deux consoles.
💡 Le savais-tu ?
Dans le jeu, le héros reçoit du professeur Chen un appareil électronique appelé le Pokédex. Le mot mêle « Pokémon » et l’anglais « index » : c’est une encyclopédie de poche. Chaque créature rencontrée y est enregistrée avec son numéro, son nom et une courte description, et compléter le Pokédex (réunir les 151 créatures d’origine) constitue l’un des grands buts du jeu.
Or un Pokédex n’est rien d’autre qu’un répertoire organisé de fiches, autrement dit une base de données. En construisant ton bestiaire avec des listes, tu retrouves la logique même du véritable Pokédex : voilà pourquoi elles sont l’outil idéal pour ce projet.
Les Pokémon de ce projet figurent parmi ces 151 : Bulbizarre y porte le numéro 001, Salamèche le 004, Carapuce le 007 et Pikachu le 025.
Un Pokémon se décrit par trois informations : son nom, son élément et sa force. Pour ne pas réécrire les mêmes lignes d’affichage à chaque fois, nous confions ce travail à une fonction, écrite une fois pour toutes : c’est là le rôle d’une fonction, un outil que l’on fabrique soi-même et que l’on réutilise à volonté.
Rappel : une fonction se déclare avec le mot-clé def, suivi de son nom et de ses paramètres entre parenthèses ; ses instructions viennent en dessous, décalées vers la droite.
def saluer(prenom): print("Bonjour", prenom) print("Bienvenue !") saluer("Léa")
Bonjour Léa Bienvenue !
Pour la force, nous emploierons une donnée réelle : la statistique d’Attaque de base du Pokémon, telle qu’elle figure dans les jeux.
✏️ Exercice 1 : la fiche d’un Pokémon
Ta mission. Écris une fonction afficher_creature(nom, element, force) qui affiche une fiche soignée : le nom, l’élément, la force, puis une ligne de séparation faite de trois tirets. Appelle ensuite ta fonction sur Salamèche, de type Feu, dont l’Attaque de base vaut 52.
Tes outils. La déclaration def, trois paramètres, et quatre appels à print.
Nom : Salamèche Élément: Feu Force : 52 ---
📘 Définition : les listes parallèles
Des listes parallèles sont plusieurs listes de longueur identique, dont les éléments situés à une même position décrivent un seul objet. Le Pokémon numéro i possède le nom noms[i], l’élément elements[i] et la force forces[i]. C’est l’index commun qui relie les trois listes.
Comment ranger plusieurs Pokémon ? Réunir trois informations dans une seule case dépasse ce que nous savons faire : il faudrait des dictionnaires ou des listes de listes, que nous découvrirons plus tard. Nous utilisons donc trois listes de même longueur, une par information. La règle est simple : le Pokémon numéro i se lit à la position i dans chacune des trois listes.
index i | noms[i] | elements[i] | forces[i] |
|---|---|---|---|
| 0 | Bulbizarre | Plante | 49 |
| 1 | Salamèche | Feu | 52 |
| 2 | Carapuce | Eau | 48 |
Lire une ligne du tableau, c’est lire un Pokémon entier. Lire une colonne, c’est lire une seule de ses caractéristiques.
Rappel : pour parcourir deux listes alignées, une boucle sur les positions suffit.
prenoms = ["Léa", "Tom"] ages = [10, 11] for i in range(len(prenoms)): print(prenoms[i], "a", ages[i], "ans")
Léa a 10 ans Tom a 11 ans
range(len(noms)) produit les nombres 0, 1, 2, c’est-à-dire toutes les positions valides de nos listes.✏️ Exercice 2 : ranger le bestiaire
Ta mission. Crée les trois listes parallèles noms, elements et forces, puis range-y ces trois Pokémon : Bulbizarre (Plante, 49), Salamèche (Feu, 52) et Carapuce (Eau, 48). Affiche enfin tout le bestiaire en appelant afficher_creature pour chaque Pokémon.
Tes outils. Trois listes, et une boucle for i in range(len(noms)).
Nom : Bulbizarre Élément: Plante Force : 49 --- Nom : Salamèche Élément: Feu Force : 52 --- Nom : Carapuce Élément: Eau Force : 48 ---
Une collection vivante grandit. Pour ajouter un Pokémon, il faut l’inscrire dans chacune des trois listes, afin que les positions restent alignées. Si l’on oubliait une seule liste, les index ne correspondraient plus et le bestiaire serait décalé.
Rappel : append ajoute un élément à la fin d’une liste, et len compte ses éléments.
fruits = ["pomme", "poire"] fruits.append("cerise") print("Il y a", len(fruits), "fruits.")
Il y a 3 fruits.
✏️ Exercice 3 : capturer Pikachu
Ta mission. Ajoute Pikachu (type Électrik, Attaque de base 55) à ton bestiaire, en l’inscrivant dans les trois listes. Affiche ensuite combien de Pokémon compte désormais ta collection.
Tes outils. append (un par liste) et len.
Le bestiaire contient 4 créatures.
Retrouver un Pokémon se fait en deux temps. D’abord une question simple : ce nom figure-t-il dans le bestiaire ? Le test in y répond par oui ou par non.
Rappel : le test in indique si un élément appartient à une liste.
fruits = ["pomme", "poire", "cerise"] if "poire" in fruits: print("Oui, il y a des poires.")
Oui, il y a des poires.
✏️ Exercice 4 : le moteur de recherche (1 sur 3)
Ta mission. Vérifie si Salamèche se trouve dans le bestiaire, et affiche un message de confirmation le cas échéant.
Tes outils. Le test in et une condition if.
Oui, Salamèche est dans le bestiaire !
Savoir qu’il est présent ne suffit pas : encore faut-il le retrouver pour le montrer. Nous parcourons le bestiaire, position par position, jusqu’à reconnaître le nom cherché ; nous affichons alors sa fiche.
Rappel : pour localiser un élément, on parcourt les positions une à une et l’on compare.
fruits = ["pomme", "poire", "cerise"] for i in range(len(fruits)): if fruits[i] == "poire": print("Trouvée à la position", i)
Trouvée à la position 1
💡 Le savais-tu ?
Ce que tu vas écrire porte un nom chez les informaticiens : une recherche séquentielle. L’ordinateur examine les fiches l’une après l’autre, jusqu’à trouver la bonne ou atteindre la fin de la liste. C’est ainsi que l’on cherche un mot dans un dictionnaire en tournant les pages. Les moteurs de recherche modernes emploient des méthodes bien plus rapides, mais tous reposent, au départ, sur cette idée élémentaire : parcourir et comparer.
✏️ Exercice 4 : le moteur de recherche (2 sur 3)
Ta mission. Demande un nom au joueur avec input. S’il figure dans le bestiaire, affiche sa fiche complète ; sinon, indique que ce Pokémon n’y est pas.
Tes outils. input, le test in, une boucle qui compare noms[i] au nom cherché, et afficher_creature.
Quelle créature cherches-tu ? Salamèche Fiche trouvée : Nom : Salamèche Élément: Feu Force : 52 ---
Quelle créature cherches-tu ? Roucool Roucool n'est pas dans le bestiaire.
Dernière variante, pour le plaisir : afficher tous les Pokémon d’un même type. Le principe ne change pas, mais au lieu de comparer les noms, nous comparons les éléments.
✏️ Exercice 4 : le moteur de recherche (3 sur 3)
Ta mission. Affiche le nom de tous les Pokémon de type Feu présents dans le bestiaire.
Tes outils. Une boucle et une condition portant sur elements[i].
Les créatures de type Feu : - Salamèche
🧠 À retenir
Ce projet t’a fait pratiquer des outils qui te resserviront bien au-delà :
- une fonction (
afficher_creature) qui rassemble un affichage répétitif en un seul outil réutilisable ; - des listes parallèles, reliées par un index commun, pour décrire des objets à plusieurs caractéristiques ;
- la boucle
for i in range(len(...))pour parcourir tout le bestiaire ; appendpour agrandir la collection etlenpour la dénombrer ;- le test
inpour savoir si un élément est présent, et la recherche séquentielle pour le localiser.
Tu disposes désormais d’un vrai petit logiciel de collection. Les mêmes idées servent à gérer une bibliothèque, une liste de contacts ou, justement, un Pokédex.
🚀 Défis bonus
Tu vas vite ? Voici de quoi prolonger le jeu. Essaie d’abord seul ; les corrigés des défis suivent ceux des exercices.
- Le menu interactif. Enferme tes actions dans une boucle
whilequi propose, à chaque tour, d’afficher le bestiaire, d’ajouter un Pokémon, d’en chercher un, ou de quitter. Un jeu deif/elif/elsedirige le programme selon le choix saisi. - Une quatrième caractéristique. Donne à chaque Pokémon une description. Cela demande une quatrième liste parallèle et une ligne de plus dans la fonction d’affichage.
- Le champion du bestiaire. Parcours la liste des forces en retenant la position de la plus grande valeur rencontrée, puis affiche le Pokémon correspondant.
- La force totale. Additionne les forces de tous les Pokémon en accumulant le résultat dans une variable au fil d’une boucle.
✅ Corrigés
Tu as tenté les exercices ? Voici les corrigés, un par un, puis ceux des défis. Compare avec ton code : s’il produit le bon résultat, même écrit autrement, c’est gagné. Mis bout à bout, les corrigés des exercices 1 à 4 forment ton programme complet.
Exercice 1 : la fiche d’un Pokémon
def afficher_creature(nom, element, force): print("Nom :", nom) print("Élément:", element) print("Force :", force) print("---") afficher_creature("Salamèche", "Feu", 52)
Exercice 2 : ranger le bestiaire
noms = ["Bulbizarre", "Salamèche", "Carapuce"] elements = ["Plante", "Feu", "Eau"] forces = [49, 52, 48] for i in range(len(noms)): afficher_creature(noms[i], elements[i], forces[i])
Exercice 3 : capturer Pikachu
noms.append("Pikachu") elements.append("Électrik") forces.append(55) print("Le bestiaire contient", len(noms), "créatures.")
Exercice 4 : le moteur de recherche
La première partie, le test de présence :
recherche = "Salamèche" if recherche in noms: print("Oui,", recherche, "est dans le bestiaire !")
La deuxième partie, la recherche complète avec affichage de la fiche :
recherche = input("Quelle créature cherches-tu ? ") if recherche in noms: for i in range(len(noms)): if noms[i] == recherche: print("Fiche trouvée :") afficher_creature(noms[i], elements[i], forces[i]) else: print(recherche, "n'est pas dans le bestiaire.")
La troisième partie, le filtre par type :
element_cherche = "Feu" print("Les créatures de type", element_cherche, ":") for i in range(len(noms)): if elements[i] == element_cherche: print("-", noms[i])
Défi 1 : le menu interactif
def afficher_creature(nom, element, force): print("Nom :", nom) print("Élément:", element) print("Force :", force) print("---") noms = ["Bulbizarre", "Salamèche", "Carapuce"] elements = ["Plante", "Feu", "Eau"] forces = [49, 52, 48] continuer = True while continuer: print("=== MENU DU BESTIAIRE ===") print("1. Afficher le bestiaire") print("2. Ajouter un Pokémon") print("3. Chercher un Pokémon") print("4. Quitter") choix = input("Ton choix ? ") if choix == "1": for i in range(len(noms)): afficher_creature(noms[i], elements[i], forces[i]) elif choix == "2": nom = input("Nom : ") element = input("Élément : ") force = int(input("Force : ")) noms.append(nom) elements.append(element) forces.append(force) print(nom, "a rejoint le bestiaire !") elif choix == "3": recherche = input("Quel nom ? ") if recherche in noms: for i in range(len(noms)): if noms[i] == recherche: afficher_creature(noms[i], elements[i], forces[i]) else: print(recherche, "n'est pas dans le bestiaire.") elif choix == "4": continuer = False print("À bientôt, dresseur !") else: print("Choix inconnu, réessaie.")
Défi 2 : une quatrième caractéristique
Crée une liste descriptions de même longueur que les autres, ajoute un paramètre description à la fonction d’affichage ainsi qu’une ligne pour l’imprimer, et pense à faire un append sur cette nouvelle liste à chaque Pokémon ajouté.
Défi 3 : le champion du bestiaire
i_max = 0 for i in range(len(forces)): if forces[i] > forces[i_max]: i_max = i print("Le plus fort :", noms[i_max], "avec", forces[i_max], "de force.")
Le plus fort : Pikachu avec 55 de force.
Défi 4 : la force totale
total = 0 for i in range(len(forces)): total = total + forces[i] print("Force totale :", total)
Force totale : 204
📚 Lexique
- Fonction
- bloc de code nommé, créé une seule fois avec
def, que l’on peut ensuite appeler autant qu’on le souhaite. - Paramètre
- information que l’on donne à une fonction au moment de l’appeler, et qu’elle utilise pour faire son travail.
return- mot-clé par lequel une fonction renvoie une valeur. Une fonction sans
returnrenvoieNone. None- valeur spéciale signifiant « absence de résultat ».
- Liste
- suite ordonnée d’éléments, notée entre crochets, dont chaque élément possède une position appelée index.
- Index
- numéro de position d’un élément dans une liste. Le premier élément porte l’index 0.
- Listes parallèles
- plusieurs listes de longueur identique, où les éléments situés au même index décrivent un seul objet.
len- fonction qui renvoie le nombre d’éléments d’une liste.
append- méthode qui ajoute un élément à la fin d’une liste.
in- opérateur qui teste si un élément se trouve dans une liste ; il renvoie
TrueouFalse. - Recherche séquentielle
- méthode qui consiste à examiner les éléments d’une liste l’un après l’autre jusqu’à trouver celui que l’on cherche.
- Base de données
- ensemble d’informations rangées de façon organisée pour pouvoir les retrouver facilement.