Développement d'un jeu de Sudoku avec Python et Pygame

PythonBeginner
Pratiquer maintenant

Introduction

Dans ce projet, nous allons créer un jeu de Sudoku en utilisant Python et la bibliothèque Pygame. Le jeu générera une grille de Sudoku du niveau de difficulté spécifié et permettra aux joueurs de résoudre le puzzle en remplissant les cases vides avec des chiffres. Le jeu offrira des fonctionnalités telles que la sélection de la difficulté, la mise en évidence des cases sélectionnées et la vérification si la grille est complète.

👀 Aperçu

Aperçu du jeu de Sudoku

🎯 Tâches

Dans ce projet, vous allez apprendre :

  • Comment importer les bibliothèques requises
  • Comment initialiser PyGame
  • Comment définir des couleurs
  • Comment définir les dimensions et le titre de la fenêtre de jeu
  • Comment créer la fenêtre de jeu
  • Comment charger des polices
  • Comment générer une grille de Sudoku
  • Comment résoudre une grille de Sudoku en utilisant l'algorithme de backtracking
  • Comment supprimer des chiffres de la grille en fonction de la difficulté
  • Comment dessiner la grille de Sudoku sur la fenêtre de jeu
  • Comment vérifier si la grille est complètement remplie
  • Comment obtenir les coordonnées de la case sous la position de la souris
  • Comment sélectionner le niveau de difficulté
  • Comment implémenter la boucle principale du jeu

🏆 Réalisations

Après avoir terminé ce projet, vous serez capable de :

  • Utiliser la bibliothèque Pygame pour le développement de jeux en Python
  • Générer une grille de Sudoku d'un niveau de difficulté spécifié
  • Résoudre une grille de Sudoku en utilisant l'algorithme de backtracking
  • Gérer les événements de souris et de clavier dans Pygame
  • Dessiner des formes et du texte sur la fenêtre de jeu
  • Implémenter la boucle principale du jeu dans Pygame

Créer les fichiers du projet

Pour commencer, créez un fichier nommé sudoku_game.py et ouvrez-le dans votre éditeur de texte ou environnement de développement intégré (IDE) préféré.

cd ~/projet
touch sudoku_game.py

Importer les bibliothèques requises

Importez les bibliothèques requises au début du fichier. Nous avons besoin des bibliothèques pygame et random pour ce jeu.

import pygame
import random

Installez la bibliothèque pygame à l'aide de la commande pip.

sudo pip install pygame

Initialiser PyGame

Initialisez la bibliothèque PyGame pour configurer la fenêtre de jeu.

pygame.init()

Définir les couleurs

Définissez les couleurs à utiliser dans le jeu. Nous utiliserons le format RGB pour les couleurs.

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (200, 200, 200)
BLUE = (0, 0, 255)
LIGHT_BLUE = (100, 100, 255)

Définir les dimensions et le titre de la fenêtre de jeu

Définissez les dimensions de la fenêtre de jeu et donnez un titre au jeu.

WINDOW_SIZE = (550, 550)
CELL_SIZE = WINDOW_SIZE[0] // 9

pygame.display.set_caption("Sudoku Game")

Créer la fenêtre de jeu

Créez la fenêtre de jeu avec les dimensions spécifiées.

screen = pygame.display.set_mode(WINDOW_SIZE)

Charger les polices

Nous devrons charger des polices pour afficher les chiffres sur l'écran du jeu. Chargez deux polices, l'une pour les chiffres plus grands et l'autre pour les chiffres plus petits.

font_large = pygame.font.SysFont("calibri", 50)
font_small = pygame.font.SysFont("calibri", 30)

Générer la grille de Sudoku

Créez une fonction generate_sudoku(difficulty) qui génère une nouvelle grille de Sudoku au niveau de difficulté spécifié. La fonction devrait renvoyer la grille générée.

def generate_sudoku(difficulty):
    ## Function code goes here
    pass

Remplir les sous-grilles diagonales

Dans la fonction generate_sudoku, remplissez les sous-grilles diagonales de la grille avec des nombres aléatoires. Cela garantit que chaque sous-grille contient les nombres de 1 à 9 sans répétition.

## Fill diagonal subgrids
for i in range(0, 9, 3):
    nums = random.sample(range(1, 10), 3)
    for j in range(3):
        grid[i + j][i + j] = nums[j]

