Tetris
![]()
Tetris est un jeu vidéo de puzzle conçu par Alekseï Pajitnov à partir de juin 1984.
![]()
Tetris met le joueur au défi de réaliser des lignes complètes en déplaçant des pièces de formes différentes, les tétrominos, qui défilent depuis le haut jusqu’au bas de l’écran. Les lignes complétées disparaissent tout en rapportant des points et le joueur peut de nouveau remplir les cases libérées.
Le jeu n’a pas de fin : le joueur perd la partie lorsqu’un tétromino reste bloqué en haut. Il doit donc résister le plus longtemps à la chute continue des tétrominos, afin de réaliser le meilleur score.
Source : https://fr.wikipedia.org/wiki/Tetris
ensemble des tétrominos du jeu Tetris
Travail demandé
Objectif : réaliser un jeu de Tetris complètement jouable, dans un environnement en mode texte (TUI – Text User Interface) :

Diagramme de classe
Procéder par petites étapes … en réalisant des tests fréquents …
#################################################################################################
# Jeu de TETRIS
# Module principal
#################################################################################################
from tetromino import *
from ui_handler import *
from grille import *
import time
# Dimensions
W, H = 10, 20
# Durées
DELAI = 1.0 # période de descente des tetrominos (en secondes)
PERIODE = 20 # période de l'accélération (en nombre de Tetrominos posés)
DELAI_LIGNE = 0.2 # Durée de suppression de ligne
COEF_ACCEL = 0.8 # Coefficient d'accélération du jeu (c'est à dire de réduction du délai)
class Tetris:
def __init__(self):
...
# Le gestionnaire des événements clavier
self.__ui_handler = UI_handler(self)
def run(self):
""" Boucle principale du jeu de Tetris :
(se termine quand game_over est vrai)
- descenre le tetromino "courant" (s'il existe !)
- rafraichir l'affichage
- gérer le rythme (méthode gerer_temps)
- attendre "delai"
"""
while ...:
...
def __enter__(self):
self.__ui_handler.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.__ui_handler.stop()
def get_score(self):
...
def get_grille(self):
...
def get_tetro(self):
...
def gerer_temps(self):
""" Mise à jour des attributs liés au temps (à chaque cycle):
chrono : incrémentation à chaque période (DELAI)
delai : réduction (*COEFF_ACCEL) toute les PERIODE cycles (pour accélérer le jeu)
"""
...
def descendre_tetro(self):
""" Descend le Tetromino d'une ligne vers le bas
si ce n'est pas possible,
le Tetromino est remonté puis posé
"""
...
def lacher_tetro(self):
""" Descend le Tetromino jusqu'en bas
et pose le Tetromino
"""
...
def decaler_tetro(self, sens):
""" Décale latéralement le Tetromino courant
d'une distance égale à sens
(si impossible, re-décale dans l'autre sens)
"""
...
def tourner_tetro(self):
""" Tourne le Tetromino courant
(si impossible, décale pour que ça passe)
"""
...
def ajouter_tetro(self):
""" Instancie un nouveau Tetromino
et le place en haut de la grille (si possible)
"""
...
def poser_tetro(self):
""" Pose le Tetromino lorsqu'il ne peut plus descendre
et lancement de la vérification de lignes
"""
...
def on_key_press(self, key):
""" Méthode appelée quand une touche est pressée
(voir UI_handler.py)
"""
if key == ESC: # arrêt du jeu
...
return False
...
def afficher(self):
""" Affiche le jeu :
score
grille
"""
...
#################################################################################################
# Exécution du jeu dans un "context manager"
# (car utilisation d'un thread dans user_input)
with Tetris() as tetris:
tetris.run()
#################################################################################################
# Jeu de TETRIS
# Module tetrominos : gestion des tetrominos
#################################################################################################
from random import randint
from displayer import *
#################################################################################################
# Tous les schémas de tetrominos
# coordonnées relatives des
TETROS = [[(0,-1), (0,0), (1,0), (1,1)],
...
]
# couleurs
COULS = [...] # indices de couleur (voir display.py)
# caractères utilisé
CHAR = '█' # Tetronimo
CHAR_SUPP = '░' # Tetronimo avant suppression de ligne
#################################################################################################
class Tetromino:
def __init__(self, ...):
...
def __str__(self):
...
def get_pos(self):
""" Retourne la position (l,c)
du Tetromino
"""
...
def set_pos(self, ...):
...
def get_all_pos(self):
""" Renvoie les positions (l,c)
de tous les éléments du Tetromino
--> [(..., ...),(..., ...),(..., ...),(..., ...)]
coordonnées de chaque élément du Tetromino
dans le repère de la grille !
"""
...
def est_dans_case(self, l, c):
""" Renvoie True si la case (l,c) de la grille
contient un élément du Tetromino
"""
...
def descendre(self):
...
def monter(self):
...
def decaler(self, sens):
""" Décale la position (colonne) du tetromino
sens == 1 : vers la droite
sens == -1 : vers la gauche
Si impossible (voir méthode Grille.est_possible), alors ne pas décaler
"""
...
def tourner(self):
""" Modifie en place le schéma du tetromino
pour qu'il rempésente un tétromino tourné de 90°
Ne renvoie rien
"""
...
def get_random_tetro():
""" Instancie et retourne un nouveau tetromino
choisi aléatoirement parmi les TETROS
"""
...
#################################################################################################
if __name__ == "__main__":
t = Tetromino(0)
print(t)
#################################################################################################
# Jeu de TETRIS
# Module grille : gestion de la grille principale
#################################################################################################
from displayer import *
from tetromino import *
class Grille:
def __init__(self, ...):
...
def __str__(self):
...
def est_possible(self):
""" Renvoie True si le Tetromino "courant"
peut être placé sur la grille
Il faut vérifier que le tetromino "courant" du jeu (chacun de ses éléments)
peut trouver une place sur la grille.
Il faut vérifier pour chacun des éléments du tetromino "courant" :
- si la case de la grille est libre
- s'il n'est pas en dehors de la grille
"""
...
def poser_tetro(self):
""" Inclus le Tetromino à la grille
Le tetromino courant du jeu est "transformé"
en chaines de caractères dans les cases de la grille
"""
...
def verif_lignes(self):
""" Vérifie la présence de lignes complètes
et renvoie les numéros des lignes supprimées
"""
...
def previder_ligne(self, ...):
""" Prévide la ligne d'indice l
avant suppression
(remplace les caractères)
"""
...
def supprimer_ligne(self, ...):
""" Supprime la ligne d'indice l
et en rajoute une vide en haut
"""
...
#################################################################################################
if __name__ == "__main__":
g = Grille()
print(g)
#################################################################################################
# Jeu de TETRIS
# Module user_input : gestionnaire d'événements clavier
# (voir https://info.blaisepascal.fr/pynput/)
#################################################################################################
from pynput import keyboard
# Codes des touches utilisées
ESC = 10
ENTER = 20
SPACE = 0
LEFT = 1
RIGHT = 2
DOWN = 3
class UI_handler:
def __init__(self, ...):
...
def start(self):
...
def stop(self):
...
def on_key_press(self, key):
""" Méthode appelée quand une touche est pressée
--> propage l'information au jeu de tetris
"""
if key == keyboard.Key.esc: # arrêt du jeu
self.__tetris.on_key_press(ESC)
...
#################################################################################################
if __name__ == "__main__":
ui = UI_handler()
ui.stop()
#################################################################################################
# Jeu de TETRIS
# Module display : gestionnaire d'affichage
# (voir https://info.blaisepascal.fr/afficher-dans-le-terminal/)
#################################################################################################
# Couleurs
COULS =['\033[91m', # ROUGE
'\033[92m', # VERT
'\033[93m', # JAUNE
'\033[94m', # BLEU
'\033[95m', # VIOLET
'\033[96m', # CYAN
'\033[97m', # GRIS
]
ENDC = '\033[00m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
HIDE = '\033[?25l'
SHOW = '\033[?25h'
HOME = '\033[H'
DEL_END = '\033[0J'
DEL_ALL = '\033[2J'
class Displayer:
def __init__(self, tetris):
...
def afficher(self):
...
def colorize(s, c):
""" Retourne une représentation en couleur c
de la chaîne s
"""
...
#################################################################################################
if __name__ == "__main__":
d = Displayer()

