Introduction

Les jeux vidéo en mode texte

Un jeu vidéo en mode texte (text-based game en anglais) est un jeu vidéo sur écran dans lequel le joueur est plongé dans un univers fictif et doit résoudre des énigmes pour progresser dans l’histoire. Le joueur interagit avec le jeu en tapant des commandes dans un terminal. Le jeu répond en affichant du texte. Le jeu est donc très proche d’un jeu de rôle papier, mais avec un ordinateur pour gérer les règles et l’univers. Le jeu n’utilise pas de graphisme, mais uniquement des phrases (texte, des questions et des réponses).

Le jeu d’aventure textuel est un jeu très ancien, qui a connu son heure de gloire dans les années 80. Il est aujourd’hui un peu tombé en désuétude, mais il reste un excellent exercice de programmation. Il est aussi très facile à mettre en oeuvre, car il ne nécessite pas de graphisme, ni de son, ni de réseau, ni de base de données, ni de moteur physique, ni de moteur de rendu, etc. Il ne nécessite qu’un terminal et un langage de programmation. Il est donc idéal pour un premier projet de programmation.

Pour avancer dans un jeu textuel, le joueur est invité à entrer des actions (se baisser pour ramasser une clé, examiner un tronc d’arbre, marcher vers le sud, tuer un monstre, etc.) en fonction du contexte et lieu où il se trouve. Ce lieu est décrit par le programme (vous vous trouvez devant le porche de la maison, vous êtes dans la forêt face à un orc, etc…) . De multiples autres critères entrent parfois en compte (vie, arme, état du personnage, etc.).

Les jeux textuels sont souvent des jeux de rôle, mais il existe aussi des jeux de stratégie, de gestion, de simulation, etc.

Un exemple : Zork

Zork I: The Great Underground Empire est un jeu vidéo d’aventure textuel développé à l’origine en 1977 par un groupe d’étudiants du MIT, connu sous le nom de « Dynamic Modeling Group ». Il est considéré comme l’un des jeux les plus emblématiques de l’histoire des jeux vidéo et a contribué à populariser le genre des jeux d’aventure textuels.

Dans Zork I, le joueur incarne un aventurier qui explore les profondeurs d’un empire souterrain, où il doit résoudre des énigmes, trouver des trésors et vaincre des ennemis pour progresser. Le jeu se déroule entièrement par le biais de descriptions textuelles et de commandes tapées au clavier. Le joueur doit utiliser son imagination et sa logique pour résoudre les énigmes et progresser dans l’aventure.

Le jeu a connu un grand succès dans les années 1980 et a inspiré de nombreux autres jeux d’aventure textuels ainsi que des adaptations pour d’autres supports, tels que des romans et des bandes dessinées.

_images/zork.jpg

On peut y jouer en ligne ici.

Voici quelques pas dans le jeu

West of House
You are standing in an open field west of a white house, with a boarded front door.
There is a small mailbox here.

>open mailbox
Opening the small mailbox reveals a leaflet.

>read leaflet
(Taken)
"WELCOME TO ZORK!
ZORK is a game of adventure, danger, and low cunning. In it you will explore some of the most amazing territory ever seen by mortals. No computer should be without one!"

>drop leaflet
Dropped.

>go south
South of House
You are facing the south side of a white house. There is no door here, and all the windows are boarded.

>go east
Behind House
You are behind the white house. A path leads into the forest to the east. In one corner of the house there is a small window which is slightly ajar.

>open window
With great effort, you open the window far enough to allow entry.

>enter house

Kitchen
You are in the kitchen of the white house. A table seems to have been used recently for the preparation of food. A passage leads to the west and a dark staircase can be seen leading upward. A dark chimney leads down and to the east is a small window which is open.
On the table is an elongated brown sack, smelling of hot peppers.
A bottle is sitting on the table.
The glass bottle contains:
A quantity of water

La solution complète

_images/zork_map.png

Objectifs

L’objectif est de créer un jeu vidéo en mode texte (beaucoup plus modeste que Zork !), en utilisant le langage Python.

Une première partie du travail consiste à définir l’univers du jeu : le lieu où se déroule l’action, les personnages, les objets, etc. Une fois l’univers défini, il faut définir les règles du jeu : comment le joueur interagit avec l’univers, comment l’univers réagit aux actions du joueur, etc. Enfin, il faut écrire le code qui implémente ces règles.

Dans sa première version, la communication entre le joueur et la machine se fera uniquement en mode texte dans un terminal.

Comme il est assez facile de le porter dans un environnement graphique, dans une seconde version, les élèves les plus avancés pourront le porter vers une interface graphique améliorera la jouabilité.

Organisation

Le mini projet est réalisé en binôme, dont la constitution est libre. Les étudiants n’ont pas besoin d’appartenir au même groupe pédagogique. Il est demandé de remplir ce questionnaire pour renseigner :

  • les membres du binôme ;

  • le contexte du jeu ;

  • l’URL du repo git (cf ci dessous).

Environnement de travail du projet

Le projet s’effectue dans un environnement GitHub / Codespaces. Pour rappel, GitHub est un service en ligne qui permet d’héberger des projets de développement logiciel. Codespaces est un service de développement en ligne qui permet de développer des applications directement dans le navigateur. Il est basé sur Visual Studio Code et permet de travailler sur des projets GitHub sans avoir à installer quoi que ce soit sur sa machine.

Pour ce qui va suivre, on considère que le binome est constitué des deux élèves Alice et Bob qui auront respectivement le rôle de :

  • propriétaire du projet ;

  • et de collaborateur du projet.

Important

Il faut décider dès à présent qui va jouer le rôle de Alice et qui va jouer le rôle de Bob. Ces rôles sont définitifs et ne peuvent pas être changés en cours de projet.

Créer l’environnement

L’environnement est créé une seule fois pour toutes, par le propriétaire du projet, ici Alice.

Une fois le projet créé, Bob sera ajouté par Alice comme collaborateur et pourra contribuer de la même manière au projet. Voici les étapes à suivre :

  • Alice se connecte à son compte GitHub

  • Alice crée un nouveau repo : https://github.com/new avec les paramètres suivants :

    • Repository name : TBA

    • Public

    • Add a README file

    • Create repository

Après création, le repo est visible à l’adresse https://github.com/Alice/TBA. Puisqu’il est public, il est visible par Bob mais il ne peut pas y contribuer pour l’instant.

Ajouter des collaborateurs

Pour un travail en binome efficace, il faut que chacun des membres puisse ajouter/modifier/supprimer des fichiers. C’est automatiquement le cas pour Alice qui est propriétaire du repo.

Pour que Bob puisse contribuer au projet, Alice doit l’inviter explicitement à partir de l’adresse https://github.com/Alice/TBA/settings/access en lui donnant le rôle de Collaborator.

Associer un codespace