Résoudre la grille de Sudoku

Créez une fonction solve_sudoku(grid) qui résout la grille de Sudoku en utilisant l'algorithme de retour en arrière. La fonction devrait renvoyer True si la grille est résoluble et False sinon.

def solve_sudoku(grid):
    ## Function code goes here
    pass

Trouver une cellule vide

Dans la fonction solve_sudoku, créez une fonction auxiliaire find_empty_cell(grid) qui renvoie les coordonnées de la prochaine cellule vide dans la grille. Si il n'y a pas de cellules vides, renvoyez None.

def find_empty_cell(grid):
    for row in range(9):
        for col in range(9):
            if grid[row][col] == 0:
                return (row, col)

    return None

Vérifier un mouvement valide

Dans la fonction solve_sudoku, créez une fonction auxiliaire is_valid_move(grid, row, col, num) qui vérifie si placer un nombre dans une cellule est un mouvement valide. La fonction devrait renvoyer True si le mouvement est valide et False sinon.

def is_valid_move(grid, row, col, num):
    ## Function code goes here
    pass

Résoudre la grille de Sudoku (suite)

Dans la fonction solve_sudoku, utilisez les fonctions auxiliaires find_empty_cell et is_valid_move pour implémenter l'algorithme de retour en arrière. Si une solution est trouvée, renvoyez True. Si le nombre actuel conduit à une solution invalide, revenez en arrière en mettant la cellule actuelle à 0.

## Essayez de remplir la cellule vide avec les nombres de 1 à 9
for num in range(1, 10):
    if is_valid_move(grid, row, col, num):
        grid[row][col] = num

        if solve_sudoku(grid):
            return True

        ## Si le nombre actuel conduit à une solution invalide, revenez en arrière
        grid[row][col] = 0

return False

Supprimer des chiffres en fonction de la difficulté

Dans la fonction generate_sudoku, supprimez des nombres de la grille en fonction du niveau de difficulté spécifié. Les niveaux de difficulté sont : 1 (facile), 2 (moyen), 3 (difficile). Le nombre de nombres à supprimer est calculé comme suit : num_to_remove = 45 + 10 * difficulty.

## Supprimez des nombres en fonction du niveau de difficulté
num_to_remove = 45 + 10 * difficulty
for _ in range(num_to_remove):
    row = random.randint(0, 8)
    col = random.randint(0, 8)
    grid[row][col] = 0

return grid

Tracer la grille

Créez une fonction draw_grid(grid, selected_cell) qui dessine la grille de Sudoku sur la fenêtre de jeu. Cette fonction devrait être responsable du dessin des cellules, des nombres et de la mise en évidence de la cellule sélectionnée.

def draw_grid(grid, selected_cell):
    ## Function code goes here
    pass

Remplir les cellules et tracer les chiffres

Dans la fonction draw_grid, parcourez la grille et dessinez les cellules et les nombres à l'aide des fonctions Pygame pygame.draw.rect et screen.blit.

## Dessinez les cellules
for row in range(9):
    for col in range(9):
        cell_rect = pygame.Rect(
            col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE
        )
        pygame.draw.rect(screen, GRAY, cell_rect)

        ## Dessinez les nombres
        if grid[row][col]!= 0:
            number = font_small.render(str(grid[row][col]), True, BLACK)
            text_rect = number.get_rect(
                center=(
                    col * CELL_SIZE + CELL_SIZE // 2,
                    row * CELL_SIZE + CELL_SIZE // 2,
                )
            )
            screen.blit(number, text_rect)

Mettre en évidence la cellule sélectionnée

Dans la fonction draw_grid, mettez en évidence la cellule sélectionnée si elle n'est pas None à l'aide de la fonction pygame.draw.rect.

## Mettez en évidence la cellule sélectionnée
if (row, col) == selected_cell:
    pygame.draw.rect(screen, LIGHT_BLUE, cell_rect, 3)

Tracer les lignes de grille

Dans la fonction draw_grid, dessinez les lignes pour créer la grille à l'aide de la fonction pygame.draw.line.

