Minesweeper Game in Python

Creating a full-featured Minesweeper game in Python requires handling various game mechanics, including the grid setup, player inputs, and game state updates. This step-by-step tutorial guides you through the process using Pygame. You will learn to initialize the game, create a grid with randomly placed mines, draw the grid, and handle player inputs for revealing cells and flagging mines. By the end, you’ll have a functioning Minesweeper game with basic features and mechanics.

Prerequisites

First, you need to install pygame if you haven’t already:

pip install pygame

Minesweeper Game Code

Here’s a basic implementation of Minesweeper:

import pygame
import random

pygame.init()

# Constants
WIDTH, HEIGHT = 600, 600
ROWS, COLS = 10, 10
MINES = 10
CELL_SIZE = WIDTH // COLS

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (128, 128, 128)
RED = (255, 0, 0)

# Fonts
FONT = pygame.font.SysFont("comicsans", 25)

# Screen
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Minesweeper")

# Functions to create the grid and place mines
def create_grid():
    grid = [[0 for _ in range(COLS)] for _ in range(ROWS)]
    mine_positions = set()
    while len(mine_positions) < MINES:
        pos = (random.randint(0, ROWS-1), random.randint(0, COLS-1))
        mine_positions.add(pos)
    for (r, c) in mine_positions:
        grid[r][c] = -1
        for i in range(max(0, r-1), min(r+2, ROWS)):
            for j in range(max(0, c-1), min(c+2, COLS)):
                if grid[i][j] != -1:
                    grid[i][j] += 1
    return grid, mine_positions

def draw_grid(grid, revealed, flagged):
    for r in range(ROWS):
        for c in range(COLS):
            rect = pygame.Rect(c * CELL_SIZE, r * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            if revealed[r][c]:
                pygame.draw.rect(screen, WHITE, rect)
                if grid[r][c] == -1:
                    pygame.draw.circle(screen, BLACK, rect.center, CELL_SIZE // 4)
                elif grid[r][c] > 0:
                    text = FONT.render(str(grid[r][c]), True, BLACK)
                    screen.blit(text, text.get_rect(center=rect.center))
            else:
                pygame.draw.rect(screen, GRAY, rect)
                if flagged[r][c]:
                    pygame.draw.rect(screen, RED, rect)
            pygame.draw.rect(screen, BLACK, rect, 1)

def reveal_cell(grid, revealed, r, c):
    if revealed[r][c] or flagged[r][c]:
        return
    revealed[r][c] = True
    if grid[r][c] == 0:
        for i in range(max(0, r-1), min(r+2, ROWS)):
            for j in range(max(0, c-1), min(c+2, COLS)):
                if not (i == r and j == c):
                    reveal_cell(grid, revealed, i, j)

# Initialize game state
grid, mine_positions = create_grid()
revealed = [[False for _ in range(COLS)] for _ in range(ROWS)]
flagged = [[False for _ in range(COLS)] for _ in range(ROWS)]
game_over = False

# Game loop
running = True
while running:
    screen.fill(WHITE)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN and not game_over:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            r, c = mouse_y // CELL_SIZE, mouse_x // CELL_SIZE
            if event.button == 1:  # Left click
                if grid[r][c] == -1:
                    game_over = True
                else:
                    reveal_cell(grid, revealed, r, c)
            elif event.button == 3:  # Right click
                flagged[r][c] = not flagged[r][c]

    draw_grid(grid, revealed, flagged)
    pygame.display.flip()

pygame.quit()

Explanation:

  1. Initialization: Initializes pygame and sets up screen dimensions, colors, fonts, and grid settings.
  2. Grid Creation:
    • create_grid(): Creates a grid, places mines randomly, and calculates adjacent mine counts for each cell.
  3. Drawing the Grid:
    • draw_grid(grid, revealed, flagged): Draws the grid, cells, and mines.
  4. Reveal Cells:
    • reveal_cell(grid, revealed, r, c): Recursively reveals cells, revealing adjacent cells if the cell is empty (0).
  5. Game Loop:
    • Handles events such as quitting the game and mouse clicks (left-click to reveal, right-click to flag).
    • Updates and draws the grid state.

This simplified implementation provides the basic mechanics of Minesweeper. Enhancements can include better graphics, win/loss detection, and advanced features like a timer and different difficulty levels.