Le jeu du Taquin en Python est assez facile à implémenter. Après tout, ce n’est qu’une matrice carrée… Mais graphiquement, cela donne quoi avec pygame ?

Le module pygame est très intéressant pour représenter graphiquement le taquin.

Avant, j’utilisais tkinter,; mais ça, c’était avant… Regardons de plus près comment implémenter le jeu du Taquin en Python. Pour savoir ce qu’est ce jeu, regardez wikipedia.

Le jeu du Taquin en Python: premiers pas

Il faut d’abord créer une matrice 4×4 (mais qui ne pollue pas, elle…). Je vais utiliser numpy.

array( [ [1,2,3,4], [5,6,7,8] , [9,10,11,12], [13,14,15,0] ] )

C’est le plateau initial. Ici, le “0” définira l’espace vide. Maintenant, il faut mélanger tout ça. Et pour se faire, nous allons devoir définir les mouvements.

Alors, comme j’anticipe beaucoup, je vais directement m’orienter vers la POO.

Je vais définir mon taquin comme un objet, et définir des méthodes pour créer les mouvements nécessaires: bouger une case vers le haut, le bas, la droite et la gauche. Je vais aussi implémenter une méthode qui affiche en mode texte le plateau (avant

Voici un premier jet:

class Taquin:
    def __init__(self):
        self.plateau = array( [ [1,2,3,4], [5,6,7,8] , [9,10,11,12], [13,14,15,0] ] )
        self.directions = [] # liste des mouvements utilisés pour mélanger le taquin
        
    def __str__(self):
        return self.plateau.__str__()
        
    def poszero(self):
        for y in range(4):
            for x in range(4):
                if self.plateau[y][x] == 0: return y,x
                
    def possible_mouvements(self):
        i,j = self.poszero()
        impossible = []
        possible = ['L' , 'R' , 'U' , 'D']
        if i == 0:
            impossible.append('D')
        if i == 3:
            impossible.append('U')
        if j == 0:
            impossible.append('R')
        if j == 3:
            impossible.append('L')
        
        return [ i for i in possible if i not in impossible ]
        
    def down(self):
        i,j = self.poszero()
        if i != 0:
            self.plateau[i][j] = self.plateau[i-1][j]
            self.plateau[i-1][j] = 0
            
    def up(self):
        i,j = self.poszero()
        if i != 3:
            self.plateau[i][j] = self.plateau[i+1][j]
            self.plateau[i+1][j] = 0
            
    def left(self):
        i,j = self.poszero()
        if j != 3:
            self.plateau[i][j] = self.plateau[i][j+1]
            self.plateau[i][j+1] = 0
            
    def right(self):
        i,j = self.poszero()
        if j != 0:
            self.plateau[i][j] = self.plateau[i][j-1]
            self.plateau[i][j-1] = 0
            
    def mix(self):
        for _ in range( 10, 100 ):
            direction = choice( self.possible_mouvements() )
            self.directions.append(direction)
            match direction:
                case 'L' : self.left()
                case 'R' : self.right()
                case 'U' : self.up()
                case _ : self.down()

La méthode mix() mélange le plateau initial en faisant des mouvements aléatoires pris parmi ceux qui sont possibles (en fonction de la position du zéro).

À ce stade, nous pouvons définir notre taquin:

>>> T = Taquin()
>>> T.mix()
>>> print( T )
[[ 2 10  6  5]
 [ 9  1  4  7]
 [ 0 13 12  8]
 [14  3 11 15]]
>>> T.up()
>>> print( T )
[[ 2 10  6  5]
 [ 9  1  4  7]
 [14 13 12  8]
 [ 0  3 11 15]]

“T.up()” a détecté la case vide et a monté la case qui était sous l’espace vide. Bon, c’est cool! Maintenant, il faudrait l’interface graphique….

Le jeu du Taquin: interface graphique

Je vous balance le code direct, c’est plus simple:

"""
Le jeu du Taquin
Stéphane Pasquet
2023-10-23
https://mathweb.fr
"""

from numpy import array
from random import randint, choice
import pygame

"""
Définition de l'objet: Taquin()
"""

class Taquin:
    def __init__(self):
        self.plateau = array( [ [1,2,3,4], [5,6,7,8] , [9,10,11,12], [13,14,15,0] ] )
        self.directions = [] # liste des mouvements utilisés pour mélanger le taquin
        
    def __str__(self):
        return self.plateau.__str__()
        
    def poszero(self):
        for y in range(4):
            for x in range(4):
                if self.plateau[y][x] == 0: return y,x
                
    def possible_mouvements(self):
        i,j = self.poszero()
        impossible = []
        possible = ['L' , 'R' , 'U' , 'D']
        if i == 0:
            impossible.append('D')
        if i == 3:
            impossible.append('U')
        if j == 0:
            impossible.append('R')
        if j == 3:
            impossible.append('L')
        
        return [ i for i in possible if i not in impossible ]
        
    def down(self):
        i,j = self.poszero()
        if i != 0:
            self.plateau[i][j] = self.plateau[i-1][j]
            self.plateau[i-1][j] = 0
            
    def up(self):
        i,j = self.poszero()
        if i != 3:
            self.plateau[i][j] = self.plateau[i+1][j]
            self.plateau[i+1][j] = 0
            
    def left(self):
        i,j = self.poszero()
        if j != 3:
            self.plateau[i][j] = self.plateau[i][j+1]
            self.plateau[i][j+1] = 0
            
    def right(self):
        i,j = self.poszero()
        if j != 0:
            self.plateau[i][j] = self.plateau[i][j-1]
            self.plateau[i][j-1] = 0
            
    def mix(self):
        for _ in range( 10, 100 ):
            direction = choice( self.possible_mouvements() )
            self.directions.append(direction)
            match direction:
                case 'L' : self.left()
                case 'R' : self.right()
                case 'U' : self.up()
                case _ : self.down()
                
    def graphicplate(self, screen, win = False):
        font = pygame.font.Font(None, 100)
        if win:
            color = (84,8,8)
        else:
            color = (40,58,82)
        for y in range(4):
            for x in range(4):
                if self.plateau[y][x] != 0:
                    pygame.draw.rect(screen, color, pygame.Rect(16+x*146, 16+y*146, 142, 142), border_radius=20)
                    if self.plateau[y][x] < 10:
                        dx = 0
                    else:
                        dx = -16
                    screen.blit( font.render(str(self.plateau[y][x]),1,(255,255,255)) , (70+dx + 144*x , 58 + 144*y) )
                
    def play(self):
        T.mix()
        pygame.init()
        screen = pygame.display.set_mode((610, 610))
        pygame.display.set_caption('Le jeu du Taquin - Stéphane Pasquet - mathweb.fr')
        green = (9,44,28)
        marroon = (33,21,3)
        marroon_light = (47,32,8)
        running = True
        
        
        while running:
            screen.fill( green )
            pygame.draw.rect(screen, marroon, pygame.Rect(10, 10, 585, 585))
            pygame.draw.rect(screen, marroon_light, pygame.Rect(16, 16, 584, 584))
            
            if (self.plateau == array( [ [1,2,3,4], [5,6,7,8] , [9,10,11,12], [13,14,15,0] ] )).all():
                self.graphicplate(screen, win = True)
            else:
                self.graphicplate(screen)
                
            
            # Fermeture de la fenêtre
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        self.up()
                    elif event.key == pygame.K_DOWN:
                        self.down()
                    elif event.key == pygame.K_LEFT:
                        self.left()
                    elif event.key == pygame.K_RIGHT:
                        self.right()
                
            pygame.display.flip()
            
        pygame.quit()
                  
        
if __name__ == "__main__":
    T = Taquin()
    T.play()

Et voilà! Pour jouer, il suffit d’appuyer sur les flèches du clavier pour faire bouger les cases.

  • ← : flèche de gauche pour faire bouger la case qui se trouve à droite de l’espace vide vers la gauche;
  • → : flèche de droite pour faire bouger la case qui se trouve à gauche de l’espace vide vers la droite;
  • ↑ : flèche du haut pour faire bouger la case qui se trouve sous l’espace vide vers le haut;
  • ↓ : flèche du bas pour faire bouger la case qui se trouve au-dessus de l’espace vide vers le bas;

Le jeu du Taquin en Python: améliorations avec des images

N’étant pas totalement satisfait, j’ai souhaité améliorer l’apparence en insérant des images plutôt que d’insérer du texte. Cela donne alors ceci:

taquin en Python avec images nombres

Et maintenant que le plus gros des modifications est fait, je peux désormais remplacer les nombres par une image découpée:

taquin en python avec image

Pour cette dernière version, il m’a fallu écrire un script annexe qui permet de découper mon image entière en 16 cases (dont la dernière ne sera pas mise afin de laisser un trou).

Vous trouverez dans le dossier compressé suivant tout ce qu’il faut:

N’hésitez pas à partager vos remarques et suggestions en laissant un commentaire.

Et n’hésitez pas à soutenir ce site sur Tipeee si ce que je propose vous satisfait.

Catégories : Python

5 3 votes
Évaluation de l'article
S’abonner
Notification pour
guest
2 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
joz

Et votre jeu est jouable à tous les coups ?
ou il y a des cas où il n’y a pas de solution ?

2
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x