Einführung
In diesem Projekt werden wir ein Sudoku-Spiel mit Python und der Pygame-Bibliothek erstellen. Das Spiel wird ein Sudoku-Gitter vom angegebenen Schwierigkeitsgrad generieren und den Spielern ermöglichen, das Rätsel zu lösen, indem sie die leeren Zellen mit Zahlen ausfüllen. Das Spiel wird Funktionen wie die Auswahl der Schwierigkeit, das Hervorheben ausgewählter Zellen und das Überprüfen, ob das Gitter vollständig ist, bieten.
👀 Vorschau

🎯 Aufgaben
In diesem Projekt lernen Sie:
- Wie erforderliche Bibliotheken importiert werden
- Wie PyGame initialisiert wird
- Wie Farben definiert werden
- Wie die Größe und der Titel des Spielfensters festgelegt werden
- Wie das Spielfenster erstellt wird
- Wie Schriftarten geladen werden
- Wie ein Sudoku-Gitter generiert wird
- Wie das Sudoku-Gitter mit dem Rückwärtsverfolgungsalgorithmus gelöst wird
- Wie Zahlen aus dem Gitter aufgrund der Schwierigkeit entfernt werden
- Wie das Sudoku-Gitter auf dem Spielfenster gezeichnet wird
- Wie überprüft wird, ob das Gitter vollständig ausgefüllt ist
- Wie die Zellenkoordinaten unter der Mausposition abgerufen werden
- Wie der Schwierigkeitsgrad ausgewählt wird
- Wie die Hauptspielschleife implementiert wird
🏆 Errungenschaften
Nach Abschluss dieses Projekts werden Sie in der Lage sein:
- Die Pygame-Bibliothek für die Spieleentwicklung in Python zu verwenden
- Ein Sudoku-Gitter vom angegebenen Schwierigkeitsgrad zu generieren
- Ein Sudoku-Gitter mit dem Rückwärtsverfolgungsalgorithmus zu lösen
- Maus- und Tastaturevents in Pygame zu behandeln
- Formen und Text auf dem Spielfenster zu zeichnen
- Die Hauptspielschleife in Pygame zu implementieren
Erstelle die Projekt-Dateien
Beginnen Sie mit dem Erstellen einer Datei namens sudoku_game.py und öffnen Sie sie in Ihrem bevorzugten Texteditor oder integrierten Entwicklungsumgebung (IDE).
cd ~/project
touch sudoku_game.py
Importiere erforderliche Bibliotheken
Importieren Sie die erforderlichen Bibliotheken am Anfang der Datei. Für dieses Spiel benötigen wir die pygame- und die random-Bibliothek.
import pygame
import random
Installieren Sie die pygame-Bibliothek mit dem pip-Befehl.
sudo pip install pygame
Initialisiere PyGame
Initialisiere die Pygame-Bibliothek, um das Spielfenster einzurichten.
pygame.init()
Definiere Farben
Definiere die Farben, die im Spiel verwendet werden sollen. Wir werden das RGB-Format für die Farben verwenden.
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (200, 200, 200)
BLUE = (0, 0, 255)
LIGHT_BLUE = (100, 100, 255)
Setze die Abmessungen und den Titel des Spiel-Fensters
Setze die Dimensionen des Spielfensters und gebe einen Titel für das Spiel fest.
WINDOW_SIZE = (550, 550)
CELL_SIZE = WINDOW_SIZE[0] // 9
pygame.display.set_caption("Sudoku Game")
Erstelle das Spiel-Fenster
Erzeuge das Spielfenster mit den angegebenen Dimensionen.
screen = pygame.display.set_mode(WINDOW_SIZE)
Lade Schriftarten
Wir müssen Schriftarten laden, um Zahlen auf dem Spielfenster anzuzeigen. Lade zwei Schriftarten, eine für die größeren Zahlen und eine für die kleineren Zahlen.
font_large = pygame.font.SysFont("calibri", 50)
font_small = pygame.font.SysFont("calibri", 30)
Generiere das Sudoku-Gitter
Erstelle eine Funktion generate_sudoku(difficulty), die ein neues Sudoku-Gitter des angegebenen Schwierigkeitsgrades generiert. Die Funktion sollte das generierte Gitter zurückgeben.
def generate_sudoku(difficulty):
## Function code goes here
pass
Fülle die Diagonal-Subgitter
Innerhalb der generate_sudoku-Funktion fülle die diagonalen Teilgitter des Gitters mit zufälligen Zahlen. Dadurch wird sichergestellt, dass jedes Teilgitter Zahlen von 1 bis 9 enthält, ohne Wiederholungen.
## Fülle die diagonalen Teilgitter
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]
Löse das Sudoku-Gitter
Erstelle eine Funktion solve_sudoku(grid), die das Sudoku-Gitter mit dem Backtracking-Algorithmus löst. Die Funktion sollte True zurückgeben, wenn das Gitter lösbar ist, und False sonst.
def solve_sudoku(grid):
## Function code goes here
pass
Suche nach leerer Zelle
Innerhalb der solve_sudoku-Funktion erstelle eine Hilfsfunktion find_empty_cell(grid), die die Koordinaten der nächsten leeren Zelle im Gitter zurückgibt. Wenn es keine leeren Zellen gibt, gebe None zurück.
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
Prüfe auf gültigen Zug
Innerhalb der solve_sudoku-Funktion erstelle eine Hilfsfunktion is_valid_move(grid, row, col, num), die überprüft, ob das Setzen einer Zahl in einer Zelle ein gültiger Zug ist. Die Funktion sollte True zurückgeben, wenn der Zug gültig ist, und False sonst.
def is_valid_move(grid, row, col, num):
## Function code goes here
pass
Löse das Sudoku-Gitter (Fortsetzung)
Innerhalb der solve_sudoku-Funktion verwende die Hilfsfunktionen find_empty_cell und is_valid_move, um den Backtracking-Algorithmus zu implementieren. Wenn eine Lösung gefunden wird, gebe True zurück. Wenn die aktuelle Zahl zu einer ungültigen Lösung führt, gehe zurück, indem du die aktuelle Zelle auf 0 setzt.
## Versuche, die leere Zelle mit Zahlen von 1 bis 9 zu füllen
for num in range(1, 10):
if is_valid_move(grid, row, col, num):
grid[row][col] = num
if solve_sudoku(grid):
return True
## Wenn die aktuelle Zahl zu einer ungültigen Lösung führt, gehe zurück
grid[row][col] = 0
return False
Zahlen basierend auf der Schwierigkeit entfernen
Innerhalb der generate_sudoku-Funktion entferne Zahlen aus dem Gitter basierend auf dem angegebenen Schwierigkeitsgrad. Die Schwierigkeitsgrade sind: 1 (leicht), 2 (mittel), 3 (schwer). Die Anzahl der zu entfernenden Zahlen wird berechnet als num_to_remove = 45 + 10 * difficulty.
## Entferne Zahlen basierend auf dem Schwierigkeitsgrad
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
Raster zeichnen
Erstelle eine Funktion draw_grid(grid, selected_cell), die das Sudoku-Gitter auf dem Spielfenster zeichnet. Diese Funktion sollte für das Zeichnen von Zellen, Zahlen und das Hervorheben der ausgewählten Zelle verantwortlich sein.
def draw_grid(grid, selected_cell):
## Function code goes here
pass
Zellen ausfüllen und Zahlen zeichnen
Innerhalb der draw_grid-Funktion gehe durch das Gitter und zeichne die Zellen und Zahlen mit den Pygame-Funktionen pygame.draw.rect und screen.blit.
## Zeichne die Zellen
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)
## Zeichne die Zahlen
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)
Markiere ausgewählte Zelle
Innerhalb der draw_grid-Funktion, wenn die ausgewählte Zelle nicht None ist, verwende die pygame.draw.rect-Funktion, um die ausgewählte Zelle hervorzuheben.
## Hervorhebe die ausgewählte Zelle
if (row, col) == selected_cell:
pygame.draw.rect(screen, LIGHT_BLUE, cell_rect, 3)
Rasterlinien zeichnen
Innerhalb der draw_grid-Funktion, zeichne die Linien, um das Gitter zu erstellen, mit der pygame.draw.line-Funktion.
## Zeichne die Linien
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,
)
Anzeige aktualisieren
Innerhalb der draw_grid-Funktion, aktualisiere die Anzeige mit der pygame.display.update-Funktion.
pygame.display.update()
Prüfen, ob das Raster voll ist
Erstelle eine Funktion is_grid_full(grid), die überprüft, ob das Sudoku-Gitter vollständig ausgefüllt ist. Dies kann durch das Durchlaufen des Gitters und das Überprüfen, ob eine Zelle 0 enthält, erreicht werden.
def is_grid_full(grid):
## Function code goes here
pass
Zelle unter der Maus ermitteln
Erstelle eine Funktion get_cell_under_mouse(pos), die die Koordinaten der Zelle unter der Mausposition zurückgibt. Dies kann berechnet werden, indem die Mausposition durch die Zellgröße geteilt wird.
def get_cell_under_mouse(pos):
## Function code goes here
pass
Schwierigkeitsgrad auswählen
Erstelle eine Funktion select_difficulty(), die dem Spieler ermöglicht, das Schwierigkeitsniveau vor dem Start des Spiels auszuwählen. Diese Funktion sollte die Schwierigkeitsoptionen anzeigen und das ausgewählte Schwierigkeitsniveau zurückgeben.
def select_difficulty():
## Function code goes here
pass
Schwierigkeitsauswahl implementieren
Innerhalb der select_difficulty-Funktion, implementiere die Logik zur Schwierigkeitsauswahl mit den Pygame-Funktionen pygame.mouse.get_pos und pygame.event.get.
## Zeige den Text zur Schwierigkeitsauswahl an
title_text = font_large.render("Select Difficulty", True, BLACK)
screen.blit(title_text, (110, 200))
## Zeige die Schwierigkeitsoptionen an
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()
## Warte auf die Schwierigkeitsauswahl
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: ## Linke Maustaste
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
Hauptspielschleife
Erstelle die Hauptspielschleife, indem du eine Funktion main() definierst.
def main():
## Function code goes here
pass
Schwierigkeitsgrad auswählen und Raster generieren
Innerhalb der main-Funktion, wähle das Schwierigkeitsniveau, indem du select_difficulty() aufrufst und beende die Funktion, wenn die Schwierigkeit None ist. Dann generiere ein Sudoku-Gitter mit dem ausgewählten Schwierigkeitsniveau, indem du generate_sudoku(difficulty) aufrufst.
## Wähle das Schwierigkeitsniveau
difficulty = select_difficulty()
if difficulty is None:
return
## Generiere ein neues Sudoku-Gitter
grid = generate_sudoku(difficulty)
Variablen der Spielschleife
Innerhalb der main-Funktion, erstelle die Spielschleifenvariablen selected_cell und running. Setze selected_cell auf None und running auf True.
selected_cell = None
running = True
Taste wiederholen aktivieren
Innerhalb der main-Funktion, aktiviere die Tastendauerfortsetzung mit der Funktion pygame.key.set_repeat. Wir setzen die Verzögerung und das Intervall auf 100 Millisekunden, um es Spielern einfacher zu machen, Zellen auszufüllen.
## Aktiviere die Tastendauerfortsetzung
pygame.key.set_repeat(100, 100)
Ereignisse verarbeiten
Innerhalb der Spielschleife, behandle Ereignisse mit der Funktion pygame.event.get. Überprüfe auf Beenden-Ereignisse, Mausknopfe-Ereignisse und Tasteneingabe-Ereignisse.
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
## Behandle Mausknopfe-Ereignisse
pass
elif event.type == pygame.KEYDOWN:
## Behandle Tasteneingabe-Ereignisse
pass
Mausknopfe-Ereignisse verarbeiten
Innerhalb der Ereignisbehandlung für Mausknopfe-Ereignisse, überprüfe, ob die linke oder rechte Maustaste gedrückt wurde.
if event.button == 1: ## Linke Maustaste
## Behandle das Klicken der linken Maustaste
pass
elif event.button == 3: ## Rechte Maustaste
## Behandle das Klicken der rechten Maustaste
pass
Linken Mausknopf-Klick verarbeiten
Innerhalb der Behandlung des Klicks auf die linke Maustaste, ermittle die Zellenkoordinaten unter der Mausposition, indem du get_cell_under_mouse(pos) aufrufst.
## Ermittle die Zelle unter der Mausposition
pos = pygame.mouse.get_pos()
row, col = get_cell_under_mouse(pos)
Linken Mausknopf-Klick verarbeiten (Fortsetzung)
Innerhalb der Behandlung des Klicks auf die linke Maustaste, wähle die Zelle aus, wenn sie leer ist, indem du prüfst, ob grid[row][col] == 0.
## Wähle die Zelle aus, wenn sie leer ist
if grid[row][col] == 0:
selected_cell = (row, col)
Rechten Mausknopf-Klick verarbeiten
Innerhalb der Behandlung des Klicks auf die rechte Maustaste, lösche die ausgewählte Zelle, wenn sie nicht None ist und leer ist, indem du prüfst, ob grid[selected_cell[0]][selected_cell[1]] == 0.
if selected_cell:
## Lösche die ausgewählte Zelle, wenn sie leer ist
if grid[selected_cell[0]][selected_cell[1]] == 0:
grid[selected_cell[0]][selected_cell[1]] = 0
Taste-Ereignisse verarbeiten
Innerhalb der Ereignisbehandlung für Tasteneingaben, überprüfe, welche Zifferntaste gedrückt wurde und setze den Wert der ausgewählten Zelle entsprechend.
if selected_cell:
## Ermittle die gedrückte Taste
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
Raster zeichnen und Abschluss prüfen
Innerhalb der Spielschleife, zeichne das Gitter, indem du draw_grid(grid, selected_cell) aufrufst. Dann überprüfe, ob das Gitter vollständig ist, indem du is_grid_full(grid) aufrufst.
## Zeichne das Gitter
draw_grid(grid, selected_cell)
## Überprüfe, ob das Gitter vollständig ist
if is_grid_full(grid):
print("Glückwunsch! Du hast das Sudoku-Puzzle gelöst.")
Anzeige aktualisieren und beenden
Nach der Spielschleife aktualisiere die Anzeige mit der Funktion pygame.display.update und beende das Spiel mit pygame.quit().
## Aktualisiere die Anzeige
pygame.display.update()
## Beende das Spiel
pygame.quit()
Spiel ausführen
Schließlich füge eine Bedingung hinzu, um zu überprüfen, ob die aktuelle Datei der Haupteinstiegspunkt des Programms ist. Wenn ja, starte das Spiel, indem du die Funktion main() aufrufst.
if __name__ == "__main__":
main()
Starte das Spiel mit dem Befehl python.
python sudoku_game.py

Zusammenfassung
Glückwunsch! Du hast erfolgreich ein Sudoku-Spiel mit Python und der Pygame-Bibliothek erstellt. Das Spiel ermöglicht es Spielern, ein Schwierigkeitslevel auszuwählen, leere Zellen mit Zahlen zu füllen und zu überprüfen, ob das Gitter vollständig ist. Viel Spaß beim Spielen und Lösen von Sudoku-Puzzles!



