minesweeper
v1.0.5
Published
Provides functionality that can be used to create a Minesweeper clone.
Downloads
20
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 toy
The zero-based row index that this cell belongs toisMine
Boolean that specifies if this cell is a mine or notnumAdjacentMines
The number of adjacent mine cells (0 - 8)state
Type ofminesweeper.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 ofminesweeper.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 stateBoardStateEnum.IN_PROGRESS
The board has been interacted with, and is not in a winning or losing stateBoardStateEnum.LOST
The board is in a losing state, meaning that a mine cell has been openedBoardStateEnum.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