Learn How to Create a Minesweeper Game with HTML, CSS, and JavaScript

Faraz

By Faraz -

Follow this step-by-step tutorial to create your own Minesweeper game with HTML, CSS, and JavaScript. Perfect for beginners with basic knowledge of web development.


learn how to create a minesweeper game with html, css, and javascript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

Minesweeper is a classic puzzle game that has been enjoyed by millions of players worldwide for several decades. The game was first released in 1990 by Microsoft and quickly became a hit. In this tutorial, we will guide you through the process of creating your own Minesweeper game using HTML, CSS, and JavaScript.

HTML is the markup language used for creating the structure and content of web pages. CSS is used for styling and layout, and JavaScript is a programming language used for creating interactive and dynamic web pages. Together, they form the foundation for most web development projects.

By the end of this tutorial, you will have a fully functioning Minesweeper game that you can play and share with others. This tutorial is designed for beginners with basic knowledge of HTML, CSS, and JavaScript. We will provide step-by-step instructions and include screenshots and code snippets to help you better understand the process.

What is Minesweeper?

Minesweeper is a classic puzzle game that was first released by Microsoft in 1990. The game is played on a grid of squares, with some of the squares containing hidden mines. The player's objective is to uncover all the squares on the grid that do not contain mines without detonating any of the mines.

To help the player, each uncovered square displays a number that indicates the number of adjacent squares that contain mines. Using these numbers and logical deduction, the player can determine the location of the mines and mark them with flags. The game is won when all squares that do not contain mines are uncovered and lost when a mine is detonated.

Minesweeper became popular for its simple yet challenging gameplay, and it has been included in many versions of the Microsoft Windows operating system. It has since been adapted for various platforms and remains a popular game to this day.

So, let's get started and create our very own Minesweeper game!

Join My Telegram Channel to Download the Projects Source Code: Click Here

Prerequisites:

Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.

Code by: Matt Soria

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our Minesweeper game.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

The document starts with a declaration, which tells the browser what type of document it is reading (in this case, an HTML5 document).

The HTML tag contains two attributes: lang which sets the language of the document to English, and head which contains metadata about the document such as the title, character set, and viewport.

The title tag inside the head tag sets the title of the page to "Minesweeper Game". The meta tag sets the character set to UTF-8 and the viewport to the width of the device.

The link tags are used to import external stylesheets. The first link imports the "Space Mono" font from Google Fonts, while the second link imports the "normalize.css" stylesheet which normalizes default styles across different browsers. The third link imports a custom stylesheet called "styles.css", which is used to style the HTML elements in the document.

The header tag creates a banner at the top of the page containing the game title and a legend that explains how to flag a mine.

The main tag contains the game board and its components. The game board is contained within a div tag with an id of "board". The game board has two main sections: the top section contains the scoreboard, mine counter, level selector, and timer, while the bottom section is currently empty.

The div tag with an id of "scoreboard" contains the mine counter, level selector, reset button, and timer. The mine counter and timer are displayed as numbers that update as the game progresses. The level selector is a dropdown menu that allows the player to choose the game's difficulty level (beginner, intermediate, expert). The reset button is an emoji that allows the player to start a new game.

The div tag with an id of "grid" will contain the actual game grid, which is populated with squares that may or may not contain mines.

Finally, the script tags at the end of the document import two JavaScript files. The first script imports the jQuery library, which is a popular JavaScript library that simplifies HTML document traversal and manipulation. The second script imports a custom JavaScript file called "script.js", which contains the game logic and functionality.

This is the basic structure of our Minesweeper game using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the Minesweeper game is in place, the next step is to add styling to the game using CSS. CSS allows us to control the visual appearance of the website, including things like layout, color, and typography.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our Minesweeper game board.

The first line sets the character set to UTF-8, which is the standard encoding for Unicode characters.

The * selector, along with *:before and *:after pseudo-elements, applies the box-sizing: inherit property to every element on the page, so that the width and height of an element include its padding and border, instead of just its content box.

The html selector sets the box-sizing property to border-box, which means that padding and border are included in an element's width and height.

The body selector sets the font family, color, background color, and padding for the body of the page.

The h1, p, a, and img selectors define the styles for headings, paragraphs, links, and images respectively.

The .wrap and .legend selectors define styles for containers and text descriptions.

The #scoreboard selector sets the styles for the score board element, including the select dropdown and reset button.

The #grid selector sets the styles for the grid that the user interacts with to play the game. It defines the styles for each cell of the grid, including its size, border, and content. It also sets styles for a disabled state of the grid, and for win or lose conditions.

