Create a Minesweeper Game using HTML CSS & JavaScript
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 <h1> for the game title.
- Create a grid of <div> 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.
Javascript
// 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(); |
HTML
<!-- 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 > |
CSS
/* 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:
Contact Us