## Dessinez les lignes
for i in range(10):
    if i % 3 == 0:
        thickness = 4
    else:
        thickness = 1

    pygame.draw.line(
        screen,
        BLACK,
        (0, i * CELL_SIZE),
        (WINDOW_SIZE[0], i * CELL_SIZE),
        thickness,
    )
    pygame.draw.line(
        screen,
        BLACK,
        (i * CELL_SIZE, 0),
        (i * CELL_SIZE, WINDOW_SIZE[1]),
        thickness,
    )

Mettre à jour l'affichage

Dans la fonction draw_grid, mettez à jour l'affichage à l'aide de la fonction pygame.display.update.

pygame.display.update()

Vérifier si la grille est pleine

Créez une fonction is_grid_full(grid) qui vérifie si la grille de Sudoku est complètement remplie. Cela peut être fait en parcourant la grille et en vérifiant si une cellule quelconque contient 0.

def is_grid_full(grid):
    ## Le code de la fonction va ici
    pass

Obtenir la cellule sous la souris

Créez une fonction get_cell_under_mouse(pos) qui renvoie les coordonnées de la cellule sous la position de la souris. Cela peut être calculé en divisant la position de la souris par la taille de la cellule.

def get_cell_under_mouse(pos):
    ## Le code de la fonction va ici
    pass

Sélectionner la difficulté

Créez une fonction select_difficulty() qui permet au joueur de sélectionner le niveau de difficulté avant de commencer le jeu. Cette fonction devrait afficher les options de difficulté et renvoyer le niveau de difficulté sélectionné.

def select_difficulty():
    ## Le code de la fonction va ici
    pass

Implémenter la sélection de difficulté

Dans la fonction select_difficulty, implémentez la logique de sélection de difficulté à l'aide des fonctions Pygame pygame.mouse.get_pos et pygame.event.get.

## Afficher le texte de sélection de difficulté
title_text = font_large.render("Select Difficulty", True, BLACK)
screen.blit(title_text, (110, 200))