This will give our Minesweeper game an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

@charset "UTF-8";
*, *:before, *:after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

body {
  text-align: center;
  color: #333;
  padding: 20px 20px 100px;
  background-color: #efefef;
  font-family: "Space Mono", monospace;
}

h1 {
  margin: 0 0 32px;
}

p {
  font-size: 1em;
  line-height: 1.25em;
}

a {
  color: inherit;
}

img {
  height: auto;
  max-width: 100%;
}

.wrap {
  text-align: center;
  position: relative;
  display: inline-block;
}

.legend {
  font-size: 14px;
  margin: 0 auto 32px;
}
.legend h4,
.legend p {
  margin: 0 0 6px;
}
.legend code {
  background: #e3e3e3;
}
.legend code .key {
  color: #ec433c;
}
.legend code .click {
  color: #2a48ec;
}

.top {
  border: 6px solid #e3e3e3;
  background-color: #e3e3e3;
}

#scoreboard {
  display: flex;
  padding-bottom: 12px;
  justify-content: space-between;
}
#scoreboard .select-wrap {
  font-weight: 700;
  vertical-align: top;
  display: inline-block;
}
#scoreboard .select-wrap select {
  margin: 0;
  height: 36px;
  border-radius: 0;
  border-width: 3px;
  border-style: solid;
  background-color: #d1d1d1;
  border-color: white #9e9e9e #9e9e9e white;
}
#scoreboard .select-wrap select:hover, #scoreboard .select-wrap select:focus {
  background-color: #ebebeb;
}
#scoreboard .reset {
  padding: 0 4px;
  font-size: 24px;
  cursor: pointer;
  font-weight: 700;
  line-height: 30px;
  border-width: 3px;
  border-style: solid;
  background-color: #d1d1d1;
  border-color: white #9e9e9e #9e9e9e white;
}
#scoreboard .reset:hover, #scoreboard .reset:focus {
  outline: none;
  background-color: #ebebeb;
}
#scoreboard .counter {
  padding: 0 4px;
  color: #ec433c;
  border: 3px inset;
  line-height: 30px;
  letter-spacing: 0.08em;
  display: inline-block;
  background: #333;
  text-shadow: 0 0 2px #ec433c;
}
#scoreboard .counter:first-of-type {
  margin-right: 20px;
}
#scoreboard .counter:last-of-type {
  margin-left: 20px;
}

#grid {
  margin: 0 auto;
  position: relative;
  display: inline-block;
}
#grid ::-moz-selection {
  background-color: transparent;
}
#grid ::selection {
  background-color: transparent;
}
#grid.disabled .cell {
  pointer-events: none;
}
#grid.disabled .status-indicator {
  top: 50%;
  left: 50%;
  z-index: 11;
  width: 8vw;
  height: 8vw;
  font-size: 4vw;
  cursor: pointer;
  line-height: 8vw;
  position: absolute;
  border-radius: 50%;
  pointer-events: auto;
  background-color: #d1d1d1;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(51, 51, 51, 0.25);
}
#grid.disabled .status-indicator::after {
  content: "";
}
#grid.disabled.win .status-indicator::after {
  content: "๐Ÿ˜Ž";
}
#grid.disabled.lose .status-indicator::after {
  content: "โ˜น๏ธ";
}
#grid .row {
  display: flex;
}
#grid .cell {
  cursor: pointer;
  width: 24px;
  height: 24px;
  position: relative;
  background-color: #d1d1d1;
  border-width: 3px;
  border-style: solid;
  border-color: white #9e9e9e #9e9e9e white;
}
#grid .cell i {
  left: 0;
  bottom: 0;
  margin: 0;
  width: 100%;
  font-size: 14px;
  font-weight: 700;
  font-style: normal;
  position: absolute;
  line-height: 24px;
}
#grid .cell::before {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  content: "";
  position: absolute;
  background-color: #d1d1d1;
}
#grid .cell::after {
  top: 50%;
  left: 50%;
  content: "";
  position: absolute;
  transform: translate(-50%, -50%);
}
#grid .cell:hover::before {
  background-color: #ebebeb;
}
#grid .cell.revealed {
  border: 1px solid #b8b8b8;
}
#grid .cell.revealed::before {
  display: none;
}
#grid .cell.revealed .flag {
  display: none;
}
#grid .cell .flag {
  top: 50%;
  left: 50%;
  z-index: 1;
  width: 10px;
  height: 4px;
  position: absolute;
  border-style: solid;
  border-width: 4px 0 4px 10px;
  transform: translate(-50%, -50%);
  border-color: transparent transparent transparent #ec433c;
}
#grid .cell.maybe .flag {
  border-color: transparent transparent transparent #d7af42;
}
#grid .cell.mine {
  background-color: #ec433c;
}
#grid .cell.mine::after {
  border-radius: 50%;
  width: 12px;
  height: 12px;
  background-color: #333;
}
#grid .cell.incorrect .flag::before, #grid .cell.incorrect .flag::after {
  top: 50%;
  z-index: 1;
  left: -13px;
  height: 2px;
  width: 16px;
  content: "";
  position: absolute;
  background-color: black;
}
#grid .cell.incorrect .flag::before {
  transform: rotate(-45deg);
}
#grid .cell.incorrect .flag::after {
  transform: rotate(45deg);
}
#grid .cell.mousedown {
  border: none;
}

#leaderboard {
  margin-top: 20px;
  text-align: center;
}
#leaderboard h4 {
  margin: 0 0 10px;
}
#leaderboard ul {
  margin: 0;
  padding: 10px;
  display: inline-block;
  background-color: rgba(209, 209, 209, 0.5);
}
#leaderboard ul li {
  padding: 2px;
  list-style: none;
}
#leaderboard ul li span {
  font-weight: 900;
  text-transform: capitalize;
}
#leaderboard ul li.highlight {
  background-color: #fef178;
}
#leaderboard button {
  border: none;
  outline: none;
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: none;
  text-decoration: underline;
}

.cell.white {
  color: #fff;
}

.cell.gray-light {
  color: #efefef;
}

.cell.gray-mid {
  color: #e3e3e3;
}

.cell.gray {
  color: #d1d1d1;
}

.cell.gray-dark {
  color: #808080;
}

.cell.black {
  color: #333;
}

.cell.red {
  color: #ec433c;
}

.cell.maroon {
  color: #a6070f;
}

.cell.purple {
  color: #a42887;
}

.cell.yellow {
  color: #d7af42;
}

.cell.yellow-light {
  color: #fef178;
}

.cell.blue {
  color: #2a48ec;
}

.cell.blue-dark {
  color: #233db7;
}

.cell.green {
  color: #2bb13d;
}

.cell.turquoise {
  color: #28907d;
}

#devbox {
  top: 10px;
  right: 10px;
  position: fixed;
  text-align: left;
  max-width: 300px;
  color: #fff;
  background-color: #333;
}
#devbox p {
  margin: 0;
  font-size: 12px;
  padding: 10px 20px;
}
#devbox p + p {
  padding-top: 5px;
} 

Step 3 (JavaScript Code):

Finally, we need to create a JavaScript function that defines a Minesweeper game, implementing using jQuery.

The code initializes the game by creating a grid of cells and randomly laying mines within the grid.

The code starts by defining a function _init() that caches some frequently used DOM elements, including the game board, the timer, the mine counter, and the level selector. It also sets up the game by defining the different levels of difficulty and the number of mines for each level.

The code then defines a function setLevel(level) that sets the parameters for the game board based on the selected difficulty level, including the number of rows and columns, the number of cells in the grid, and the number of mines.

The setBoard(level) function is used to initialize the game board. It first clears the grid and sets the level parameters based on the selected level. It then builds the grid by creating a number of rows and cells based on the level parameters. It sets the mine counter and the timer, and it sets the game state to unstarted.

The code then defines a number of event listeners that respond to user actions, including changing the level, resetting the game, and clicking on the status indicator. When the game is reset or when the status indicator is clicked, the setBoard(level) function is called to initialize the game board.

The layMines(level, clickedCellIndex) function is used to randomly lay mines within the grid. It first selects all the cells that are not already taken by a mine and randomly selects cells to lay mines until the desired number of mines is reached. It then identifies the cell numbers and counts the number of mines in the neighboring cells for each non-mine cell. The count is stored in the data-cell attribute of the cell.

The game also includes a timer that counts the elapsed time and a mine counter that keeps track of the number of remaining mines. The code updates the timer and the mine counter in real-time as the game progresses. Finally, the game checks for existing high scores in the local storage and displays them if they exist. However, the high score feature is currently commented out.

Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, youโ€™ve to create a file with .js extension.

