Activité pratique
Durée2h30Consignes globales
Cette activité pratique a pour but de vous préparer au projet PyRat. Elle consiste en trois grandes parties :
- Vous allez installer le logiciel.
- Vous allez mettre en place un dépôt Git, afin de travailler efficacement en groupe.
- Enfin, 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éances via le serveur Discord du cours. Vous devriez dès à présent le rejoindre si ça n’est pas déjà fait.
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 classes et fonctions fournies par la bibliothèque. Nous y avons également ajouté quelques tutoriels, qui constituent la base de cette activité pratique.
Important
Comme pour la plupart des logiciels que vous rencontrerez dans votre vie, le code et la documentation de PyRat sont rédigés 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 du paquet
pyrat-game, c’est-à-dire la bibliothèque PyRat telle qu’elle sera téléchargée et installée dans votre workspace. -
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. PyRat automatise une grande partie de l’installation via uv.
À faire
Ouvrez un terminal dans le dossier où vous voulez créer les fichiers du projet (ne créez pas de projet via uv pour l’instant). Un bon emplacement serait dans un dossier IMT/S5/info/projet par exemple (adaptez selon ce que vous avez déjà).
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.
Vérifier que uv est installé
À faire
En utilisant le terminal ouvert précédemment, vérifiez que uv est bien installé sur votre machine. Si ça n’est pas le cas, installez-le.
Télécharger et installer PyRat
PyRat s’installe facilement grâce à uvx, un outil fourni avec uv qui permet d’exécuter des programmes distribués via PyPI, sans avoir besoin de créer un environnement virtuel au préalable.
À faire
Trouvez la page décrivant l’installation dans la documentation de PyRat, et suivez les instructions.
La commande d’installation devrait créer un dossier pyrat_workspace, contenant vos dossiers players et games.
Ce pyrat_workspace est un projet uv muni d’un environnement virtuel (.venv) dans lequel la bibliothèque pyrat-game est installée.
Lors de son installation, PyRat configure également le PATH de l’environnement virtuel pour que les programmes des dossiers players et games soient trouvés par l’interpréteur python. Ainsi, les scripts qui lancent les parties (dans games) peuvent importer les classes des joueurs (dans players) via from players.random1 import Random1.
Vérifier l’installation de PyRat
Une fois PyRat installé, démarrez VSCode, et ouvrez le dossier pyrat_workspace (celui qui contient pyproject.toml).
Via l’arborescence à gauche, ouvrez le fichier games/sample_game.py, et exécutez le. Vous devriez constater que VSCode utilise bien l’environnement virtuel du projet, et que la partie se lance.
Information
Vous pouvez aussi lancer une partie sans passer par VSCode : placez-vous dans le dossier pyrat_workspace avec un terminal, et lancez uv run games/sample_game.py.
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.
À ce stade, chacun(e) d’entre vous a installé PyRat sur sa propre machine et a son propre pyrat_workspace qui fonctionne. À présent, nous allons créer un projet collaboratif, via un dépôt Git sur le GitLab de l’école.
On suppose que vous avez déjà toutes et tous un compte sur ce GitLab, et que vous y avez déposé une clé SSH, comme demandé à l’issue de la séance sur le travail à plusieurs avec Git et GitLab.
Information
Si votre clé n’est pas encore en place, ne bloquez pas la séance là-dessus : prenez l’URL de clonage en HTTPS, qui ne demande que vos identifiants GitLab, et posez votre clé après le cours en suivant la fiche GitLab. Vous pousserez sur ce dépôt jusqu’à la fin du semestre.
Nous allons à présent créer un dépôt Git sur lequel vous pourrez travailler à plusieurs. Bonne nouvelle : votre workspace est déjà dans un dépôt Git, car uv en a créé un au moment de l’installation. Il contient également un fichier .gitignore, fourni par PyRat, qui exclut d’office les fichiers qui ne doivent pas être versionnés, comme l’environnement virtuel .venv, les dossiers temporaires __pycache__, ou les fichiers créés par votre éditeur et votre système d’exploitation.
Vérifiez tout de même qu’un dossier .git existe bien à la racine de pyrat_workspace (par exemple en lançant git status depuis ce dossier). Si ce n’est pas le cas, par exemple parce que votre dossier projet est lui-même déjà dans un dépôt Git, lancez d’abord git init dans pyrat_workspace.
À faire
Choisissez l’un(e) d’entre vous, appelons cette personne le/la “Boss” le temps de cette section, puis suivez les instructions ci-dessous.
Créer le projet
Qui ? Le/La boss seulement.
Sur https://gitlab-df.imt-atlantique.fr, créez un projet privé du nom de votre choix. Pensez à décocher la case “Initialize repository with a README”.

Copiez ensuite le lien de clonage du projet (en SSH ou en HTTPS). Il vous sera demandé à l’étape suivante.

