Une première version

Une première version minimale d’un jeu d’aventure en mode texte a été créée. Elle est bien sûr infiniment plus simple que Zork. Il y a moins de lieux, pour le moment pas encore d’objets ni de personnages autres que le joueur et très peu d’interactions. Cette première version servira de base à ce qui va suivre, et sera améliorée au fur et à mesure.

GitHub stuff

Le starter code a été récupéré à l’étape précédente. Ouvrir la [REPOSITORY_HOMEPAGE] et démarrer le codespace associé :

Code Codespaces

Astuce

La compréhension et la manipulation de Git sont grandement facilitées par l’extension GitLens de VS Code.

Exécution

Le jeu se lance depuis le terminal:

$ python game.py

Entrez votre nom: Indiana

Bienvenue Indiana dans ce jeu d'aventure !
Entrez 'help' si vous avez besoin d'aide.

Vous êtes dans un marécage sombre et ténébreux. L'eau bouillonne, les abords sont vaseux.

Sorties: N, O

>

Déplacez vous, explorez les différentes possibilités, faites un plan rapide de la map du jeu. Repérez tous les lieux, les directions par lesquelles on y rentre ou on en sort. Explorez tous les passages possibles pour vérifier la cohérence de l’implémentation.

Pour quitter le jeu, il suffit de taper quit.

Avertissement

Les chaines de caractères doivent être renseignées exactement comme elles sont affichées dans le jeu. Les majuscules et les minuscules sont prises en compte. Les espaces sont importants. Les accents aussi.

A titre d’exemple, la réponse à la question Quel est le lieu où se trouve le joueur au démarrage du jeu ?, la réponse doit être un marécage sombre et ténébreux ». Si la description est constituée de deux phrases, on ne retient que la première.

  1. Combien y a t-il de lieux ?

  2. Combien y a t-il de passages entre les différents lieux ?

  3. Quel est le lieu au nord ouest ?

  4. Quel est le lieu au nord est ?

  5. Quel est le lieu au sud est ?

  6. Quel est le lieu au sud ouest ?

  7. On peut aller directement de la grotte au château fort

  8. On peut aller directement de la grotte au chalet

  9. On peut aller directement du marécage au château fort

  10. On peut aller directement du marécage au chalet

Analyse du code de game.py

game.py est le fichier principal du jeu. Observer attentivement le code de ce fichier.

Avertissement

Quelques indications pour les réponses à apporter :

  • Les lignes consécutives doivent être séparées par un tiret. Exemple : 10-15 ;

  • Les lignes non consécutives doivent être séparées par des virgules suivies d’un seul espace. Exemple : 10, 11, 13, 17 ;

  • Les objets doivent être décrits par la chaine de caractères utilisée par la commande type(). Exemple : si la commande type() retourne list, la réponse est list;

  • Les fonctions et les méthodes doivent comporter les parenthèses. Exemple : __init__().

  1. Quelle est la classe principale définie dans ce fichier ?

  2. Combien a t-elle d’attributs ?

  3. Combien a t-elle de méthodes ?

  4. Quel est le constructeur ?

  5. Quelle est la méthode principale ?

  6. A quelle ligne demande t-on le nom du joueur ?

  7. A quelle ligne demande t-on la commande du joueur ?

  8. A quelle ligne traite t-on la commande du joueur ?

  9. A quelle ligne affiche t-on la localisation du joueur au démarrage du jeu ?

  10. Quelle est la première ligne de code exécutée par l’instruction $ python game.py ?

  11. Quelles sont les lignes qui définissent les différents lieux ?

  12. Quel est le type de l’objet qui les regroupe ?

  13. Quelle est le nom de la variable qui permet d’y faire référence dans ce fichier ?

  14. Quelles sont les lignes qui définissent les différents passages entre les lieux ?

  15. A quelle ligne définit on le lieu où est placé le joueur au démarrage du jeu ?

  16. Combien y a t-il de commandes dans cette version du jeu ?

  17. A quelles lignes sont elles définies ?

  18. Quelle est le type de l’objet qui les regroupe ?

  19. Quelle est le nom de la variable qui permet d’y faire référence dans ce fichier ?

  20. Pour la ligne 5, room fait référence au fichier et Room fait référence à la classe .

  21. Pour la ligne 8, actions fait référence au fichier .

  22. est la méthode qui initialise le jeu.

  23. est le type de l’objet qui permet de stocker les instructions que fournit le joueur au moteur du jeu.

  24. Il est transformé en un objet de type par la méthode à la ligne de la méthode .

  25. La vérification que la commande est reconnue par le moteur de jeu ou non est faite à la ligne .

  26. Si la commande n’est pas valide, un message d’erreur est affiché à la ligne .

  27. Si la commande est valide, un élément de la chaine de caractère entrée au clavier par le joueur est transformée en un objet de type à la ligne .

  28. Si la commande est valide, l’action correspondante est déclenchée à la ligne .

  29. La ligne 96 crée une instance de la classe Game.

  30. La ligne 96 crée une référence vers une instance de la classe Game.

  31. La ligne 96 appelle la méthode sur une instance de la classe .