$(document).ready(function() {

  var $body,
        $document,
        $board,
        $grid,
        timer,
        time,
        unstarted;
  
    function _init() {
      // Cache some common DOM queries
      $document = $(document);
      $body = $('body');
      $body.addClass('loaded');
  
      // Start Minesweeper
      $board = $('#board');
      $grid = $('#grid');
      var $timer = $('#timer');
      var $mineCounter = $('#minecounter');
      var $levelSelect = $('#level');
      var levels = {
        'beginner': '9x9x10',
        'intermediate': '16x16x44',
        'expert': '16x30x99'
      };
      var level = $levelSelect.val();
      var levelParams,
          rows,
          $rows,
          columns,
          cellCount,
          mines,
          freeCells,
          mineTally,
          pauseTime,
          beginnerHighScore = 999,
          intermediateHighScore = 999,
          expertHighScore = 999;
  
      var countColors = {0: '', 1: 'blue', 2: 'green', 3: 'red', 4: 'blue-dark', 5: 'maroon', 6: 'turquoise', 7: 'purple', 8: 'gray-dark'};
  
      time = 0;
      timer = false;
      unstarted = true;
      var statusIndicator = '<div class="status-indicator"></div>';
  
      function setLevel(level) {
        levelParams = levels[level];
        rows = parseInt(levelParams.split('x')[0]);
        columns = parseInt(levelParams.split('x')[1]);
        cellCount = rows*columns;
        mines = levelParams.split('x')[2];
        freeCells = cellCount - mines;
      }
  
      function setBoard(level) {
        // Clear Grid
        $grid.html(statusIndicator).removeClass('disabled lose win').addClass('unstarted');
  
        // Set Up Grid
        setLevel(level);
  
        // Set unstarted
        unstarted = true;
  
        // Build Rows
        for (r=0;r -1) {
            m--;
            continue;
          }
          takenCells.push(mineCell);
          $(freeCells[mineCell]).addClass('mine');
        }
  
        // Identify Cell Numbers
        var $cells = $('.cell');
        for (c=0;c<$cells.length;c++) {
          var $cell = $($cells[c]);
          $cell.attr('data-cell', c);
          // Skip if it's a mine
          if ($cell.is('.mine')) {
            continue;
          }
  
          var mineCount = 0;
          var rowPos = Math.floor(c/columns);
          var $currentRow = $cell.closest('.row');
          $currentRow.attr('data-row', rowPos);
          var rowCells = $currentRow.find('.cell');
          var cellPos = c % columns;
  
          if ($(rowCells[cellPos - 1]).is('.mine')) {
            mineCount++;
          }
          if ($(rowCells[cellPos + 1]).is('.mine')) {
            mineCount++;
          }
  
          if (rowPos > 0) {
            var prevRowCells = $($rows[rowPos - 1]).find('.cell');
            if ($(prevRowCells[cellPos - 1]).is('.mine')) {
              mineCount++;
            }
            if ($(prevRowCells[cellPos]).is('.mine')) {
              mineCount++;
            }
            if ($(prevRowCells[cellPos + 1]).is('.mine')) {
              mineCount++;
            }
          }
  
          if (rowPos < rows - 1) {
            var nextRowCells = $($rows[rowPos + 1]).find('.cell');
            if ($(nextRowCells[cellPos - 1]).is('.mine')) {
              mineCount++;
            }
            if ($(nextRowCells[cellPos]).is('.mine')) {
              mineCount++;
            }
            if ($(nextRowCells[cellPos + 1]).is('.mine')) {
              mineCount++;
            }
          }
  
          if (mineCount > 0) {
            $cell.html('<i>'+mineCount+'</i>');
            // Styling classes
            var colorClass = countColors[mineCount];
            $cell.addClass(colorClass);
          } else {
            $cell.addClass('zero');
          }
        }
      }
  
      // Click cell to start game
      $('html').off('click', '#grid.unstarted .cell').on('click', '#grid.unstarted .cell', function(e) {
        $grid.removeClass('unstarted');
        if (unstarted && !$(e.target).is('.mine')) {
          layMines(level, $('.cell').index(this));
          timer = window.setInterval(startTimer, 1000);
          unstarted = false;
        }
      });
  
      // Timer Functions
      function resetTimer() {
        $timer.html('000');
        time = 0;
      }
      function startTimer() {
        time++;
        if (time < 10) {
          $timer.html('00'+time);
        } else if (time > 9 && time < 100) {
          $timer.html('0'+time);
        } else {
          $timer.html(time);
        }
      }
  
      function stopTimer() {
        window.clearInterval(timer);
      }
  
      function pauseTimer() {
        stopTimer();
        pauseTime = parseInt($('#timer').html());
      }
  
      function unpauseTimer() {
        time = pauseTime;
        timer = window.setInterval(startTimer, 1000);
        pauseTime = false;
      }
  
      // Pause when window loses focus
      $(window).on('blur', function() {
        pauseTimer();
      }).on('focus', function() {
        if (pauseTime) {
          unpauseTimer();
        }
      });
  
      // Check Cell
      function checkCell($cell) {
        if (!$cell.is('.mine') && !$cell.is('.revealed')) {
          cellClick($cell, 'reveal');
  
          if ($cell.is('.zero')) {
            $cell.trigger('click');
          }
        }
      }
  
      // Clicking on a cell
      function cellClick($cell, action) {
        // If Flagging
        if (action === 'flag' && !$cell.is('.revealed')) {
          if ($cell.is('.flagged')) {
            $cell.removeClass('flagged');
            $cell.addClass('maybe');
            mineTally++;
            updateMinecounter(mineTally);
          } else if ($cell.is('.maybe')) {
            $cell.removeClass('maybe');
            var flag = $cell.find('.flag');
            flag.remove();
          } else {
            $cell.addClass('flagged');
            $cell.append('<span class="flag"></span>');
            mineTally--;
            updateMinecounter(mineTally);
          }
          // If Revealing
        } else if (action === 'reveal') {
          $cell.addClass('revealed');
  
          // If it's a mine you lose!
          if ($cell.is('.mine')) {
            lose();
          }
  
          statusCheck();
        } else if (action === 'clear') {
          if (!$cell.is('.revealed') || $cell.is('.zero')) {
            return;
          }
  
          clearClick($cell);
        }
      }
  
      // Update Minecounter
      function updateMinecounter(mineTally) {
        if (mineTally < 10) {
          $mineCounter.html('0'+mineTally);
        } else {
          $mineCounter.html(mineTally);
        }
      }
  
      // Clicking on a Zero cell
      function zeroClick($cell) {
        var cellPos = $cell.prevAll().length;
        var $currentRow = $cell.closest('.row');
        var rowPos = parseInt($currentRow.attr('data-row'));
        var rowCells = $currentRow.find('.cell');
  
        checkCell($(rowCells[cellPos - 1]));
        checkCell($(rowCells[cellPos + 1]));
  
        if (rowPos > 0) {
          var prevRowCells = $($rows[rowPos - 1]).find('.cell');
          checkCell($(prevRowCells[cellPos - 1]));
          checkCell($(prevRowCells[cellPos]));
          checkCell($(prevRowCells[cellPos + 1]));
        }
  
        if (rowPos < rows) {
          var nextRowCells = $($rows[rowPos + 1]).find('.cell');
          checkCell($(nextRowCells[cellPos - 1]));
          checkCell($(nextRowCells[cellPos]));
          checkCell($(nextRowCells[cellPos + 1]));
        }
      }
  
      // Clicking on a number to clear free cells
      function clearClick($cell) {
        var cellPos = $cell.prevAll().length;
        var $currentRow = $cell.closest('.row');
        var rowPos = parseInt($currentRow.attr('data-row'));
        var rowCells = $currentRow.find('.cell');
        var adjacentCells = [];
        var correctClear = true;
        var adjacentMines = 0;
        var adjacentFlags = 0;
        var i;
        adjacentCells.push($(rowCells[cellPos - 1]));
        adjacentCells.push($(rowCells[cellPos + 1]));
  
        if (rowPos > 0) {
          var prevRowCells = $($rows[rowPos - 1]).find('.cell');
          adjacentCells.push($(prevRowCells[cellPos - 1]));
          adjacentCells.push($(prevRowCells[cellPos]));
          adjacentCells.push($(prevRowCells[cellPos + 1]));
        }
  
        if (rowPos < rows) {
          var nextRowCells = $($rows[rowPos + 1]).find('.cell');
          adjacentCells.push($(nextRowCells[cellPos - 1]));
          adjacentCells.push($(nextRowCells[cellPos]));
          adjacentCells.push($(nextRowCells[cellPos + 1]));
        }
  
        for (i = 0; i < adjacentCells.length; i++) {
          // add to mine count
          if ($(adjacentCells[i]).is('.mine')) {
            adjacentMines++;
          }
          // add to flag cout
          if ($(adjacentCells[i]).is('.flagged')) {
            adjacentFlags++;
          }
        }
  
        if (adjacentFlags === adjacentMines) {
          for (i = 0; i < adjacentCells.length; i++) {
            if ($(adjacentCells[i]).is('.mine')) {
              if ($(adjacentCells[i]).is('.flagged')) {
                continue;
              } else {
                $(adjacentCells[i]).addClass('revealed');
                correctClear = false;
              }
            } else if ($(adjacentCells[i]).is('.flagged')) {
              correctClear = false;
              $(adjacentCells[i]).addClass('incorrect');
              lose();
            }
          }
  
          if (correctClear) {
            for (i = 0; i < adjacentCells.length; i++) {
              if (!$(adjacentCells[i]).is('.mine')) {
                if ($(adjacentCells[i]).is('.zero')) {
                  zeroClick($(adjacentCells[i]));
                }
                cellClick($(adjacentCells[i]), 'reveal');
              }
            }
          }
        } else {
          return;
        }
      }
  
      // Check status
      function statusCheck() {
        if ($('.cell.revealed').length == freeCells) {
          stopTimer();
          var winTime = $('#timer').html();
          $grid.addClass('disabled win');
          resetHighScore(level, winTime);
        }
      }
  
      function lose() {
        $grid.addClass('disabled lose');
        stopTimer();
      }
  
      // Clicking on a cell
      $('html').on('click', '.cell', function(e) {
        e.preventDefault();
        var action = 'reveal';
        var $cell = $(this);
  
        if (e.altKey || e.which === 3) {
          action = 'flag';
        } else if ($cell.is('.revealed') || e.which === 1 & e.which === 3) {
          action = 'clear';
        }
  
        if ($cell.is('.flagged') && !e.altKey) {
          return;
        }
  
        if ($cell.is('.zero')) {
          zeroClick($cell);
        }
  
        cellClick($cell, action);
      });
  
      // Mouse down on a cell
      $('html').on('mousedown', '.cell:not(.revealed,.flagged)', function(e) {
        if (!e.altKey && e.which !== 3) {
          $(this).addClass('mousedown');
        }
      }).on('mouseup mouseleave', '.cell.mousedown', function() {
        $(this).removeClass('mousedown');
      });
  
      // Scoreboard functionality
      function resetHighScore(level, winTime) {
        if (localStorage.getItem(level)) {
          if (winTime < localStorage.getItem(level)) {
            localStorage.setItem(level, winTime);
            populateHighScore(level, winTime, true);
          }
        } else {
          localStorage.setItem(level, winTime);
          populateHighScore(level, winTime, true);
        }
      }
  
      function populateHighScore(level, highScore, highlight) {
        if (!$('#leaderboard').length) {
          $board.find('.bottom').append('<div id="leaderboard"><h4>High Scores</h4><ul><li class="beginner"></li><li class="intermediate"></li><li class="expert"></li></ul><div><button id="score-reset" class="score-reset">Clear Scores</button></div></div>');
        }
        if (highlight === true) {
          $('#leaderboard .highlight:not(.'+level+')').removeClass('highlight');
          $('#leaderboard .'+level).addClass('highlight');
        }
        var highScoreDisplay = parseInt(highScore,10);
        $('#leaderboard .'+level).html('<span>'+level+'</span>: '+highScoreDisplay+' seconds');
      }
  
      function clearScores() {
        localStorage.clear();
        $('#leaderboard').remove();
      }
  
      // Clicking on score reset to clear scores
      $('html').on('click', '#score-reset', clearScores);
    }
  
    _init();
  });

Final Output:

learn how to create a minesweeper game with html, css, and javascript.gif

Conclusion:

Congratulations, you have successfully created your own Minesweeper game using HTML, CSS, and JavaScript! In this tutorial, we walked you through the process of setting up the project, styling the game board, adding game logic with JavaScript, testing and refining the game, and deploying it online.

Creating a game like Minesweeper requires a solid understanding of HTML, CSS, and JavaScript, and we hope this tutorial has helped you gain a better understanding of these web development technologies. We encourage you to continue learning and experimenting with these technologies to create more exciting and interactive web projects.

Remember, it's important to test and refine your game thoroughly before deploying it online. This will ensure that your game works as intended and provides an enjoyable experience for players.

We hope you had fun creating your own Minesweeper game and learned something new along the way. Thank you for following along with this tutorial, and we wish you the best of luck in your future web development projects!

Thatโ€™s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below ๐Ÿ”ฅ and you can support me by buying me a coffee.

And donโ€™t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz ๐Ÿ˜Š

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post