Principe tetris en python 2?me version

Description

Vous trouverez dans cette archive:

TetrisPythonPrincipe2 : explication détaillée du principe du jeu Tetris via
l'utilisation d'une matrice dans un contexte graphique simple (ici Tkinter).
Principe normalement portable dans tous les langages.

Tetris2.0e : adaptation du principe de base dans une version jeu plus finalisée.

Source / Exemple :


 
################################################################################
# #
# Principe du tétris en python #
# #
################################################################################
# #
# coordCourante [0,3] #
# | #
# [[0,0,0,*,0,0,0,0,0,0], [[0,1,0,0], [[1,1,1,1], #
# [0,0,0,0,0,0,0,0,0,0], [0,1,0,0], [0,0,0,0], #
# [0,0,0,0,0,0,0,0,0,0], [0,1,0,0], [0,0,0,0], #
# [0,0,0,0,0,0,0,0,0,0], [0,1,0,0]] [0,0,0,0]] #
# [0,0,0,0,0,0,0,0,0,0], piece piece #
# [0,0,0,0,0,0,0,0,0,0], (position 1) (position 2) #
# [0,0,0,0,0,0,0,0,0,0], 1/ On initialise la coordonnée courante de #
# [0,0,0,0,0,0,0,0,0,0], déplacement et on choisi une pièce. #
# [0,0,0,0,0,0,0,0,0,0], 2/ On appel la méthode chargée de descendre #
# [0,0,0,0,0,0,0,0,0,0], la pièce ligne par ligne à une vitesse donnée. #
# [0,0,0,0,0,0,0,0,0,0], 3/ Avant chaque déplacement on vérifie par #
# [0,0,0,0,0,0,0,0,0,0], anticipation si la pièce ne débordera pas ou #
# [0,0,0,0,0,0,0,0,0,0], si on tente de la placer sur une pièce déjà #
# [0,0,0,0,0,0,0,0,0,0], présente. #
# [0,0,0,0,0,0,0,0,0,0], 4/ Si le mouvement est possible on incrémente le #
# [0,0,0,0,0,0,0,0,0,0], membre de la coordonnée concerné, on efface la#
# [0,0,0,0,0,0,0,0,0,0], pièce de l'écran, et on la redessine à sa #
# [0,0,0,0,0,0,0,0,0,0], nouvelle coordonnée. #
# [0,0,0,0,0,0,0,0,0,0], 6/ Si le déplacement n'est plus possible en #
# [0,0,0,0,0,0,0,0,0,0]] descente on imprime la pièce dans la matrice #
# matriceJeu et on vérifie si une ou plusieurs ligne se #
# sont formées. #
# 7/ Retour en 1/ #
# #
################################################################################

from Tkinter import *
from random import randrange
from time import clock

#-------------------------------------------------------------------------------
def initialisation():
""" Création de la matrice de jeu 'matriceJeu' 20 lignes 10 colonnes.
Création du canvas de dessin 'airDessin'.
Définition des pièces et de leurs positions."""
global tabCouleurs,matriceJeu,airDessin,tabCarresPiece,tabPieces,partieTerminee

tabCouleurs = [0,'LimeGreen','dark green','red','blue','DarkOrange','SteelBlue','deepskyblue','wheat','LightGoldenrodYellow']

matriceJeu = []
for i in range(20):
matriceJeu.append([0]*10)

fenetreJeu = Frame(fen)
fenetreJeu.pack()

airDessin = Canvas(fenetreJeu,bg='black',height=400,width=200)
airDessin.pack()

tabCarresPiece = [] #<- tableau contenant les ID des objets Tk rectangle sur l'air de dessin(pour pouvoir les effacer)

#----- Définition des pièces -----------------------------------------
piece1 =[[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],#<-1ere orientation-> O
[[0,0,0,0],[0,0,1,1],[0,1,1,0],[0,0,0,0]],#2eme O O
[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],#3eme O
[[0,0,0,0],[0,0,1,1],[0,1,1,0],[0,0,0,0]]]#4eme

piece2 = [[[0,0,2,0],[0,2,2,0],[0,2,0,0],[0,0,0,0]], # O
[[0,0,0,0],[0,2,2,0],[0,0,2,2],[0,0,0,0]], # O O
[[0,0,2,0],[0,2,2,0],[0,2,0,0],[0,0,0,0]], # O
[[0,0,0,0],[0,2,2,0],[0,0,2,2],[0,0,0,0]]]

piece3 = [[[0,3,0,0],[0,3,0,0],[0,3,0,0],[0,3,0,0]], # O
[[3,3,3,3],[0,0,0,0],[0,0,0,0],[0,0,0,0]], # O
[[0,3,0,0],[0,3,0,0],[0,3,0,0],[0,3,0,0]], # O
[[3,3,3,3],[0,0,0,0],[0,0,0,0],[0,0,0,0]]] # O