## Afficher les options de difficulté
option_y = 300
for difficulty, label in difficulties.items():
    option_text = font_small.render(f"{difficulty}. {label}", True, BLACK)
    text_rect = option_text.get_rect(center=(WINDOW_SIZE[0] // 2, option_y))
    screen.blit(option_text, text_rect)
    option_y += 70

pygame.display.update()

## Attendre la sélection de difficulté
difficulty_selected = False
difficulty = 1

while not difficulty_selected:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            return
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  ## Bouton gauche de la souris
                pos = pygame.mouse.get_pos()
                if 180 <= pos[0] <= 380:
                    if 300 <= pos[1] <= 350:
                        difficulty = 1
                        difficulty_selected = True
                    elif 370 <= pos[1] <= 420:
                        difficulty = 2
                        difficulty_selected = True
                    elif 440 <= pos[1] <= 490:
                        difficulty = 3
                        difficulty_selected = True

return difficulty

Boucle principale du jeu

Créez la boucle principale du jeu en définissant une fonction main().

def main():
    ## Le code de la fonction va ici
    pass

Sélectionner la difficulté et générer la grille

Dans la fonction main, sélectionnez le niveau de difficulté en appelant select_difficulty() et retournez si la difficulté est None. Ensuite, générez une grille de Sudoku en utilisant le niveau de difficulté sélectionné en appelant generate_sudoku(difficulty).

## Sélectionnez le niveau de difficulté
difficulty = select_difficulty()
if difficulty is None:
    return

## Générez une nouvelle grille de Sudoku
grid = generate_sudoku(difficulty)

Variables de la boucle du jeu

Dans la fonction main, créez les variables de boucle de jeu selected_cell et running. Affectez selected_cell à None et running à True.

selected_cell = None
running = True

Activer la répétition de touches

Dans la fonction main, activez la répétition de touches à l'aide de la fonction pygame.key.set_repeat. Nous définissons le délai et l'intervalle sur 100 millisecondes pour faciliter la saisie des cases par les joueurs.

## Activer la répétition de touches
pygame.key.set_repeat(100, 100)

Gérer les événements

Dans la boucle de jeu, gérer les événements à l'aide de la fonction pygame.event.get. Vérifiez les événements de fermeture, d'événements de bouton de souris et d'événements de touches.

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
    elif event.type == pygame.MOUSEBUTTONDOWN:
        ## Gérer les événements de bouton de souris
        pass
    elif event.type == pygame.KEYDOWN:
        ## Gérer les événements de touches
        pass

Gérer les événements de boutons de souris

Dans la gestion des événements de bouton de souris, vérifiez si le bouton gauche de la souris est cliqué ou si le bouton droit de la souris est cliqué.

if event.button == 1:  ## Bouton gauche de la souris
    ## Gérer le clic du bouton gauche de la souris
    pass
elif event.button == 3:  ## Bouton droit de la souris
    ## Gérer le clic du bouton droit de la souris
    pass

Gérer le clic sur le bouton gauche de la souris

Dans la gestion du clic du bouton gauche de la souris, obtenez les coordonnées de la cellule sous la position de la souris en appelant get_cell_under_mouse(pos).

## Obtenez la cellule sous la position de la souris
pos = pygame.mouse.get_pos()
row, col = get_cell_under_mouse(pos)

Gérer le clic sur le bouton gauche de la souris (suite)

Dans la gestion du clic du bouton gauche de la souris, sélectionnez la cellule si elle est vide en vérifiant si grid[row][col] == 0.

## Sélectionnez la cellule si elle est vide
if grid[row][col] == 0:
    selected_cell = (row, col)

Gérer le clic sur le bouton droit de la souris

Dans la gestion du clic du bouton droit de la souris, effacez la cellule sélectionnée si elle n'est pas None et si elle est vide en vérifiant si grid[selected_cell[0]][selected_cell[1]] == 0.

if selected_cell:
    ## Effacez la cellule sélectionnée si elle est vide
    if grid[selected_cell[0]][selected_cell[1]] == 0:
        grid[selected_cell[0]][selected_cell[1]] = 0

Gérer les événements de touches

Dans la gestion des événements de touches, vérifiez quelle touche numérique est pressée et définissez la valeur de la cellule sélectionnée en conséquence.

if selected_cell:
    ## Obtenez la touche pressée
    if event.key == pygame.K_1:
        grid[selected_cell[0]][selected_cell[1]] = 1
    elif event.key == pygame.K_2:
        grid[selected_cell[0]][selected_cell[1]] = 2
    elif event.key == pygame.K_3:
        grid[selected_cell[0]][selected_cell[1]] = 3
    elif event.key == pygame.K_4:
        grid[selected_cell[0]][selected_cell[1]] = 4
    elif event.key == pygame.K_5:
        grid[selected_cell[0]][selected_cell[1]] = 5
    elif event.key == pygame.K_6:
        grid[selected_cell[0]][selected_cell[1]] = 6
    elif event.key == pygame.K_7:
        grid[selected_cell[0]][selected_cell[1]] = 7
    elif event.key == pygame.K_8:
        grid[selected_cell[0]][selected_cell[1]] = 8
    elif event.key == pygame.K_9:
        grid[selected_cell[0]][selected_cell[1]] = 9

Dessiner une grille et vérifier l'achèvement

Dans la boucle de jeu, dessinez la grille en appelant draw_grid(grid, selected_cell). Ensuite, vérifiez si la grille est complète en appelant is_grid_full(grid).

## Dessinez la grille
draw_grid(grid, selected_cell)

## Vérifiez si la grille est complète
if is_grid_full(grid):
    print("Congratulations! You solved the Sudoku puzzle.")

Mettre à jour l'affichage et quitter

Après la boucle de jeu, mettez à jour l'affichage en utilisant la fonction pygame.display.update et quittez le jeu en utilisant pygame.quit().

## Mettez à jour l'affichage
pygame.display.update()

## Quittez le jeu
pygame.quit()

Lancer le jeu

Enfin, ajoutez une condition pour vérifier si le fichier actuel est le point d'entrée principal du programme. Si c'est le cas, exécutez le jeu en appelant la fonction main().

if __name__ == "__main__":
    main()

Exécutez le jeu en utilisant la commande python.

python sudoku_game.py

Capture d'écran d'exécution du jeu Sudoku

Résumé

Félicitations ! Vous avez réussi à créer un jeu de Sudoku en utilisant Python et la bibliothèque Pygame. Le jeu permet aux joueurs de sélectionner un niveau de difficulté, de remplir les cases vides avec des chiffres et de vérifier si la grille est complète. Amusez-vous bien à jouer et à résoudre des puzzles de Sudoku !

✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer