Create a Minesweeper Game using HTML CSS & JavaScript
Last Updated :
26 Apr, 2025
Improve
Minesweeper is a classic puzzle game that challenges your logical thinking and deduction skills. It's a great project for developers looking to improve their front-end web development skills. In this article, we'll walk through the steps to create a Minesweeper game using HTML, CSS, and JavaScript.
Preview of final output: Let us have a look at how the final output will look like.
Prerequisites
Before we dive into coding, make sure you have the following tools and knowledge:
- Basic understanding of HTML, CSS, and JavaScript.
- A code editor like Visual Studio Code or Sublime Text.
- A modern web browser (e.g., Chrome, Firefox).
Approach
- Use
for the game title.
- Create a grid of elements to represent the cells of the Minesweeper board.
- Define styles for the game board, cells, buttons, and other UI components.
- Apply colors, fonts, and layout rules to make the game visually appealing.
- Generate a grid of cells based on the desired number of rows and columns.
- Randomly place mines within the grid while ensuring that mines are not placed adjacent to each other.
- Handle user interactions, such as clicking on cells.
- Keep track of the game state, including whether the player has won or lost.
- Implement win and lose conditions.
Example: The code below explains the approach.
// Script.js
const numRows = 8;
const numCols = 8;
const numMines = 10;
const gameBoard =
document.getElementById(
"gameBoard"
);
let board = [];
function initializeBoard() {
for (let i = 0; i < numRows; i++) {
board[i] = [];
for (
let j = 0;
j < numCols;
j++
) {
board[i][j] = {
isMine: false,
revealed: false,
count: 0,
};
}
}
// Place mines randomly
let minesPlaced = 0;
while (minesPlaced < numMines) {
const row = Math.floor(
Math.random() * numRows
);
const col = Math.floor(
Math.random() * numCols
);
if (!board[row][col].isMine) {
board[row][
col
].isMine = true;
minesPlaced++;
}
}
// Calculate counts
for (let i = 0; i < numRows; i++) {
for (
let j = 0;
j < numCols;
j++
) {
if (!board[i][j].isMine) {
let count = 0;
for (
let dx = -1;
dx <= 1;
dx++
) {
for (
let dy = -1;
dy <= 1;
dy++
) {
const ni =
i + dx;
const nj =
j + dy;
if (
ni >= 0 &&
ni <
numRows &&
nj >= 0 &&
nj <
numCols &&
board[ni][
nj
].isMine
) {
count++;
}
}
}
board[i][j].count =
count;
}
}
}
}
function revealCell(row, col) {
if (
row < 0 ||
row >= numRows ||
col < 0 ||
col >= numCols ||
board[row][col].revealed
) {
return;
}
board[row][col].revealed = true;
if (board[row][col].isMine) {
// Handle game over
alert(
"Game Over! You stepped on a mine."
);
} else if (
board[row][col].count === 0
) {
// If cell has no mines nearby,
// Reveal adjacent cells
for (
let dx = -1;
dx <= 1;
dx++
) {
for (
let dy = -1;
dy <= 1;
dy++
) {
revealCell(
row + dx,
col + dy
);
}
}
}
renderBoard();
}
function renderBoard() {
gameBoard.innerHTML = "";
for (let i = 0; i < numRows; i++) {
for (
let j = 0;
j < numCols;
j++
) {
const cell =
document.createElement(
"div"
);
cell.className = "cell";
if (board[i][j].revealed) {
cell.classList.add(
"revealed"
);
if (
board[i][j].isMine
) {
cell.classList.add(
"mine"
);
cell.textContent =
"????";
} else if (
board[i][j].count >
0
) {
cell.textContent =
board[i][
j
].count;
}
}
cell.addEventListener(
"click",
() => revealCell(i, j)
);
gameBoard.appendChild(cell);
}
gameBoard.appendChild(
document.createElement("br")
);
}
}
initializeBoard();
renderBoard();
<!-- Index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Minesweeper Game</title>
</head>
<link rel="stylesheet" href="./style.css">
<body>
<h1>Minesweeper</h1>
<div id="gameBoard"></div>
</body>
<script src="./script.js"></script>
</html>
/* Styles.css */
body {
font-family: Arial, sans-serif;
text-align: center;
}
.board {
display: inline-block;
margin: 20px;
}
.cell {
width: 30px;
height: 30px;
border: 1px solid #ccc;
display: inline-block;
text-align: center;
vertical-align: middle;
font-size: 20px;
cursor: pointer;
/* Default color for unrevealed tiles */
background-color: #eee;
/* Default color for unrevealed tile text */
color: #333;
}
.revealed {
/* Color for revealed tiles */
background-color: #ccc;
/* Color for revealed tile text */
color: #000;
}
.mine {
/* Color for mines */
background-color: #ff3333;
}
Output:
