Aller au contenu

POO : TD Lemmings⚓︎

Introduction du jeu⚓︎

Col

Lemmings {.center}

Col

Lemmings {.center}

Lemmings est un jeu vidéo de réflexion développé par le studio écossais DMA Design (aujourd'hui Rockstar North) et édité par Psygnosis en 1991.

Le joueur doit guider des dizaines de lemmings, minuscules créatures écervelées, dans des niveaux alambiqués truffés de dangers mortels. Le jeu est fondé sur le mythe populaire selon lequel les lemmings, petits rongeurs bien réels des régions arctiques, se livreraient au suicide collectif en se jetant des falaises.

Jouer \(\,\) Cliquez ici pour jouer !

Dans ce jeu, les lemmings marchent dans une grotte représentée par une grille à deux dimensions dont chaque case est soit un mur soit un espace vide, un espace vide pouvant contenir au maximum un lemming à un instant donné. Les lemmings apparaissent les uns après les autres à une position de départ, et disparaissent lorsqu'ils atteignent une case de sortie.

Chaque lemming possède les propriétés suivantes :

  • Sa position, donnée par deux coordonnées, désignant la case dans laquelle il se trouve.
  • La direction dans laquelle il se déplace (gauche ou droite).

Les lemmings se déplacent à tour de rôle, toujours dans l'ordre correspondant à leur introduction dans le jeu, de la manière suivante :

  • si l'espace immédiatement en-dessous est libre, le lemming tombe d'une case ;
  • sinon, si l'espace immédiatement devant est libre (dans la direction du lemming concerné), le lemming avance d'une case ;
  • enfin, si aucune de ces deux conditions n'est vérifiée, le lemming se retourne.

On propose, pour réaliser un petit programme permettant de voir évoluer une colonie de lemmings,

  • une structure avec une classe Lemming pour les lemmings,
  • une classe Case pour les cases de la grotte, et
  • une classe principale Jeu pour les données globales.

Définition des classes⚓︎

Définition des Classes

Classe Jeu⚓︎

La casse principale Jeu contient :

  • un attribut grille contenant un tableau de cases (instances de Case) à deux dimensions , et
  • un attribut lemmings contenant la liste (au sens Python) des Lemmings actuellement en jeu.

Son constructeur initialise la grille, par exemple à partir d'une carte donnée par un fichier texte d'un format inspiré du suivant, où le caractère :

  • # représente un mur,
  • I représente l'entrée et
  • O représente la sortie

#I###############
#               #
#####  ##########
#         #     #
#   #######     #
#               O
######  #########
     #  #        
     ####        

Cette classe Jeu fournit notamment (mais pas uniquement !) les méthodes suivantes :

  • afficher(self) affiche la carte avec les positions et directions de tous les lemmings en jeu ;
  • tour(self) fait « agir » chaque lemming une fois et affiche le nouvel état du jeu ;
    dans cette méthode, il faut « regarder » ce qui se trouve autour de chaque lemming (mur, trou, ...) afin de le faire agir en conséquence ...
  • demarrer(self) lance une boucle infinie attendant des commandes de l'utilisateur.

Exemples de commandes :

  • « + » pour ajouter un lemming,
  • « q » pour quitter le jeu,....

Classe Lemming⚓︎

Une classe Lemming contenant des attributs :

  • des attributs entiers positifs l et c indiquant la position (ligne et colonne) où se trouve le lemming dans la grille, et
  • un attribut d indiquant sa direction, valant :
    • 1 si le lemming se dirige vers la droite, et
    • -1 si le lemming se dirige vers la gauche.

Cette classe Lemming fournit en outre les méthodes suivantes :

  • __str__(self) renvoie le caractère '>' ou '<' selon la direction du lemming ;
  • avancer(self) déplace le lemming, dans la bonne direction, droite ou gauche (selon la direction dans laquelle il se trouve – changement de colonne) ;
  • retourner(self) retourne le lemming (changement de direction) ;
  • tomber(self) fait tomber le lemming (changement de ligne);
  • ...

Warning

ATTENTION : le lemming ne regarde pas où il va : ce n'est pas lui qui décide quoi faire s'il y a un mur en face, un autre lemming, un trou, ... Tout ceci est géré par la méthode tour du jeu.

Classe Case⚓︎

La classe Case contient un attribut terrain contenant le caractère représentant la caractéristique de la case (mur, vide, sortie, entrée ... comme dans le fichier texte décrivant la grotte), et un attribut lemming contenant l'éventuel lemming présent dans cette case et None si la case est libre.

Cette classe fournit notamment les méthodes suivantes :

  • __str__(self) renvoie le caractère à afficher pour représenter cette case ou son éventuel occupant ;
  • estLibre(self) renvoie True si la case est peut recevoir un lemming (elle n'est ni un mur, ni occupée par un lemming) ;
  • liberer(self) retire le lemming présent dans la case ;
  • occuper(self, lem) place le lemming lem sur la case ;
  • ...

Déroulement du jeu⚓︎

  • La méthode Jeu.demarrer lance une boucle infinie, dont une issue passe par l'appui sur la touche "q" (« quitter ») du clavier.
  • Le rythme du jeu est donné par une constante de classe Jeu.PERIODE.
  • Le calcul des positions des lemmings, suivi de l'affichage du jeu a lieu chaque Jeu.PERIODE secondes.

A chaque « tour », les lemmings font un mouvement (avancer, tomber ou se retourner), dans l'ordre de leur entrée dans le jeu. Lorsque l'un d'entre eux atteint la sortie, il quitte le jeu (on pourra par exemple à cette occasion incrémenter un attribut score du jeu)

Si l'utilisateur appui sur la touche « + », un nouveau lemming rentre dans le jeu.

Ressources possibles⚓︎

Gestion des touches du clavier⚓︎

On peut utiliser la classe GestionnaireEvenement qui utilise la bibliothèque pynput, décrite sur cet article.  

Gestion des tableaux⚓︎

On peut stocker les tableaux de jeux dans un fichier .txt .
Pour ouvrir et lire ce fichier, rien de tel que le module os et la structure with ... as ... .  

Amélioration de l'affichage⚓︎

Avec des caractères plus complets⚓︎

█ pour les murs

.....

Avec des couleurs⚓︎

Plusieurs méthodes :

class bcolors: 
    VIOLET = '\033[95m'
    BLEU = '\033[94m'
    CYAN = '\033[96m'
    VERT = '\033[92m'
    JAUNE = '\033[93m'
    ROUGE = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

print(f"Voici un {bcolors.ROUGE}texte{bcolors.ENDC} {bcolors.BOLD}avec{bcolors.ENDC} des {bcolors.BLEU}couleurs{bcolors.ENDC}")

Remarque

Cette syntaxe ne fonctionne qu'avec certains terminaux (fonctionne avec Vscode, ou dans un Terminal Linux, par exemple bash et/ou zsh, mais pas avec l'IDLE de Python, ni avec Pyzo)

Ou bien utiliser une bibliothèque, comme termcolor.

Avec des cases de plusieurs caractères⚓︎

...

Travail à Faire⚓︎

Implémenter une classe⚓︎

Implémenter une classe pour gérer l'interface utilisateur

Un Exemple en animation⚓︎

Lemmings Animés, dans un Terminal

Cette base peut ensuite évidemment être étendue avec des terrains plus variés, de nouvelles possibilités d'interaction pour le joueur, des objectifs en termes de nombre de lemmings sauvés, etc...

Références⚓︎