Activité pratique
Durée2h30Consignes globales
Cette activité pratique a pour but de vous préparer au projet PyRat. Elle consiste en deux grandes parties :
-
Vous allez installer le logiciel et écrire votre premier programme pour vous déplacer dans le labyrinthe. Vous allez également mettre en place un dépôt Git, afin de travailler efficacement en groupe.
-
Puis, vous serez guidé(e)s dans l’écriture de votre premier programme PyRat.
Cette mise en place peut être assez longue, mais elle est essentielle pour bien attaquer le projet. Si vous ne parvenez pas à tout faire dans la séance, terminez en dehors avant la prochaine.
N’oubliez pas que nous pouvons vous aider entre les séance via le serveur Discord du cours. Vous devriez dès à présent le rejoindre si ça n’est pas déjà fait.
Important
Pensez à bien suivre les étapes décrites sur cette page dans l’ordre, en particulier pour l’installation de PyRat et la mise en place du dépôt Git. Il y a parfois des petits détails importants qui, si vous lisez en diagonale, peuvent vous faire perdre beaucoup de temps.
À faire
Vous trouverez plus bas des boîtes “À faire” indiquant les étapes où vous devez agir.
Contenu de l’activité
Où trouver PyRat ?
Le plus important à connaître est le site principal du logiciel PyRat, qui centralise tous les éléments de prise en main :
-
Documentation : Cette page regroupe les éléments de documentation sur comment installer et utiliser PyRat. La documentation présente aussi l’API PyRat, c’est à dire les fonctions fournies par la bibliothèque. Nous y avons également ajouté quelques tutoriels, qui constitueront la base de cette activité pratique.
Information
Comme pour la plupart des logiciels que vous rencontrerez dans votre vie, la documentation de PyRat est rédigée en anglais. Si vous passez par des outils de traduction automatique, il peut arriver d’observer des petites différences avec les termes utilisés dans le cours. N’hésitez pas à en discuter avec nous.
Important
Autre remarque, le code de PyRat est également rédigé en anglais. Dans ce projet, nous vous demandons de produire vos codes, commentaires et documentations en anglais également. C’est une pratique essentielle dans le métier d’ingénieur(e), où vous serez amené(e)s à travailler dans des contextes internationaux.
Voici également quelques liens secondaires, qui pourront vous être utiles plus tard :
-
PyPI : La page de référence pour l’installation de PyRat via
pip. -
GitHub : Ce dépôt GitHub contient les codes sources du logiciel PyRat. Quand nous travaillons à une nouvelle version du logiciel, c’est là que nos modifications sont publiées.
-
GitHub issues : Les issues GitHub sont une sorte de forum, où sont discutés les possibles problèmes rencontrés par les utilisateurs lors de l’installation ou l’utilisation du logiciel. C’est une bonne pratique de consulter cette page si vous rencontrez des difficultés.
Préparer l’environnement du projet
Dans cette section, nous allons préparer l’environnement de travail pour le projet PyRat. Pour cela, nous allons créer l’arborescence de dossiers suivante.
À faire
Créez un dossier projet vide là où vous stockez vos fichiers de cours d’informatique. Puis, ouvrez un terminal et naviguez jusqu’à ce dossier.
Dans ce projet, nous allons travailler avec l’IDE VSCode. Vous pouvez en utiliser un autre si vous préférez, il vous suffira d’adapter les instructions.
Créer un environnement virtuel Python
Afin de faciliter la séparation des dépendances d’un projet à l’autre, Python impose de passer par un environnement virtuel pour l’installation de bibliothèques logicielles. Nous allons installer PyRat dans un tel environnement.
À faire
En utilisant le terminal ouvert précédemment, créez un environnement virtuel Python dans le dossier projet (par exemple nommé venv_projet). Puis, activez cet environnement virtuel.
Télécharger et installer PyRat
À présent, nous allons installer la bibliothèque PyRat dans l’environnement virtuel venv_projet activé précédemment.
À faire
Trouvez la page décrivant l’installation dans la documentation de PyRat, et suivez les instructions.
Quelques remarques importantes :
- Pensez à bien activer l’environnement virtuel
venv_projetavant d’installer PyRat. - L’installation de PyRat ne s’arrête pas au
pip install pyrat-game, il faut aussi créer le workspace PyRat. La commande correspondante est indiquée dans le guide d’installation. - Le workspace PyRat doit être créé dans le dossier
projet, à côté devenv_projet(pas dedans). - La commande qui crée le dossier
pyrat_workspaceajoute automatiquement ce dossier dans la variable d’environnementPATHde votre système. Cela permet aux codes Python que vous écrirez de s’importer facilement entre eux. Si vous déplacez ou renommez le dossierpyrat_workspaceaprès sa création, vous devrez réparer cette variable d’environnement, comme expliqué dans cette issue.
Une fois PyRat installé, démarrez VSCode, et ouvrez le dossier projet (celui qui contient venv_projet et pyrat_workspace). Via l’arborescence à gauche, ouvrez le fichier games/sample_game.py.
Comme venv_projet apparaît dans les dossiers ouverts, VSCode détectera votre environnement virtuel, et vous proposera de l’utiliser automatiquement, comme indiqué par la flèche dans la capture d’écran ci-dessous. S’il ne le fait pas, cliquez sur le numéro de version Python au bout de la flèche en bas à droite, et choisissez l’environnement virtuel venv_projet.
Préparer le travail en groupe
Avant de démarrer cette activité pratique, vous avez dû former un trinôme. Si ça n’est pas le cas, faites le maintenant, et informez votre enseignant(e) de sa composition.
On suppose également que vous avez déjà toutes et tous créé un compte sur Gitlab ou Github, et créé une clé SSH. Si ça n’est pas le cas, revoilà le lien de la page sur le travail collaboratif avec Git vue en environnement.
Mise en place du dépôt Git
À présent, nous allons faire en sorte que vous puissiez synchroniser votre dossier pyrat_workspace entre vous.
Avant de commencer, assurez -vous que chaque membre du groupe supprime un éventuel dossier __pycache__ dans pyrat_workspace/players. Ce dossier est créé automatiquement par Python pour stocker des fichiers temporaires, mais il ne doit pas être versionné avec Git.
À faire
Une fois votre trinôme constitué, choisissez l’un(e) d’entre vous (appelons cette personne “Boss” le temps de cette section pour vous motiver à prendre ce rôle :) ), puis suivez les instructions ci-dessous.
-
Le/la boss crée un projet Git nommé
pyrat_workspace(privé, sansREADME.md(décochez la case)), via Gitlab ou Github.Important
Attention à bien nommer le projet
pyrat_workspace. Si vous l’appelez autrement (par exemplemon_workspace), les autres étudiant(e)s du groupe risquent de créer un dossiermon_workspaceau lieu depyrat_workspacelors du clonage, ce qui empêchera les imports Python de fonctionner correctement. -
Le/la boss initialise ce dépôt grâce aux commandes suivantes :
-
Le/la boss invite les autres étudiant(e)s du groupe comme collaborateurs du projet via l’interface de Gitlab ou Github.
Information
C’est fini pour le boss (jusqu’à l’étape 5) ! Passons aux autres étudiant(e)s du groupe.
-
Chaque étudiant(e) non-boss supprime le dossier
pyrat_workspacecréé par PyRat pendant l’installation. Puis, chacun(e) clone le dépôt au même endroit avec les commandes suivante :Cette commande devrait créer un nouveau dossier
pyrat_workspacelà où se trouvait celui que vous avez supprimé.Important
Attention à ce que ce nouveau dossier soit bien au même endroit et s’appelle bien
pyrat_workspace. La raison est que ce chemin a été ajouté dans lePATHpar PyRat, ce qui permettra à vos codes Python de s’importer facilement.Information
C’est tout pour les non-boss ! Les instructions restantes concernent tout le monde.
-
Vérifiez que vous avez bien le bon
pyrat_workspacedans votre workspace VSCode. Pour vous en rendre compte, cliquez sur le menu Source control à gauche. Vous devriez voir que VSCode a automatiquement détecté votre dépôt Git, et vous propose de gérer vosadd,commit,push, etc. directement via son interface. -
Vérifiez que PyRat marche bien. Démarrez le script
sample_game.pydans le dossierpyrat_workspace/gameset exécutez le. Vous devriez voir une partie de PyRat se lancer, comme précédemment.
Ajout d’un fichier README.md
Dans tout projet informatique, il est important d’avoir un petit fichier qui explique succinctement (ou pas) à quoi sert le projet. On appelle ce fichier un “README”, et on y trouve généralement les adresses de contact des auteur(e)s, les instructions d’utilisation du projet, etc.
Sur les dépôts Git, ce fichier s’appelle classiquement README.md, car on rédige son contenu en Markdown, un langage permettant de formater du texte. Si vous avez déjà utilisé des outils comme Discord, (ou Mattermost, Slack, etc.), c’est généralement ce langage qui est utilisé pour mettre du texte en gras, italique, etc.
À faire
Choisissez l’un(e) d’entre vous qui n’était pas le/la Boss, et appelons cet(te) étudiant(e) “Big Boss” (le temps de cette section, ne prenez pas la grosse tête tout de suite). Puis, suivez les instructions ci-dessous.
-
Le/la Big Boss crée un fichier
README.mddans son workspace PyRat, comme indiqué plus haut. -
Une fois le fichier créé, le/la Big Boss y copie-colle le texte suivant (changez les éléments entre
<...>par le bon contenu), et sauvegarde le fichier.
À présent, votre objectif est de manipuler Git (via l’interface VSCode ou la ligne de commande) pour que :
- Le fichier
README.mdapparaisse sur le dépôt. - Chaque étudiant(e) du groupe ait une vue locale à jour du dépôt dans son workspace.
Ajout d’un fichier .gitignore
Quand on réalise un projet avec Git, il faut uniquement versionner les fichiers intéressants (le code, la documentation, éventuellement certaines données, etc.), mais pas les fichiers qui permettent l’exécution du projet (environnement virtuel, fichiers temporaires, etc.).
Pour cela, on peut mettre à la racine du dépôt un fichier nommé .gitignore, dans lequel on liste tous les fichiers et dossiers à ignorer par Git.
À faire
L’étudiant(e) qui n’a pas encore dirigé le groupe devient le/la Méga Boss. Puis, suivez les instructions ci-dessous.
-
Le/la Méga Boss télécharge ce fichier
.gitignorestandard pour Python, le place dans son dossierpyrat_workspace, comme indiqué plus haut, puis le renomme en.gitignore. -
Puis, en vous inspirant de ce que vous avez fait pour le fichier
README.mdplus haut, arrangez vous pour que :- Le fichier
.gitignoreapparaisse sur le dépôt. - Chaque étudiant(e) du groupe ait une vue locale à jour du dépôt dans son workspace.
- Le fichier
C’est parti !
Se familiariser avec PyRat
A ce stade, tout est prêt pour commencer le projet ! Découvrons à présent en quoi consiste le logiciel PyRat. Avant d’attaquer la création de programmes PyRat, étudiez les liens suivants :
-
Découverte de PyRat : Ce lien présente PyRat dans les grandes lignes, à savoir le contenu de
pyrat_workspaceet de la bibliothèque Pythonpyrat-game, les élements de jeu, etc. -
Tutoriels de base : Sur cette page, nous vous proposons quelques tutoriels à suivre, qui détaillent les programmes PyRat fournis par défaut dans le
pyrat_workspace, et vous expliquent comment customiser les éléments de jeu.
Votre premier programme PyRat
L’objectif de cette activité pratique est d’écrire vos premiers codes PyRat, c’est à dire :
- Un joueur, sous la forme d’un fichier héritant de la classe
Player, décrit dans un fichier du dossierpyrat_workspace/players. - Un script, qui lance une partie avec votre joueur, décrit dans un fichier du dossier
pyrat_workspace/games.
Description de la stratégie
Le programme que nous allons écrire est une amélioration de Random4, décrit dans le tutoriel sur les programmes RandomX.
L’un des problèmes de Random4 (que Random3 avait déjà) est que, si le rat arrive dans une zone du labyrinthe où il a visité toutes les cases voisines, il tente de rejoindre une case non visitée en se déplaçant aléatoirement. À partir de là, le rat reprend sa stratégie d’exploration.
On pourrait améliorer cet aspect du programme en gardant en mémoire notre trajectoire, c’est à dire la suite de cases parcourues jusqu’au tour en cours. Ainsi, en arrivant sur une case dont on a déjà visité toutes les cases voisines, il suffirait de revenir en arrière le long de la trajectoire parcourue. Si on arrive sur une case dont on a déjà visité tous les voisins, on recommence, etc. À un moment, à force de revenir sur ses pas, le rat finira par arriver sur une case ayant au moins une case voisine inexplorée, et pourra reprendre sa quête de fromage.
Création du joueur
À faire
Faites une copie du fichier Random4.py (dans le dossier players), et renommez le nouveau fichier Random5.py (dans le même dossier). Faites toutes les modifications nécessaires pour que ce nouveau fichier décrive une classe nommée Random5.
Ne vous préoccupez pas du comportement du joueur pour le moment, on cherche juste à créer un programme utilisable qui ne crashe pas.
Création de la partie
À faire
Créez un fichier visualize_random5.py dans le dossier games de votre pyrat_workspace. Ce fichier doit effectuer les opérations détaillées ci-dessous.
-
Importer la classe
Random5que vous venez de créer. -
Créer une partie de PyRat (une instance de la classe
Game), contenant 1 morceau de fromage. Pensez aussi à mettre une valeur élevée à l’argumenttrace_lengthpour vérifier plus tard que le rat revient bien sur ses traces. -
Instancier un joueur de la classe
Random5, et l’ajouter à la partie. -
Démarrer la partie.
Information
Inspirez vous des tutoriels PyRat, ainsi que des exemples donnés par défaut dans pyrat_workspace/games.
Implémentez la stratégie
À faire
Maintenant que vous avez un script visualize_random5.py qui lance une partie de PyRat avec le joueur Random5, adaptez le code de Random5.py pour que le rat suive la stratégie décrite plus haut.
N’hésitez pas à lancer régulièrement votre script visualize_random5.py, par exemple pour afficher la trajectoire parcourue, ou pour vérifier que votre code ne crashe pas.
Vous devriez obtenir un rat qui se comporte comme suit. En particulier, il ne devrait pas aller dans des culs de sac (amélioration apportée par Random4), et devrait revenir sur ses pas quand toutes les cases voisines sont déjà visitées.
Évaluez la stratégie
Maintenant que vous avez une nouvelle stratégie, il faut se poser la question de si elle est vraiment efficace. Pour cela, une approche possible est de la comparer à d’autres méthodes.
À faire
Adaptez le script evaluate_random_players.py fourni à la fin du tutoriel pour ajouter votre joueur Random5 aux quatre autres.
Quelles conclusions tirez-vous ? Discutez-en avec votre enseignant(e) !
Pour aller plus loin
Le joueur Random6
Description de la stratégie
Quand Random5 arrive à un croisement amenant à plusieurs cases voisines non visitées, le rat choisit une case aléatoirement parmi celles-ci et s’y dirige.
Imaginons le cas trivial où il n’y a aucun mur, on se dit alors que les directions se rapprochant le plus du fromage (à vol d’oiseau) sont les plus intéressantes. Comme en PyRat on bouge sur une grille, mieux vaut aller vers le nord ou l’est si le fromage est au nord-est. Une stratégie intéressante serait alors de trier les cases voisines non visitées par ordre croissant de distance au fromage, et de privilégier la première.
À faire
Quel est l’impact du nombre de murs sur cette stratégie et son intérêt par rapport à une orientation aléatoire ?
Implémentez et évaluez la stratégie
À faire
En vous inspirant de ce que vous avez fait pour Random5, créez un joueur Random6 (et un script dans games pour le tester), qui implémente la stratégie guidée par l’emplacement du fromage.
Vous devriez observer quelque chose comme ça :
À faire
Puis, complétez le script evaluate_random_players.py pour ajouter votre joueur Random6 aux cinq autres. Un avis sur les résultats observés ?
Les cas limites
On se posait précédemment la question de si le nombre de murs pouvait poser problème.
À faire
Faites varier ce nombre pour évaluer la densité au delà de laquelle Random6 n’est pas significativement meilleur que Random5. Le plus efficace est de créer un script dans le dossier games pour tester ça dans une boucle qui augmente progressivement la densité de murs.
On avait déjà parlé de significativité dans le tutoriel, n’hésitez pas à relire cette partie.
Remarques
Si vous avez suivi toutes les étapes, vous devriez vous rendre compte que votre programme ne comporte plus d’aléatoire du tout !
À faire
Pensez à faire un peu de ménage dans les dépendances de votre fichier Random6.py (qui est du coup assez mal nommé) en enlevant import random.
Une autre remarque est que la distance Euclidéenne utilisée pour trier les voisins non visités ne prend pas en compre la topologie du labyrinthe, ni la boue. Cela s’observe dans la vidéo plus haut, où on voit bien que la portion de chemin 82 -> 95 -> 94 aurait été plus courte que 82 -> 81 -> 94. Il faudra donc passer à des stratégies plus intelligentes pour trouver des chemins plus courts.
Pour aller encore plus loin
Le joueur Random7
La plupart du temps, le fromage va se trouver en diagonale par rapport au rat (par exemple au nord-ouest). Conceptuellement, dans un labyrinthe sans murs, ça ne change pas grand chose d’aller au nord puis à l’ouest, ou d’aller à l’ouest puis au nord. La boue dans le labyrinthe change toutefois cette équivalence. C’est un phénomène que nous avons décrit dans les remarques sur Random6 plus haut.
On pourrait donc améliorer Random6 comme suit : si deux actions réduisent la distance au fromage, on privilégie celle qui amène à la case suivante en un minimum de tours.
À faire
Comme précédemment, créez un joueur Random7 qui implémente cette stratégie, ainsi qu’un script pour lancer une partie avec.
À faire
Puis, complétez le script evaluate_random_players.py pour l’ajouter aux autres. Est-ce que cet ajout améliore significativement les performances moyennes par rapport à Random6 ?
Suivre le mur
On dit parfois que quand on est perdu dans un labyrinthe, il suffit de poser une main sur un mur, et d’avancer sans jamais décoller sa main. On teste ?
À faire
Prenez quelques minutes pour essayer d’imaginer les cas où cette stratégie peut fonctionner, pour partir d’une case et arriver au morceau de fromage.
Une fois que vous avez identifié ce qui marche, créez un script dans games pour créer ce contexte, puis créez un joueur pour réaliser cette stratégie.
Factoriser tout ça
Maintenant que vous avez codé 7 programmes aléatoires, vous devez vous apercevoir qu’il y a un certain nombre de redondances dans vos codes. En particulier, la fonction remove_dead_ends(...) introduite à partir de Random4 apparaît probablement dans tous les fichiers développés par la suite, vu que ce pré-traitement est relativement indépendant de la stratégie de déplacement.
Maintenant, imaginons que vous découvriez une erreur dans le code de cette fonction. Pour la corriger, il va falloir fouiller dans tous vos fichiers pour changer toutes les copies de remove_dead_ends(...). C’est problématique, car vous allez perdre du temps, et peut-être introduire de nouvelles erreurs sans faire exprès…
À faire
Prenez un moment pour réfléchir aux contenus de vos programmes aléatoires. Comment pourriez-vous exploiter le paradigme orienté objet pour mieux organiser tout ça ? Est-ce que votre nouvelle organisation permet également de factoriser des éléments développés pour le programme qui suit le mur ?

