Dans ce tutoriel, tu vas créer un jeu de dames en Python avec Tkinter : un plateau 8×8 dessiné sur un Canvas, des pions qui se déplacent au clic, les prises, la promotion en dame et la détection de la fin de partie. Un projet idéal pour pratiquer la programmation orientée objet, les tableaux 2D et les événements.

Ce que tu vas construire : un jeu de dames en Python complet
Programmer un jeu de dames en Python, c’est un excellent exercice : il faut représenter le plateau, gérer les tours, vérifier les règles et mettre à jour l’affichage à chaque coup.
Prérequis
- Python 3 installé sur ton ordinateur
- Tkinter, inclus par défaut avec Python
- Un éditeur de code : VS Code, PyCharm ou IDLE
- Les bases de Python : classes, listes et boucles
Commence par la calculatrice Python avec Tkinter : elle présente les bases des fenêtres et des boutons.
Étape 1 : comprendre la structure du projet
Tout le jeu tient dans une classe CheckersGame qui contient la logique et l’interface. Le plateau est un tableau 2D de 8×8 cases : chaque case est vide ("") ou contient un pion ("white", "black") ou une dame ("white_king", "black_king"). Le Canvas de Tkinter redessine le plateau à chaque coup.
Étape 2 : créer la fenêtre et la classe du jeu
Crée un fichier dames.py. Commence par importer Tkinter et sa boîte de messages, puis crée la classe :
import tkinter as tk
from tkinter import messagebox
class CheckersGame:
def __init__(self, root):
self.root = root
self.root.title("Jeu de Dames 🎲")
self.board_size = 8 # Échiquier 8x8
self.cell_size = 60 # Taille d'une case (en pixels)
self.board = [] # Plateau de jeu (tableau 2D)
self.selected_piece = None # Pièce sélectionnée
self.current_turn = "white" # Tour du joueur ("white" ou "black")
# Crée un Canvas pour dessiner l’échiquier
self.canvas = tk.Canvas(
root, width=self.board_size * self.cell_size, height=self.board_size * self.cell_size
)
self.canvas.pack()
self.canvas.bind("<Button-1>", self.on_click)
self.init_board() # Initialise le plateau
self.draw_board() # Dessine l'échiquierdames.pyÉtape 3 : placer les pions sur le plateau
Les pions occupent les trois premières et les trois dernières rangées, uniquement sur les cases foncées :
def init_board(self):
self.board = [["" for _ in range(self.board_size)] for _ in range(self.board_size)]
for row in range(self.board_size):
for col in range(self.board_size):
if (row + col) % 2 == 1: # Cases foncées
if row < 3:
self.board[row][col] = "black" # Pièces noires
elif row > 4:
self.board[row][col] = "white" # Pièces blanchesdames.py
Étape 4 : dessiner le damier et les pions
Pour chaque case, on dessine un rectangle clair ou foncé avec create_rectangle(), puis un cercle coloré avec create_oval() s’il y a un pion :
def draw_board(self):
self.canvas.delete("all") # Efface tout
for row in range(self.board_size):
for col in range(self.board_size):
x1 = col * self.cell_size
y1 = row * self.cell_size
x2 = x1 + self.cell_size
y2 = y1 + self.cell_size
fill_color = "white" if (row + col) % 2 == 0 else "gray"
self.canvas.create_rectangle(x1, y1, x2, y2, fill=fill_color)
piece = self.board[row][col]
if piece:
color = "white" if piece.startswith("white") else "black"
outline = "gold" if "king" in piece else "blue"
self.canvas.create_oval(
x1 + 10, y1 + 10, x2 - 10, y2 - 10, fill=color, outline=outline, width=2
)dames.pyÉtape 5 : gérer les clics de la souris
Au premier clic, le joueur sélectionne un pion. Au second, le programme tente de le déplacer sur la case choisie. La position de la souris est convertie en ligne et en colonne en divisant par la taille d’une case :
def on_click(self, event):
col = event.x // self.cell_size
row = event.y // self.cell_size
if self.selected_piece:
self.move_piece(row, col)
elif self.board[row][col].startswith(self.current_turn):
self.selected_piece = (row, col)dames.pyÉtape 6 : valider et effectuer les mouvements
Avant de déplacer un pion, on vérifie que le mouvement respecte les règles. Si le pion saute par-dessus un adversaire, celui-ci est retiré du plateau. Enfin, on vérifie la promotion en dame et on passe au joueur suivant :
def move_piece(self, new_row, new_col):
old_row, old_col = self.selected_piece
if self.is_valid_move(old_row, old_col, new_row, new_col):
piece = self.board[old_row][old_col]
self.board[new_row][new_col] = piece
self.board[old_row][old_col] = ""
if abs(new_row - old_row) > 1: # Capture
middle_row = (old_row + new_row) // 2
middle_col = (old_col + new_col) // 2
self.board[middle_row][middle_col] = ""
self.promote_to_king(new_row, new_col)
self.switch_turn()
else:
messagebox.showerror("Erreur", "Mouvement non valide !")
self.selected_piece = None
self.draw_board()dames.pyCe code s’appuie sur plusieurs méthodes : is_valid_move() (déplacement autorisé), must_capture() et can_capture() (prise obligatoire), promote_to_king() (promotion), switch_turn() (changement de joueur) et check_game_over() (fin de partie). Tu les trouveras toutes dans le code complet ci-dessous.
Le code complet du jeu de dames en Python
Voici le programme complet, avec toutes les règles. Copie-le dans dames.py, puis lance le jeu avec python dames.py :
import tkinter as tk
from tkinter import messagebox
class CheckersGame:
def __init__(self, root):
self.root = root
self.root.title("Jeu de Dames")
self.board_size = 8
self.cell_size = 60
self.board = []
self.selected_piece = None
self.current_turn = "white"
self.canvas = tk.Canvas(
root, width=self.board_size * self.cell_size, height=self.board_size * self.cell_size
)
self.canvas.pack()
self.canvas.bind("<Button-1>", self.on_click)
self.init_board()
self.draw_board()
def init_board(self):
self.board = [["" for _ in range(self.board_size)] for _ in range(self.board_size)]
for row in range(self.board_size):
for col in range(self.board_size):
if (row + col) % 2 == 1:
if row < 3:
self.board[row][col] = "black"
elif row > 4:
self.board[row][col] = "white"
def draw_board(self):
self.canvas.delete("all")
for row in range(self.board_size):
for col in range(self.board_size):
x1 = col * self.cell_size
y1 = row * self.cell_size
x2 = x1 + self.cell_size
y2 = y1 + self.cell_size
fill_color = "white" if (row + col) % 2 == 0 else "gray"
self.canvas.create_rectangle(x1, y1, x2, y2, fill=fill_color)
piece = self.board[row][col]
if piece:
color = "white" if piece.startswith("white") else "black"
outline = "gold" if "king" in piece else "blue"
self.canvas.create_oval(
x1 + 10, y1 + 10, x2 - 10, y2 - 10, fill=color, outline=outline, width=2
)
def on_click(self, event):
col = event.x // self.cell_size
row = event.y // self.cell_size
if self.selected_piece:
self.move_piece(row, col)
elif self.board[row][col].startswith(self.current_turn):
self.selected_piece = (row, col)
def move_piece(self, new_row, new_col):
old_row, old_col = self.selected_piece
if self.is_valid_move(old_row, old_col, new_row, new_col):
piece = self.board[old_row][old_col]
self.board[new_row][new_col] = piece
self.board[old_row][old_col] = ""
if abs(new_row - old_row) > 1: # Capture
middle_row = (old_row + new_row) // 2
middle_col = (old_col + new_col) // 2
self.board[middle_row][middle_col] = ""
self.promote_to_king(new_row, new_col)
# Vérifier si une capture supplémentaire est possible
if self.can_capture(new_row, new_col):
self.selected_piece = (new_row, new_col)
self.draw_board()
return
self.switch_turn()
else:
messagebox.showerror("Erreur", "Mouvement non valide !")
self.selected_piece = None
self.draw_board()
self.check_game_over()
def is_valid_move(self, old_row, old_col, new_row, new_col):
piece = self.board[old_row][old_col]
if self.board[new_row][new_col] != "":
return False
if "king" in piece: # Dame
return self.is_valid_king_move(old_row, old_col, new_row, new_col)
# Pièces normales
if abs(new_row - old_row) == 1 and abs(new_col - old_col) == 1:
return not self.must_capture()
if abs(new_row - old_row) == 2 and abs(new_col - old_col) == 2:
middle_row = (old_row + new_row) // 2
middle_col = (old_col + new_col) // 2
return (
self.board[middle_row][middle_col].startswith(
"black" if self.current_turn == "white" else "white"
)
and self.board[new_row][new_col] == ""
)
return False
def is_valid_king_move(self, old_row, old_col, new_row, new_col):
if abs(new_row - old_row) != abs(new_col - old_col):
return False
step_row = 1 if new_row > old_row else -1
step_col = 1 if new_col > old_col else -1
r, c = old_row + step_row, old_col + step_col
encountered_pieces = 0
while r != new_row and c != new_col:
if self.board[r][c] != "":
encountered_pieces += 1
r += step_row
c += step_col
return encountered_pieces == 1
def must_capture(self):
for row in range(self.board_size):
for col in range(self.board_size):
if self.board[row][col].startswith(self.current_turn):
if self.can_capture(row, col):
return True
return False
def can_capture(self, row, col):
directions = [(-2, -2), (-2, 2), (2, -2), (2, 2)]
piece = self.board[row][col]
if "king" in piece: # Vérifier toutes les directions possibles pour une dame
for step_row, step_col in [(-1, -1), (-1, 1), (1, -1), (1, 1)]:
r, c = row + step_row, col + step_col
while 0 <= r < self.board_size and 0 <= c < self.board_size:
if self.board[r][c] == "":
r += step_row
c += step_col
continue
if self.board[r][c].startswith(
"black" if self.current_turn == "white" else "white"
):
r += step_row
c += step_col
if 0 <= r < self.board_size and 0 <= c < self.board_size and self.board[r][c] == "":
return True
break
else: # Pièces normales
for dr, dc in directions:
middle_row = row + dr // 2
middle_col = col + dc // 2
new_row, new_col = row + dr, col + dc
if (
0 <= new_row < self.board_size
and 0 <= new_col < self.board_size
and self.board[middle_row][middle_col].startswith(
"black" if self.current_turn == "white" else "white"
)
and self.board[new_row][new_col] == ""
):
return True
return False
def promote_to_king(self, row, col):
if row == 0 and self.board[row][col] == "white":
self.board[row][col] = "white_king"
elif row == self.board_size - 1 and self.board[row][col] == "black":
self.board[row][col] = "black_king"
def switch_turn(self):
self.current_turn = "white" if self.current_turn == "black" else "black"
self.root.title(f"Tour : {self.current_turn}")
def check_game_over(self):
white_pieces = sum(row.count("white") + row.count("white_king") for row in self.board)
black_pieces = sum(row.count("black") + row.count("black_king") for row in self.board)
if white_pieces == 0 or black_pieces == 0:
winner = "Noir" if white_pieces == 0 else "Blanc"
messagebox.showinfo("Fin de la partie", f"Le joueur {winner} a gagné !")
self.root.quit()
if __name__ == "__main__":
root = tk.Tk()
game = CheckersGame(root)
root.mainloop()dames.py
Aller plus loin
- Mettre en surbrillance les cases où le pion sélectionné peut aller
- Afficher le joueur dont c’est le tour dans le titre de la fenêtre ou sous le plateau
- Ajouter un compteur de pions capturés
- Créer un adversaire contrôlé par l’ordinateur, d’abord avec des coups aléatoires, puis avec l’algorithme minimax
- Découvrir un autre jeu de plateau : le mini-jeu du Morpion en Java ou le jeu d’échecs en React et TypeScript
FAQ : questions fréquentes
Comment lancer le jeu de dames ?
Enregistre le code dans un fichier dames.py, ouvre un terminal dans le même dossier et tape python dames.py (ou python3 dames.py sur macOS et Linux).
Pourquoi un message « Mouvement non valide » s’affiche ?
Le déplacement ne respecte pas les règles : case occupée, mauvais sens, ou prise obligatoire ignorée. Sélectionne un autre pion ou une autre case.
Comment un pion devient-il une dame ?
Quand un pion atteint la dernière rangée du camp adverse, la méthode promote_to_king() le transforme en dame, qui peut alors se déplacer en diagonale dans les deux sens.
Peut-on jouer contre l’ordinateur ?
Pas dans cette version, qui se joue à deux sur le même ordinateur. C’est une excellente idée d’évolution, présentée dans la section « Aller plus loin ».
Bravo, ton jeu de dames en Python est terminé ! Tu as manipulé un Canvas, des événements et toute la logique d’un vrai jeu. Personnalise les couleurs, ajoute des règles et partage ta version en commentaire !


merci pour ce tuto, sauf que le code poster ici est legerement different que github
Merci lm-code, mais dans mes spouvenirs il y avait beaucoup plsu de tutoriels. Pourrais tu les remettres ? Ps, merci pour ce jeu de dame que j’ai amélioré, mais la base vient de vous, et merci à GPT.
Hello Greg, tout d’abord navré our le retard. En effet, il y en avait beaucoup plus. Je les remettrai au fur et à mésure tkt