Implementing a Minesweeper Game in C

Game Rules Overview

Minesweeper is a classic puzzle game that challenges players to identify and avoid hidden mines on a grid. The objective is to reveal all non-mine cells as quickly as possible. The game ends in failure if a player accidentally clicks on a mine cell.

The game board consists of a rectangular grid where mines are randomly distributed. Different difficulty levels are available:

  • Beginner: 9x9 grid with 10 mines
  • Intermediate: 16x16 grid with 40 mines
  • Expert: 16x30 grid with 99 mines
  • Custom: User-defined grid size and mine count (maximum 24x30)

Implementation Approach

To implement Minesweeper, we need to design a data structure that can represent the game state, including the mine positions, revealed cells, and flagged cells. A two-dimensional array is suitable for representing the game board.

Our implementation will require several key components:

  • Game board initialization
  • Mine placement algorithm
  • Cell revealing mechanism
  • Adjacent mine counting
  • Win/lose condition checking

Code Implementation

Header File (minesweeper.h)


#include 
#include 
#include 

#define GRID_ROWS 9
#define GRID_COLS 9
#define BUFFER_ROWS (GRID_ROWS + 2)
#define BUFFER_COLS (GRID_COLS + 2)
#define MINE_COUNT 10

// Function prototypes
void initializeBoard(char board[BUFFER_ROWS][BUFFER_COLS], int rows, int cols, char value);
void displayBoard(char board[BUFFER_ROWS][BUFFER_COLS], int displayRows, int displayCols);
void placeMines(char board[BUFFER_ROWS][BUFFER_COLS], int rows, int cols);
void revealCell(char mineField[BUFFER_ROWS][BUFFER_COLS], char playerBoard[BUFFER_ROWS][BUFFER_COLS], int x, int y);
int countAdjacentMines(char mineField[BUFFER_ROWS][BUFFER_COLS], int x, int y);
void playGame(char mineField[BUFFER_ROWS][BUFFER_COLS], char playerBoard[BUFFER_ROWS][BUFFER_COLS], int rows, int cols);

Game Logic Implementation (minesweeper.c)


#include "minesweeper.h"

void initializeBoard(char board[BUFFER_ROWS][BUFFER_COLS], int rows, int cols, char value) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            board[i][j] = value;
        }
    }
}

void displayBoard(char board[BUFFER_ROWS][BUFFER_COLS], int displayRows, int displayCols) {
    printf("------ Minesweeper Game ------\n");
    
    // Print column numbers
    for (int i = 0; i <= displayCols; i++) {
        printf("%d ", i);
    }
    printf("\n");
    
    // Print board with row numbers
    for (int i = 1; i <= displayRows; i++) {
        printf("%d ", i);
        for (int j = 1; j <= displayCols; j++) {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
}

void placeMines(char board[BUFFER_ROWS][BUFFER_COLS], int rows, int cols) {
    int minesPlaced = 0;
    while (minesPlaced < MINE_COUNT) {
        int x = rand() % rows + 1;
        int y = rand() % cols + 1;
        
        if (board[x][y] == '0') {
            board[x][y] = 'M'; // 'M' represents a mine
            minesPlaced++;
        }
    }
}

int countAdjacentMines(char mineField[BUFFER_ROWS][BUFFER_COLS], int x, int y) {
    int mineCount = 0;
    for (int i = x - 1; i <= x + 1; i++) {
        for (int j = y - 1; j <= y + 1; j++) {
            if (mineField[i][j] == 'M') {
                mineCount++;
            }
        }
    }
    return mineCount;
}

void revealCell(char mineField[BUFFER_ROWS][BUFFER_COLS], char playerBoard[BUFFER_ROWS][BUFFER_COLS], int x, int y) {
    if (x < 1 || x > GRID_ROWS || y < 1 || y > GRID_COLS || playerBoard[x][y] != '*') {
        return;
    }
    
    if (mineField[x][y] == 'M') {
        // Game over - hit a mine
        playerBoard[x][y] = 'M';
        return;
    }
    
    int adjacentMines = countAdjacentMines(mineField, x, y);
    playerBoard[x][y] = adjacentMines + '0';
    
    // If there are no adjacent mines, reveal all adjacent cells recursively
    if (adjacentMines == 0) {
        for (int i = x - 1; i <= x + 1; i++) {
            for (int j = y - 1; j <= y + 1; j++) {
                if (i != x || j != y) {
                    revealCell(mineField, playerBoard, i, j);
                }
            }
        }
    }
}

void playGame(char mineField[BUFFER_ROWS][BUFFER_COLS], char playerBoard[BUFFER_ROWS][BUFFER_COLS], int rows, int cols) {
    initializeBoard(mineField, BUFFER_ROWS, BUFFER_COLS, '0');
    initializeBoard(playerBoard, BUFFER_ROWS, BUFFER_COLS, '*');
    
    placeMines(mineField, rows, cols);
    
    int cellsRevealed = 0;
    int totalCells = rows * cols - MINE_COUNT;
    
    while (cellsRevealed < totalCells) {
        displayBoard(playerBoard, rows, cols);
        
        int x, y;
        printf("Enter coordinates to reveal (row column): ");
        scanf("%d %d", &x, &y);
        
        if (x < 1 || x > rows || y < 1 || y > cols) {
            printf("Invalid coordinates. Please try again.\n");
            continue;
        }
        
        if (playerBoard[x][y] != '*') {
            printf("This cell has already been revealed. Please try another.\n");
            continue;
        }
        
        revealCell(mineField, playerBoard, x, y);
        
        if (playerBoard[x][y] == 'M') {
            printf("Game over! You hit a mine!\n");
            displayBoard(mineField, rows, cols);
            return;
        }
        
        cellsRevealed++;
    }
    
    printf("Congratulations! You've successfully revealed all non-mine cells!\n");
    displayBoard(mineField, rows, cols);
}

Main Program (main.c)


#include "minesweeper.h"

void displayMenu() {
    printf("********************\n");
    printf("*****  1.play  *****\n");
    printf("*****  0.exit  *****\n");
    printf("********************\n");
}

int main() {
    srand((unsigned int)time(NULL));
    
    int choice;
    do {
        displayMenu();
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1: {
                char mineField[BUFFER_ROWS][BUFFER_COLS] = {0};
                char playerBoard[BUFFER_ROWS][BUFFER_COLS] = {0};
                playGame(mineField, playerBoard, GRID_ROWS, GRID_COLS);
                break;
            }
            case 0:
                printf("Exiting game...\n");
                break;
            default:
                printf("Invalid choice. Please try again.\n");
                break;
        }
    } while (choice != 0);
    
    return 0;
}

Tags: Minesweeper c programming game development Puzzle Games implementation

Posted on Wed, 13 May 2026 12:44:36 +0000 by Ilovetopk