Publier le workspace
Qui ? Le/La boss seulement.
Placez-vous dans votre dossier pyrat_workspace avec un terminal, puis effectuez les commandes suivantes (remplacer url_de_clonage_du_projet par le lien copié à l’étape précédente) :
Rechargez la page du projet sur GitLab : vos fichiers doivent y être. Vérifiez au passage que le dossier .venv n’y est pas, mais que pyproject.toml et uv.lock y sont bien.
Inviter les autres membres et l’enseignant(e)
Qui ? Le/La boss seulement.
Cliquez sur “Members” dans le menu, puis ajoutez les autres membres du groupe et l’enseignant(e) avec le rôle Maintainer.

Récupérer le dépôt
Qui ? Les autres membres du groupe.
Supprimez le dossier pyrat_workspace que vous aviez créé à l’installation. Puis, depuis le dossier projet (ou autre, selon ce que vous avez choisi), clonez celui du groupe (cela créera un dossier du nom de votre projet, nom_du_depot dans les commandes ci-dessous) et préparez-le :
Le dépôt que vous venez de cloner ne contient pas d’environnement virtuel (car il n’était pas sur GitLab grâce au .gitignore). uv sync le crée sur la vôtre, tel que décrit par pyproject.toml et uv.lock, et y installe les dépendances du projet (ici, notamment pyrat-game, ainsi que votre workspace lui-même).
Vérifier que tout marche
Qui ? Tout le monde.
Depuis votre dossier nom_du_depot, lancez :
Une partie de PyRat doit se lancer. Si c’est le cas, votre workspace est correctement installé et connecté au dépôt du groupe.
Ouvrez également le menu Source control de VSCode : votre dépôt Git doit être détecté, et VSCode vous propose de gérer vos add, commit, push et pull directement via son interface.

Information
Pendant tout le projet, quelques commandes suffiront la plupart du temps :
VS Code permet de faire ces commandes via son interface graphique, notamment via le menu Source Control.
Un premier exemple de travail collaboratif
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.
Par défaut, le README de votre projet contient des informations de base sur ce qu’est un workspace PyRat. Nous allons y ajouter la liste du groupe pour l’exemple.
À 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.
Compléter le README
Qui ? Le/la Big Boss seulement.
Le/la Big Boss ajoute les noms de ses coéquipiers dans le fichier README.md, par exemple dans une nouvelle section Students au début de celui-ci :
Il/elle s’arrange pour que le fichier README.md modifié apparaisse sur le dépôt.
Récupérer le fichier modifié
Qui ? Les autres membres du groupe.
Le but est de manipuler Git (via l’interface VSCode ou la ligne de commande) pour que chaque étudiant(e) du groupe ait une vue locale à jour du dépôt dans son workspace.
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, jetez un oeil aux liens suivants.
À faire
Parcourez le lien de découverte de PyRat, ainsi que le premier des tutoriels (sur les programms RandomX). Pas besoin d’étudier les tutoriels suivants pour le moment, l’important est de repérer les ressources utiles pour plus tard.
-
Découverte de PyRat : Ce lien présente PyRat dans les grandes lignes, à savoir le contenu de votre workspace et de la bibliothèque Python
pyrat-game, les éléments 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 votre 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’une classe héritant de
Player. On stockera les fichiers décrivant les joueurs dans le dossierplayers. - Un script, qui lance une partie avec votre joueur. On stockera les fichiers décrivant les scripts dans le dossier
games.
Description de la stratégie
Le programme que nous allons écrire (Random5) est une amélioration de Random4, décrit dans le tutoriel sur les programmes RandomX.
En bref, Random4 est un programme qui :
- Au début de la partie, raye les culs de sac de la carte pour ne pas s’y diriger.
- Puis, à chaque tour de jeu :
- Détermine les cases adjacentes au personnage qui n’ont pas encore été visitées dans la partie. Il en choisit une aléatoirement, et s’y déplace.
- Si toutes les cases adjacentes ont déjà été visitées, le personnage choisit une case adjacente au hasard, et s’y déplace.
L’un des problèmes de Random4 est que, si le rat arrive dans une zone du labyrinthe où il a visité toutes les cases voisines, sa stratégie pour en sortir n’est pas optimisée. En effet, le rat choisit une case adjacente au hasard, et s’y déplace, en espérant atteindre une case du labyrinthe voisine de cases pas encore visitées pour améliorer le tour suivant.
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.
Inspirez-vous des fichiers existants dans le dossier games, ainsi que du tutoriel sur la personnalisation des parties.
-
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.
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 compte 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.
Vous devriez observer quelque chose comme ça :
À 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.
Information utile : vous pouvez fixer la position de départ du joueur et du fromage. Consultez la doc !
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 ?