Depuis la page d’accueil du repo (https://github.com/Alice/TBA), Alice et Bob doivent chacun démarrer leur propre codespace (il n’est pas possible de partager un codespace).

Code Codespaces Create codespace on main

Avertissement

Une fois créé, le codespace est accessible à une adresse du type https://[STRANGE_CODESPACE_NAME].github.dev/. Les codespaces de Alice et de Bob sont indépendants et n’ont donc pas la même adresse.

Les codespaces sont associés au compte Github. Il n’est donc pas possible pour Alice d’accéder au codespace de Bob et vice versa (une erreur 404 est générée)

La seule façon de partager du code entre Alice et Bob est de passer par le repo. Il est important :

  • de bien se répartir le travail pour éviter les conflits ;

  • de synchroniser régulièrement le repo avec les codespaces.

Les codespaces sont gérés sur la page https://github.com/codespaces. Il faut veiller à stopper ou à supprimer les codespaces inutilisés pour ne pas consommer des ressources inutilement.

Le workflow

Le repo est le référentiel du projet. A ce titre, il doit être régulièrement synchronisé avec chacun des codespaces. Alice et Bob devront suivre la démarche suivante :

  • synchronisation descendante à partir du repo : git pull

  • modification/ajout/suppression de fichiers

  • ajout à l’index : git add .

  • insertion dans l’historique : git commit -m "message explicatif"

  • synchronisation montante avec le repo : git push

Pour une organisation optimale, il sera pratique de ne pas travailler sur les mêmes fichiers. La structuration en modules/classes permet ça.

Etape initiale

Au démarrage, le repo et les codespaces sont synchronisés comme l’indique la figure ci dessous. 1e14 est le commit initial et ne contient que le fichier README.md.

_images/workflow-00.drawio.png

Pour Alice, dans le terminal du codespace

Alice $ git log --format="%h"
1e14

Même chose pour Bob

Bob $ git log --format="%h"
1e14

Alice ajoute du code

Alice ajoute du code dans son codespace.

Puis elle ajoute ces fichiers à l’index, et crée le commit. Dans le terminal du codespace

Alice $ git add .
Alice $ git commit -m "Ajout de code"
Alice $ git log --format="%h"
78de
1e14
_images/workflow-01.drawio.png

A présent, le codespace de Alice est en avance sur le repo

Alice $ git status

# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

Alice synchronise son codespace avec le repo

Pour maintenir le repo à jour avec ses dernières modifications, Alice doit synchroniser son codespace avec le repo. Elle pousse son commit 78de

Alice $ git push
_images/workflow-02.drawio.png

Le repo est à jour mais pas le codespace de Bob

Alice $ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Bob récupère les modifications d’Alice

Bob récupère les modifications d’Alice en synchronisant son codespace avec le repo. Il tire le commit 78de

Bob $ git pull
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From https://github.com/Alice/TBA
   1e14..78de  master -> origin/master
Updating 1e14..78de
Fast-forward
file1.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
_images/workflow-03.drawio.png

Le codespace de Bob est synchronisé avec le repo

Bob $ git status
On branch master
Your branch is up to date with 'origin/master'.
$ git log --format="%h"
78de
1e14

Bob ajoute du code

Il peut se trouver une situation dans laquelle Bob travaille de son côté, et crée le commit e094

Bob $ git add .
Bob $ git commit -m "Ajout d'autre code"
Bob $ git log --format="%h"
   e094
   1e14
_images/workflow-04.drawio.png

Lorsque Bob veut synchroniser son codespace avec le repo, il va se produire une erreur puisqu’il ne dispose pas du commit 78de:

Bob $ git push
To github.com:Alice/TBA
! [rejected]        master -> master (fetch first)
error: impossible de pousser des références vers 'github.com:Alice/TBA'
astuce: Les mises à jour ont été rejetées car la branche distante contient du travail que
astuce: vous n'avez pas en local. Ceci est généralement causé par un autre dépôt poussé
astuce: vers la même référence. Vous pourriez intégrer d'abord les changements distants
astuce: (par exemple 'git pull ...') avant de pousser à nouveau.
astuce: Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus d'information.

Si les modifications de Bob ne sont pas en conflit avec celles d’Alice, il peut tirer les modifications d’Alice, ajouter ses fichiers à l’index, créer le commit et pousser les modifications

Bob $ git pull
Bob $ git add .
Bob $ git commit -m "Ajout d'autre code"
Bob $ git log --format="%h"
   e094
   78de
   1e14
_images/workflow-05.drawio.png

Bob peut synchroniser son codespace avec le repo

Bob $ git push
_images/workflow-06.drawio.png

Le repo est à jour et Alice peut récupérer les modifications de Bob

Bob $ git pull
_images/workflow-07.drawio.png

Résolution de conflit

Il peut y avoir une situation pour laquelle Bob a effectué des modifications contradictoires avec le repo, par exemple modifié le même fichier qu’Alice. Dans ce cas, il y a un conflit et lorsque Bob tire les modifications d’Alice, il obtient un message d’erreur

Bob $ git pull
! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/yourusername/yourrepo'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g. 'git pull')
hint: before pushing again.

Bob doit résoudre le conflit en éditant le fichier conflictuel. Il doit supprimer les marqueurs de conflit et choisir les modifications à conserver. Une fois le conflit résolu, il ajoute le fichier à l’index, crée un commit de résolution de conflit qui fait l’interface entre 78de et e094

Bob $ git add .
Bob $ git commit -m "Résolution du conflit"
Bob $ git log --format="%h"
   e094
   4a82
   78de
   1e14
_images/workflow-08.drawio.png

Bob peut alors synchroniser son codespace avec le repo et il sera possible à Alice de récupérer les modifications apportées par Bob

Bob $ git push

Remise du travail

Les instructions et la date limite de remise du travail sont précisées sur la page d’accueil de l’unité.

La remise du travail s’effectue sous la forme de la remise d’une archive zip sur la plateforme Blackboard.

L’archive devra contenir les seuls fichiers strictement nécessaires pour exécuter le code (et uniquement ceux là) ;

  • un fichier principal main.py qui permet de lancer le jeu avec la commande $ python main.py;

  • les autres fichiers .py nécessaires au fonctionnement du jeu ;

  • un rapport au format pdf structuré de la façon suivante :

    • guide utilisateur (comment jouer à votre jeu : les conditions de victoire, les commandes, etc.) ;

    • guide développeur (le diagramme de classes) ;

    • perspectives de développement (ce que vous imaginez pour améliorer votre jeu) ;

  • une vidéo de démonstration de votre jeu (3 minutes max, OBS Studio est une solution open source performante). La vidéo doit contenir :

    • présentation de l’univers du jeu (carte, personnages, objets, etc.) ;

    • démonstration d’un parcours perdant ;

    • démonstration d’un parcours gagnant.

Evaluation

Votre code doit pouvoir être exécuté sur une machine différente de la machine utilisée pour le développement. Il est fondamental d’avoir ce contexte en tête. En particulier toute référence absolue à un fichier est proscrite.

Il sera impératif de vérifier que votre projet se dézippe et marche correctement sur une machine différente de celle utilisée pour la conception avant de le soumettre.

Le projet sera évalué sur la base des critères suivants :

  • sur 2 points : la fonctionnalité du code

    • 0 : il y a une erreur à l’exécution ;

    • 1 : une erreur se produit parfois ;

    • 2 : le code fonctionne.

  • sur 5 points : le score pylint (comme vu dans le chapitre Qualité du code). A travers ce score sont évalués : la structuration, les commentaires, le nommage, etc. ;

  • sur 5 points : la qualité du jeu (jouabilité, intérêt, etc.) ;

    • 1 : le travail est trop loin des attentes ;

    • 2 : il y a quelques améliorations à apporter ;

    • 3 : le travail correspond à ce qui est attendu ;

    • 4 : le travail est supérieur à ce qui est attendu ;

    • 5 : le travail est exceptionnel.

  • sur 4 points : la qualité du rapport. Il doit satisfaire les critères énoncés dans la section Remise du travail ;

    • 1 : le travail est trop loin des attentes ;

    • 2 : il y a quelques améliorations à apporter ;

    • 3 : le travail correspond à ce qui est attendu ;

    • 4 : le travail est supérieur à ce qui est attendu ;

  • sur 4 points : la qualité de la vidéo de présentation. Elle doit satisfaire les critères énoncés dans la section Remise du travail ;

    • 1 : le travail est trop loin des attentes ;

    • 2 : il y a quelques améliorations à apporter ;

    • 3 : le travail correspond à ce qui est attendu ;

    • 4 : le travail est supérieur à ce qui est attendu ;