piece4 = [[[0,4,4,0],[0,4,4,0],[0,0,0,0],[0,0,0,0]], # O O
[[0,4,4,0],[0,4,4,0],[0,0,0,0],[0,0,0,0]], # O O
[[0,4,4,0],[0,4,4,0],[0,0,0,0],[0,0,0,0]],
[[0,4,4,0],[0,4,4,0],[0,0,0,0],[0,0,0,0]]]

piece5 = [[[0,5,0,0],[0,5,5,0],[0,5,0,0],[0,0,0,0]], # O
[[0,0,0,0],[0,0,5,0],[0,5,5,5],[0,0,0,0]], # O O
[[0,0,0,5],[0,0,5,5],[0,0,0,5],[0,0,0,0]], # O
[[0,5,5,5],[0,0,5,0],[0,0,0,0],[0,0,0,0]]]

piece6 = [[[0,0,6,0],[0,0,6,0],[0,6,6,0],[0,0,0,0]], # O
[[0,0,0,0],[0,6,6,6],[0,0,0,6],[0,0,0,0]], # O
[[0,6,6,0],[0,6,0,0],[0,6,0,0],[0,0,0,0]], # O O
[[0,0,0,0],[0,6,0,0],[0,6,6,6],[0,0,0,0]]]

piece7 = [[[0,7,0,0],[0,7,0,0],[0,7,7,0],[0,0,0,0]], # O
[[0,0,0,0],[0,0,0,7],[0,7,7,7],[0,0,0,0]], # O
[[0,7,7,0],[0,0,7,0],[0,0,7,0],[0,0,0,0]], # O O
[[0,0,0,0],[0,7,7,7],[0,7,0,0],[0,0,0,0]]]

tabPieces =(piece1,piece2,piece3,piece4,piece5,piece6,piece7)

partieTerminee = False
print "Tappez 'q' pour quitter"

nouvelle_piece()

#-------------------------------------------------------------------------------
def nouvelle_piece():
""" Choix d'une nouvelle pièce au hazard, réinitialisation de sa coordonnée
matricielle de départ et de son sens."""
global coordCourante,sens,vitesse,pieceCourante,partieTerminee,tempsInit,pause

coordCourante = [0,3]
sens = 0
vitesse = 1

index = randrange(0,len(tabPieces))
pieceCourante = tabPieces[index]

if not verif_deplacement(0,0,0): #<- si la pièce ne peut être posée à sa position actuelle
partieTerminee = True #<- la partie est terminée
dessine_piece() #<- on la dessine quand même
print "Perdu"
else:
dessine_piece() #<- sinon on la dessine
tempsInit = clock() #<- on mémorise le temps initial de son déplacement (cf:cycle())
pause = False
cycle() #<- on fait partir le cycle de descente

#-------------------------------------------------------------------------------
def cycle():
"""Méthode qui compare le temps initial de la nouvelle position d'une pièce
avec le temps présent et ce à une fréquence donnée."""
global tempsPresent,pause

if not partieTerminee:
tempsPresent = clock()
# lorsque la différence des temps dépasse la vitesse de descente
if (tempsPresent - tempsInit >= vitesse) and not pause:
pause = True #<- on stop la comparaison pour éviter d'y revenir plusieurs fois de suite
descente() #<- on test si le déplacement vers le bas est possible
fen.after(25,cycle)

#-------------------------------------------------------------------------------
def descente():
"""Appel à la fonction de vérification de descente possible."""
global coordCourante,tempsInit,pause

if verif_deplacement(1,0,0): #<- si la pièce peut descendre
coordCourante[0] += 1 #<- sa coordonnée matricielle en ligne est incrémentée de 1
dessine_piece() #<- on la redessine
tempsInit = clock() #<- on mémorise le temps initial de son déplacement
pause = False #<- on redonne la possibilité d'effectuer la comparaison des temps à la fonction 'cycle()'
else :
imprime_piece() #<- si elle ne peut plus descendre on l'imprime dans la matrice
verif_ligne() #<- on verifie si une ou plusieurs lignes se sont formées
nouvelle_piece() #<- on va choisir une nouvelle pièce

#-------------------------------------------------------------------------------
def gauche(event):
"""Appel à la fonction de vérification de déplacement à gauche possible."""
if verif_deplacement(0,-1,0):
coordCourante[1] -=1
dessine_piece()

#-------------------------------------------------------------------------------
def droite(event):
"""Appel à la fonction de vérification de déplacement à droite possible."""
if verif_deplacement(0,1,0):
coordCourante[1] += 1
dessine_piece()

#-------------------------------------------------------------------------------
def tourne(event):
"""Appel à la fonction de vérification de changementde de sens possible."""
global sens

if verif_deplacement(0,0,1):
sens += 1
if sens == 4:
sens = 0
dessine_piece()

#-------------------------------------------------------------------------------
def acceleration(event):
"""Touche BAS appuyée : augmentation de la vitesse."""
global vitesse

