npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

minesweeper

v1.0.5

Published

Provides functionality that can be used to create a Minesweeper clone.

Downloads

36

Readme

Minesweeper

A collection of objects that provide the logic needed to create a Minesweeper clone.

All you need to do in your project is write the UI.

Dependencies

Minesweeper is written in vanilla JS and has no dependencies. Works with node and in the browser.

Why

With so many front-end frameworks and view layer libraries to choose from, I am able to use this library to play around with them without needing to write a lot of irrelevant logic code.

How

Step 1: Include the library

Available as an npm package using

npm install minesweeper

or a bower package using

bower install minesweeper-lib

Alternatively, you can just download the file from the dist directory and manually include it in your project using

<script src="minesweeper.js"></script>

Step 2: Access the library

If you're using modules in your project, you'll need to

var minesweeper = require('minesweeper');

or the equivalent using an AMD style script loader such as require.js.

If you're directly including the source file using a script tag, it will be accessible at

window.minesweeper

Step 3: Create a mine array

Create a mine array by passing some options to minesweeper.generateMineArray.

All properties are optional, and will use the defaults specified below if not provided.

var mineArray = minesweeper.generateMineArray({
    rows: 10,
    cols: 10,
    mines: 15
});

Step 4: Create a new board using the mine array

Create a board using the mine array you just created.

var board = new minesweeper.Board(mineArray);

Step 5: Render the board

Get a copy of the board grid with a call to board.grid()

var grid = board.grid();

This will return a two-dimensional array filled with minesweeper.Cell objects that you can use to render the board.

Each cell has the following properties:

  • x The zero-based column index that this cell belongs to
  • y The zero-based row index that this cell belongs to
  • isMine Boolean that specifies if this cell is a mine or not
  • numAdjacentMines The number of adjacent mine cells (0 - 8)
  • state Type of minesweeper.CellStateEnum which determines whether this cell has been opened by the user or not. Can be one of:
    • minesweeper.CellStateEnum.CLOSED
    • minesweeper.CellStateEnum.OPEN
  • flag Type of minesweeper.CellFlagEnum which determines if the user has flagged this cell with an exclamation or question mark. Can be one of:
    • minesweeper.CellFlagEnum.NONE
    • minesweeper.CellFlagEnum.EXCLAMATION
    • minesweeper.CellFlagEnum.QUESTION

Assuming you know the rules of Minesweeper, that's all the information you need to render the board. For example, you could now render the board to the browser console with the following code

var BoardStateEnum = minesweeper.BoardStateEnum;
var CellStateEnum = minesweeper.CellStateEnum;
var CellFlagEnum = minesweeper.CellFlagEnum;
var Board = minesweeper.Board;
var Cell = minesweeper.Cell;
var generateMineArray = minesweeper.generateMineArray;

var printBoard = function (board) {
  var i,
      strColHead = '   ',
      grid = board.grid();

  // print a header that shows the column numbers 
  for (i = 0; i < board.numCols(); i++) {
    strColHead += '   ' + i + '   ';
  }
  console.log(strColHead);

  // print all the rows on the board
  for (i = 0; i < board.numRows(); i++) {
    printRow(grid[i], i);
  }
};

var printRow = function (rowArray, rowNum) {
  var i,
      cell,
      strRow = '';

  // Start the row with the row number
  strRow += rowNum !== undefined ? ' ' + rowNum + ' ' : '';

  // Add each cell in the row to the string we will print
  for (i=0; i<rowArray.length; i++) {
    cell = rowArray[i];
    if (cell.state === CellStateEnum.CLOSED) {
      if (cell.flag === CellFlagEnum.NONE) {
        strRow += getCellString(' ');
      } else if (cell.flag === CellFlagEnum.EXCLAMATION) {
        strRow += getCellString('!');
      } else if (cell.flag === CellFlagEnum.QUESTION) {
        strRow += getCellString('?');
      }
    } else if (cell.state === CellStateEnum.OPEN) {
      if (cell.isMine) {
        strRow += getCellString('*');
      } else {
        strRow += getCellString(cell.numAdjacentMines);
      }
    }
  }

  // Print this row to the console
  console.log(strRow);
};

var getCellString = function (content) {
  return ' [ ' + content + ' ] ';
};

var mineArray = minesweeper.generateMineArray({
    rows: 5,
    cols: 5,
    mines: 5
});

var board = new Board(mineArray);

printBoard(board);

Step 6: Playing the game

There are two methods on the Board object that you use to play the game:

board.openCell(x,y)
board.cycleCellFlag(x,y)

x represents the column number, and y represents the row number. Both are zero-based indexes.

After each move, the internal state of the board and grid will update according to the rules of Minesweeper.

You can get the latest version of the grid by calling board.grid() again and re-rendering to the screen.

Step 7: Check the game state

You can check the state of the board at anytime by calling

board.state()

which returns an enum of type BoardStateEnum

  • BoardStateEnum.PRISTINE Before any interaction (open cell, flag cell) the board is in this state
  • BoardStateEnum.IN_PROGRESS The board has been interacted with, and is not in a winning or losing state
  • BoardStateEnum.LOST The board is in a losing state, meaning that a mine cell has been opened
  • BoardStateEnum.WON The board is in a winning state, meaning that all non-mine cells have been opened, and all mine cells have been flagged with an exclamation

Once the board enters either BoardStateEnum.LOST or BoardStateEnum.WON, any further attempts to modify the board using board.openCell(x,y) or board.cycleCellFlag(x,y)` will not be successful.

Learn

The code is free and open-source under the MIT license, so feel free to use it in any way you like. Whether that be in your own learning projects, in learning materials you put together for others, or in a published Minesweeper clone.

Contributing

Any contributions to the code or this documentation are more than welcome. For bug fixes make sure you write new test cases that will prevent regression, and all existing tests should still be passing. Then submit your PR.

For breaking changes or new features, please raise an issue first. But I'm very friendly and will be receptive to your suggestions!

Author

Feel free to connect with me on Twitter (@binaryluke), or learn more about me at lukehoward.name