Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Slide Puzzle Using Python PyGame
In this article, we will guide you through creating a slide puzzle game using Python and the PyGame library. A slide puzzle consists of numbered tiles in a grid with one empty space, where players slide tiles to arrange them in numerical order.
Throughout this tutorial, we will explore how to set up the game window, create puzzle tiles, shuffle them randomly, and handle user input for an interactive experience. By the end, you'll have a fully functional slide puzzle game.
Installation and Setup
First, install PyGame if you haven't already:
pip install pygame
Create a new Python script and import the necessary modules:
import pygame import random import sys # Initialize PyGame pygame.init() # Game constants WINDOW_SIZE = 400 GRID_SIZE = 3 TILE_SIZE = WINDOW_SIZE // GRID_SIZE MARGIN = 2 WHITE = (255, 255, 255) BLACK = (0, 0, 0) BLUE = (70, 130, 180)
Creating the Game Window
Set up the game window with proper dimensions and title:
import pygame
import random
import sys
pygame.init()
WINDOW_SIZE = 400
GRID_SIZE = 3
TILE_SIZE = WINDOW_SIZE // GRID_SIZE
MARGIN = 2
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (70, 130, 180)
# Create game window
screen = pygame.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))
pygame.display.set_caption("Slide Puzzle Game")
font = pygame.font.Font(None, 36)
print("Game window created successfully")
Game window created successfully
Puzzle Logic
Create the puzzle board representation and helper functions:
class SlidePuzzle:
def __init__(self, size=3):
self.size = size
self.board = list(range(1, size * size)) + [0] # 0 represents empty space
self.solved_board = self.board.copy()
def shuffle_board(self):
"""Shuffle the board to create a solvable puzzle"""
for _ in range(1000):
self.make_random_move()
def find_empty_pos(self):
"""Find the position of empty space (0)"""
index = self.board.index(0)
return index // self.size, index % self.size
def get_valid_moves(self):
"""Get list of tiles that can move into empty space"""
empty_row, empty_col = self.find_empty_pos()
moves = []
# Check adjacent positions
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dr, dc in directions:
new_row, new_col = empty_row + dr, empty_col + dc
if 0 <= new_row < self.size and 0 <= new_col < self.size:
moves.append((new_row, new_col))
return moves
def make_random_move(self):
"""Make a random valid move for shuffling"""
valid_moves = self.get_valid_moves()
if valid_moves:
move_pos = random.choice(valid_moves)
self.move_tile(move_pos[0], move_pos[1])
def move_tile(self, row, col):
"""Move tile at given position to empty space"""
empty_row, empty_col = self.find_empty_pos()
tile_index = row * self.size + col
empty_index = empty_row * self.size + empty_col
# Swap tile with empty space
self.board[tile_index], self.board[empty_index] = self.board[empty_index], self.board[tile_index]
def is_solved(self):
"""Check if puzzle is solved"""
return self.board == self.solved_board
# Test the puzzle logic
puzzle = SlidePuzzle(3)
print("Initial board:", puzzle.board)
puzzle.shuffle_board()
print("Shuffled board:", puzzle.board)
print("Is solved:", puzzle.is_solved())
Initial board: [1, 2, 3, 4, 5, 6, 7, 8, 0] Shuffled board: [1, 2, 3, 4, 0, 6, 7, 5, 8] Is solved: False
Complete Game Implementation
Here's the complete slide puzzle game with graphics and user interaction:
import pygame
import random
import sys
class SlidePuzzleGame:
def __init__(self):
pygame.init()
self.WINDOW_SIZE = 400
self.GRID_SIZE = 3
self.TILE_SIZE = self.WINDOW_SIZE // self.GRID_SIZE
self.MARGIN = 2
# Colors
self.WHITE = (255, 255, 255)
self.BLACK = (0, 0, 0)
self.BLUE = (70, 130, 180)
self.GREEN = (60, 179, 113)
self.GRAY = (128, 128, 128)
# Setup display
self.screen = pygame.display.set_mode((self.WINDOW_SIZE, self.WINDOW_SIZE))
pygame.display.set_caption("Slide Puzzle Game")
self.font = pygame.font.Font(None, 48)
self.clock = pygame.time.Clock()
# Initialize puzzle
self.board = list(range(1, self.GRID_SIZE * self.GRID_SIZE)) + [0]
self.solved_board = self.board.copy()
self.shuffle_board()
def shuffle_board(self):
"""Shuffle the board to create a solvable puzzle"""
for _ in range(1000):
self.make_random_move()
def find_empty_pos(self):
"""Find the position of empty space (0)"""
index = self.board.index(0)
return index // self.GRID_SIZE, index % self.GRID_SIZE
def get_valid_moves(self):
"""Get list of positions that can move into empty space"""
empty_row, empty_col = self.find_empty_pos()
moves = []
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dr, dc in directions:
new_row, new_col = empty_row + dr, empty_col + dc
if 0 <= new_row < self.GRID_SIZE and 0 <= new_col < self.GRID_SIZE:
moves.append((new_row, new_col))
return moves
def make_random_move(self):
"""Make a random valid move for shuffling"""
valid_moves = self.get_valid_moves()
if valid_moves:
move_pos = random.choice(valid_moves)
self.move_tile(move_pos[0], move_pos[1])
def move_tile(self, row, col):
"""Move tile at given position to empty space"""
empty_row, empty_col = self.find_empty_pos()
# Check if move is valid
if (row, col) in self.get_valid_moves():
tile_index = row * self.GRID_SIZE + col
empty_index = empty_row * self.GRID_SIZE + empty_col
self.board[tile_index], self.board[empty_index] = self.board[empty_index], self.board[tile_index]
return True
return False
def is_solved(self):
"""Check if puzzle is solved"""
return self.board == self.solved_board
def get_tile_at_pos(self, mouse_pos):
"""Get tile position from mouse coordinates"""
x, y = mouse_pos
col = x // self.TILE_SIZE
row = y // self.TILE_SIZE
if 0 <= row < self.GRID_SIZE and 0 <= col < self.GRID_SIZE:
return row, col
return None
def draw(self):
"""Draw the game board"""
self.screen.fill(self.WHITE)
for row in range(self.GRID_SIZE):
for col in range(self.GRID_SIZE):
index = row * self.GRID_SIZE + col
tile_value = self.board[index]
# Calculate tile position
x = col * self.TILE_SIZE + self.MARGIN
y = row * self.TILE_SIZE + self.MARGIN
width = self.TILE_SIZE - 2 * self.MARGIN
height = self.TILE_SIZE - 2 * self.MARGIN
if tile_value != 0: # Don't draw empty space
# Draw tile background
color = self.GREEN if self.is_solved() else self.BLUE
pygame.draw.rect(self.screen, color, (x, y, width, height))
pygame.draw.rect(self.screen, self.BLACK, (x, y, width, height), 2)
# Draw tile number
text = self.font.render(str(tile_value), True, self.WHITE)
text_rect = text.get_rect(center=(x + width//2, y + height//2))
self.screen.blit(text, text_rect)
# Draw win message
if self.is_solved():
text = self.font.render("Puzzle Solved!", True, self.BLACK)
text_rect = text.get_rect(center=(self.WINDOW_SIZE//2, self.WINDOW_SIZE//2))
pygame.draw.rect(self.screen, self.WHITE, text_rect.inflate(20, 10))
self.screen.blit(text, text_rect)
pygame.display.flip()
def run(self):
"""Main game loop"""
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left mouse button
tile_pos = self.get_tile_at_pos(event.pos)
if tile_pos:
row, col = tile_pos
self.move_tile(row, col)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: # Press 'R' to reset
self.board = list(range(1, self.GRID_SIZE * self.GRID_SIZE)) + [0]
self.shuffle_board()
self.draw()
self.clock.tick(60)
pygame.quit()
sys.exit()
# Run the game
if __name__ == "__main__":
game = SlidePuzzleGame()
game.run()
Game Controls
The game supports simple mouse controls:
- Left Click: Click on any tile adjacent to the empty space to move it
- Press 'R': Reset and shuffle the puzzle
- Close Window: Exit the game
Key Features
| Feature | Description |
|---|---|
| Solvable Shuffling | Ensures puzzle is always solvable by making random valid moves |
| Visual Feedback | Tiles turn green when puzzle is solved |
| Input Validation | Only allows valid moves adjacent to empty space |
| Reset Function | Press 'R' to shuffle and start over |
Conclusion
This slide puzzle game demonstrates fundamental PyGame concepts including event handling, graphics rendering, and game state management. The modular design makes it easy to modify grid size, colors, or add new features like move counters or timers.