vitesse = 0.01

#-------------------------------------------------------------------------------
def acceleration_relache(event):
"""Touche BAS relachée : la vitesse prend sa valeur déterminée par le niveau."""
global vitesse

vitesse = 1

#-------------------------------------------------------------------------------
def imprime_piece():
"""Copie les valeurs de la pièce dans la matrice de jeu à ses coordonnées
matricielles."""
for i in range(4):
for j in range(4):
if pieceCourante[sens][i][j] != 0:
matriceJeu[coordCourante[0]+i][coordCourante[1]+j] = pieceCourante[sens][i][j]

#-------------------------------------------------------------------------------
def verif_deplacement(decalLigne,decalColonne,pivot):
"""Vérification par anticipation de la possibilité de déplacement de la pièce."""

## verif_deplacement(1,0,0) : déplacement vers le bas possible ?
## verif_deplacement(0,-1,0) : déplacement vers la gauche possible ?
## verif_deplacement(0,1,0) : déplacement vers la droite possible ?
## verif_deplacement(0,0,1) : rotation possible ?

## Pour chaque vérification, on se place à la coordonnée courante de la pièce
## à laquelle on ajoute le décalage demandé (dans le cas de la rotation aucun décalage, on prend
## la définition suivante de la pièce en cours).
## Puis on boucle en ligne et colonne dans celle-ci(par itération) et pour chaque valeur différente
## de zéro on vérifie si on sort pas de la matrice de jeu et sinon, si la pièce ne chevauchera pas une pièce déja placée.

rotation = sens + pivot
if rotation == 4 :
rotation = 0

for indiceLigne in range(4):
for indiceColonne in range(4):
if pieceCourante[rotation][indiceLigne][indiceColonne] != 0:
if (coordCourante[1]+decalColonne)+indiceColonne > 9 or (coordCourante[1]+decalColonne)+indiceColonne < 0 \
or (coordCourante[0]+decalLigne)+indiceLigne > 19:
return False
elif (pieceCourante[rotation][indiceLigne][indiceColonne] * matriceJeu[(coordCourante[0]+decalLigne)+indiceLigne][(coordCourante[1]+decalColonne)+indiceColonne]) != 0 :
return False
return True

#-------------------------------------------------------------------------------
def dessine_piece():
"""Efface la pièce dans l'air de dessin et la redessine à sa nouvelle position."""
global tabCarresPiece

if tabCarresPiece:
for carrePiece in tabCarresPiece:
airDessin.delete(carrePiece) #<- on efface tous les objets Tk rectangle de la pièce
tabCarresPiece = []

for indiceLigne in range(len(pieceCourante[sens])):
for indiceColonne in range(len(pieceCourante[sens][0])):
if pieceCourante[sens][indiceLigne][indiceColonne] != 0:
couleur = tabCouleurs[pieceCourante[sens][indiceLigne][indiceColonne]]
tabCarresPiece.append(airDessin.create_rectangle(((coordCourante[1]+indiceColonne)*20)+1,((coordCourante[0]+indiceLigne)*20)+1,
((coordCourante[1]+indiceColonne)*20)+(20-1),((coordCourante[0]+indiceLigne)*20)+(20-1),fill=couleur,outline=couleur))

#-------------------------------------------------------------------------------
def verif_ligne():
"""Vérifie si une ou plusieurs lignes se sont formées."""
for indiceLigne in range(20):
if 0 not in matriceJeu[indiceLigne]: #<- si dans une ligne de la matrice,le chiffre '0' n'est pas présent: cette ligne est complète
del matriceJeu[indiceLigne] #<- on la supprime de la matrice
matriceJeu[0:0] = [[0,0,0,0,0,0,0,0,0,0]] #<- on la remplace par une ligne vide au debut de la matrice

maj_grille()

#-------------------------------------------------------------------------------
def maj_grille():
"""Mise à jour graphique de la matrice après la pose d'une pièce
ou après suppression d'une ou plusieurs ligne."""

airDessin.delete(ALL)
for ligne in range(20):
for colonne in range(10):
if matriceJeu[ligne][colonne] != 0:
couleur = tabCouleurs[matriceJeu[ligne][colonne]]
airDessin.create_rectangle((colonne*20)+1,(ligne*20)+1,((colonne*20)+(20-1)),((ligne*20)+(20-1)),fill=couleur,outline=couleur)

fen.update()

#-------------------------------------------------------------------------------
def Quitter(event):
fen.quit()
fen.destroy()

fen = Tk()
fen.wm_geometry(newGeometry='+220+0')
fen.resizable(0,0)
fen.bind('q',Quitter)
fen.bind('<Right>',droite)
fen.bind('<Left>',gauche)
fen.bind('<Up>',tourne)
fen.bind('<Down>',acceleration)
fen.bind('<KeyRelease-Down>',acceleration_relache)
initialisation()
fen.mainloop()

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.