UNPKG

minesweeperjs-engine

Version:

A Javascript implementation of the rules and logic of the classic minesweeper game.

1 lines 5.54 kB
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["minesweeperjs-engine"]=t():e["minesweeperjs-engine"]=t()}(self,(function(){return(()=>{"use strict";var e={917:(e,t,s)=>{s.r(t),s.d(t,{default:()=>r});class i{constructor(e,t){this.x=e,this.y=t,this.value=0,this.isVisible=!1,this.isFlagged=!1}getX(){return this.x}getY(){return this.y}getValue(){return this.value>=10?"X":this.value}setValue(e){this.value=e}getIsVisible(){return this.isVisible}setIsVisible(e){this.isVisible=e}getIsFlagged(){return this.isFlagged}setIsFlagged(e){this.isFlagged=e}increment(){this.value++}decrement(){this.value<10&&this.value--}toggleFlag(){this.isFlagged=!this.isFlagged}getIsClickable(){return!this.isFlagged&&!this.isVisible}}class r{constructor(e,t,s){this.newGame(e,t,s)}newGame(e,t,s){this.board=new Array(t);for(let s=0;s<t;s++){this.board[s]=new Array(e);for(let t=0;t<e;t++)this.board[s][t]=new i(t,s)}this.x=e,this.y=t,this.addMines(s),this.mineCount=s,this.started=!1,this.over=!1,this.squaresLeft=e*t-s,this.moveCount=0,this.edges=this.createEdgesBoard(e,t),this.lastXPlayed=-1,this.lastYPlayed=-1,this.time=null}getCell(e,t){return this.board[t][e]}getWidth(){return this.x}getLength(){return this.y}getLastPositionPlayed(){return{x:this.lastXPlayed,y:this.lastYPlayed}}getNeighborCount(e,t){return this.edges[t][e]}getBoard(){return this.board}addMines(e){for(;e>0;){let t=Math.floor(Math.random()*this.x),s=Math.floor(Math.random()*this.y);"X"!==this.board[s][t].getValue()&&(e--,this.board[s][t].setValue(10),this.getNeighbors(t,s).forEach((e=>{e.increment()})))}}getNeighbors(e,t){let s=[];for(let i=Math.max(0,t-1);i<Math.min(t+2,this.y);i++)for(let r=Math.max(0,e-1);r<Math.min(e+2,this.x);r++)i===t&&r===e||s.push(this.board[i][r]);return s}createEdgesBoard(e,t){let s=new Array(this.y).fill(null).map((()=>Array(this.x).fill(0)));for(let i=0;i<t;i++)for(let t=0;t<e;t++)s[i][t]=this.getNeighbors(t,i).reduce(((e,t)=>e+!t.getIsVisible()),0);return s}isEdge(e,t){return this.board[t][e].getIsVisible()&&this.edges[t][e]>0}updateEdges(e,t){for(let s=Math.max(0,t-1);s<Math.min(t+2,this.y);s++)for(let i=Math.max(0,e-1);i<Math.min(e+2,this.x);i++)s===t&&i===e||"X"===this.board[s][i].getValue()||this.edges[s][i]--}changeBoard(e,t){let s=!1;for(;!s;){let i=Math.floor(Math.random()*this.y),r=Math.floor(Math.random()*this.x);if("X"!==this.board[i][r].getValue()){s=!0,this.board[i][r].setValue(10),this.getNeighbors(r,i).forEach((e=>{e.increment()}));let a=this.getNeighbors(e,t);this.getNeighbors(e,t).forEach((e=>{e.decrement()})),this.board[t][e].setValue(a.reduce(((e,t)=>e+("X"===t.getValue())),0))}}}getClickableNeighbors(e,t){let s=[];return this.board[t][e].getIsVisible()&&this.getNeighboringFlagCount(e,t)===this.board[t][e].getValue()&&(s=this.getNeighbors(e,t).filter((e=>e.getIsClickable())).map((e=>({x:e.getX(),y:e.getY()})))),s}getNeighboringFlagCount(e,t){return this.getNeighbors(e,t).reduce(((e,t)=>e+t.getIsFlagged()),0)}clearNeighbors(e,t){this.lastXPlayed=e,this.lastYPlayed=t;const s=this.getClickableNeighbors(e,t);let i=[];return s.forEach((e=>{i=i.concat(this.click(e.x,e.y))})),i.sort(((e,t)=>e.state?-1:t.state?1:0)),i}toggleFlag(e,t){return this.lastXPlayed=e,this.lastYPlayed=t,this.board[t][e].toggleFlag(),[{x:e,y:t,value:this.board[t][e].getIsFlagged()}]}click(e,t){let s=[];return this.board[t][e].getIsClickable()&&(this.moveCount++,s=this.gameMechanics(e,t),this.lastXPlayed=e,this.lastYPlayed=t),s}gameMechanics(e,t){let s=[],i=this.board[t][e].getValue();return this.board[t][e].setIsVisible(!0),this.board[t][e].setIsFlagged(!1),1===this.moveCount&&(this.startTimer(),"X"===i&&(this.changeBoard(e,t),i=this.board[t][e].getValue())),"X"===i?this.gameOver(e,t):(0===i?s=this.explode(e,t,[]):(s.push({x:e,y:t,value:i}),this.squaresLeft--,this.updateEdges(e,t)),0===this.squaresLeft&&(s=s.concat(this.gameWon(e,t))),s)}explode(e,t,s){this.board[t][e].setIsVisible(!0),this.squaresLeft--,this.updateEdges(e,t);let i=this.board[t][e].getValue();return s.push({x:e,y:t,value:i}),0===i&&this.getNeighbors(e,t).forEach((e=>{e.getIsVisible()||(s=this.explode(e.getX(),e.getY(),s))})),s}gameOver(e,t){this.over=!0;let s=[];for(let e=0;e<this.y;e++)for(let t=0;t<this.x;t++)this.board[e][t].getIsVisible()||s.push({x:t,y:e,value:this.board[e][t].getValue()});return s.push({x:e,y:t,state:"LOSE",time:this.stopTimer()}),s}gameWon(e,t){this.over=!0;let s=[];for(let e=0;e<this.y;e++)for(let t=0;t<this.x;t++)this.board[e][t].getIsVisible()||s.push({x:t,y:e,value:this.board[e][t].getValue()});return s.push({x:e,y:t,state:"WIN",time:this.stopTimer()}),s}startTimer(){this.started=!0,this.time=new Date}stopTimer(){return Math.floor((new Date-this.time)/1e3)}toString(){let e="---".repeat(this.x+2);for(let t=0;t<this.y;t++){e+="\n| ";for(let s=0;s<this.x;s++){let i="*";this.board[t][s].getIsVisible()?i=this.board[t][s].getValue():this.board[t][s].getIsFlagged()&&(i="F"),e+=" "+i+" "}e+=" |"}return e+="\n"+"---".repeat(this.x+2),e}}}},t={};function s(i){if(t[i])return t[i].exports;var r=t[i]={exports:{}};return e[i](r,r.exports,s),r.exports}return s.d=(e,t)=>{for(var i in t)s.o(t,i)&&!s.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s(917)})()}));