Analyse du code de room.py

La ligne 5 de game.py importe la classe Room du fichier room.py. Observer attentivement le code de ce fichier pour répondre aux questions suivantes.

  1. Quelle est la classe principale définie dans ce fichier ?

  2. Combien a t-elle d’attributs ?

  3. Combien a t-elle de méthodes ?

  4. Quel est le constructeur ?

  5. Quelle est le type de l’objet utilisé pour la description du lieu ? Observer un exemple d’appel au constructeur de cette classe dans le fichier game.py.

  6. Quelle est la variable qui permet d’y faire référence dans ce fichier ?

  7. Quel est le type de l’objet qui regroupe les différentes sorties d’un lieu ?

  8. Quelle est la variable qui permet d’y faire référence ?

  9. Que retourne la méthode get_exit() si la direction passée en paramètre est valide ?

  10. Que retourne la méthode get_exit() si la direction passée en paramètre n’est pas valide ?

  11. Pour la méthode get_exit_string(), quel est le type de la valeur de retour ?

Les f-strings

Pour la méthode Room.get_long_description(), observer la construction de la valeur de retour.

La chaine de caractères est une f-string, pour formatted string. Elle permet de concaténer des chaînes de caractères avec des variables.

Pour concaténer une variable dans une f-string, il suffit de l’entourer de {}. Par exemple, pour concaténer la variable self.description dans une f-string, il suffit d’écrire f"Vous êtes {self.description}".

Si self.description contient la chaine de caractère dans une forêt enchantée, la f-string précédente sera transformée en Vous êtes dans une forêt enchantée.

Note

Pour plus d’informations sur les f-strings, consulter la documentation officielle.

Pour faciliter la compréhension globale du code, on peut utiliser un diagramme de classes.

Pour la classe Room, le diagramme de classes est le suivant :

_images/room.png

Le diagramme est divisé en 3 parties :

  • la première partie représente le nom de la classe ;

  • la deuxième partie expose les attributs et leur type;

  • et la troisième partie expose les méthodes, leurs arguments et le type de la valeur de retour.

Note

Le diagramme de classes est un outil très utile pour comprendre le code. Il permet de visualiser les attributs et les méthodes de chaque classe ainsi que les relations entre les différentes classes.

Analyse du code de player.py

La ligne 6 de game.py importe la classe Player du fichier player.py. Observer attentivement le code de ce fichier.

  1. Quelle est la classe principale définie dans ce fichier ?

  2. Combien a t-elle d’attributs ?

  3. Combien a t-elle de méthodes ?

  4. Quel est le constructeur ?

  5. Quel est le type de l’objet qui stocke le nom du joueur ?

  6. Quelle est la variable qui permet d’y faire référence ?

  7. Quel est le type de l’objet qui stocke le lieu dans lequel se trouve le joueur ?

  8. Quelle est la variable qui permet d’y faire référence ?

  9. Que retourne la méthode move() si le déplacement est valide ?

  10. Que retourne la méthode move() si le déplacement n’est pas valide ?

  11. Quelle est la ligne qui permet de déplacer le joueur dans le lieu de destination ?

Le diagramme de classes de la classe Player est le suivant :

_images/player.png

Il y a une relation d’association entre la classe Player et la classe Room. Cela signifie que la classe Player utilise la classe Room. Cette relation est représentée par une ligne. Ici la cardinalité est représentée par un 1. Cela signifie que la classe Player utilise une seule instance de la classe Room (le joueur ne peut être présent que dans un seul lieu à chaque tour).

Analyse du code de actions.py

La ligne 8 de game.py importe la classe Actions du fichier command.py. Observer attentivement le code de ce fichier.

  1. Quelle est la classe principale définie dans ce fichier ?

  2. Combien a t-elle d’attributs ?

  3. Combien a t-elle de méthodes d’instance ?

  4. Combien a t-elle de méthodes de classe ?

  5. Combien a t-elle de fonctions ?

  6. Y a t-il un constructeur ?

  7. Les fonctions ont elles toutes la même signature ?

  8. Combien ont elles de paramètres ?

  9. De quel type est le premier paramètre ?

  10. De quel type est le deuxième paramètre ?

  11. De quel type est le troisième paramètre ?

  12. De quel type est la valeur de retour ?

Les fonctions de ce fichier sont des fonctions dites de callback. Elles sont associées à la commande correspondante avec l’attribut Command.action() de la classe Command.

  1. Quelle est la fonction de callback associée à la commande help ?

  2. Quelle est la fonction de callback associée à la commande quit ?

  3. Quelle est la fonction de callback associée à la commande go ?

Les fonctions de callback ont en argument un objet de type Game et ont donc accès à tous les attributs et toutes les méthodes de cette classe. Pour ces fonctions…

  1. Quelle est la variable qui permet d’accéder à la salle courante ?

  2. Quelle est la variable qui permet d’accéder au nom de la salle courante ?

  3. Quelle est la variable qui permet d’accéder à la description de la salle courante ?

  4. Quelle est la variable qui permet d’accéder aux sorties de la salle courante ?

Le diagramme de classes de la classe Actions est le suivant :

_images/actions.png

Cette classe est particulière puisqu’elle ne possède ni attributs ni méthodes, uniquement des fonctions. C’est une classe de fonctions. Elle est utilisée pour regrouper les fonctions de callback associées aux commandes. Cela permet de les organiser dans un même fichier.

Analyse du code de command.py

La ligne 7 de game.py importe la classe Command du fichier command.py. Observer attentivement le code de ce fichier.

  1. Quelle est la classe principale définie dans ce fichier ?

  2. Combien a t-elle d’attributs ?

  3. Combien a t-elle de méthodes ?

  4. Quel est le constructeur ?

  5. Quel est le type de l’objet qui stocke le nom de la commande ?

  6. Quelle est la variable qui permet d’y faire référence ?

  7. Quel est le type de l’objet qui stocke l’information de ce que fait la commande ?

  8. Quelle est la variable qui permet d’y faire référence ?

  9. Quel est le type de l’objet qui stocke l’action déclenchée par la commande ?

  10. Quelle est la variable qui permet d’y faire référence ?

  11. Quel est le type de l’objet qui stocke le nombre de paramètres que nécessite par la commande ?

  12. Quelle est la variable qui permet d’y faire référence ?

La docstring

Cette classe possède une docstring. Elle est très utile pour documenter le code. Elle est accessible via la fonction help de Python.

Par convention une docstring de classe est structurée en plusieurs parties :

  • une première ligne qui décrit la classe ;

  • une ligne vide ;

  • une description plus détaillée de la classe (optionnel) ;

  • une ligne vide (optionnel) ;

  • une liste des attributs de la classe ;

  • une ligne vide ;

  • une liste des méthodes de la classe ;

  • une ligne vide ;

  • une liste des exceptions levées par la classe (optionnel) ;

  • une ligne vide ;

  • des exemples d’utilisation sous forme de doctest.

Note

Pour plus d’informations sur les docstrings, consulter la documentation officielle.

Le diagramme de classes de la classe Command est le suivant :

_images/command.png

Une seule fonction de callback (de la classe Actions) est associée à une commande. Cette fonction est appelée lorsque l’utilisateur tape la commande correspondante dans la console.

Exercices

Docstrings

Compléter la docstring des classes Room et Player en utilisant la convention décrite ci-dessus.

Diagramme de classe

Dessiner le diagramme de classe de la classe Game.

Passage interdit

Apporter les modifications nécessaires pour que le passage entre la forêt et la tour en pierre ne soit pas possible. Vérifiez que les déplacements possibles sont conformes à la nouvelle carte.

Sens unique

Apporter les modifications nécessaires pour que l’on puisse aller du marécage vers la tour en pierre, mais pas l’inverse. Vérifiez que les déplacements possibles sont conformes à la nouvelle carte.

Commande vide

Actuellement la commande vide est traitée comme une commande inconnue. Lorsque le joueur appuie sur Entrée à l’invite de commande, le jeu affiche un message d’erreur:

>

Commande '' non reconnue. Entrez 'help' pour voir la liste des commandes disponibles.

>

Il serait plus judicieux de ne rien afficher:

>
>
>

Modifier le code en conséquence.

Amélioration de la description du lieu

Actuellement, la description de chaque lieu telle qu’initialisée dans la classe Game (lignes 33, 35, 37, 39, 41 et 43) contient le mot « dans ». Il serait plus judicieux de factoriser ce mot en l’incluant plutôt au moment de la fabrication de la chaine de description.

Ainsi, ligne 35 dans la classe Game, la description de la tour serait « une immense tour en pierre qui s’élève au dessus des nuages. » » et non « dans une immense tour en pierre qui s’élève au dessus des nuages. ». Modifier la construction des 6 lieux en conséquence.

Cependant, on souhaite conserver le même affichage dans le terminal. Il faut donc modifier la fabrication de la chaine de description. Dans quelle classe est-elle effectuée ? A quelle ligne ? Modifier le code de cette classe en conséquence et vérifier le bon fonctionnement du jeu.

GitHub stuff

Enregistrer les modifications apportées aux fichiers dans le repo local au codespace

$ git add .
$ git commit -m "Une première version"

Pour référencer plus facilement cette version dans le futur, créer un tag

$ git tag v1

Synchroniser votre codespace avec votre dépôt GitHub

$ git push

Vérifier que les modifications sont bien présentes dans le dépôt GitHub.