Permalink
Browse files

First commit — 35 min. so far

  • Loading branch information...
0 parents commit 4e620a71a81a7628e3865c2c1de4fcef9c8742a1 @mishoo committed Dec 18, 2015
Showing with 231 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +15 −0 index.html
  3. +28 −0 minesweeper.css
  4. +146 −0 minesweeper.js
  5. +40 −0 minesweeper.scss
@@ -0,0 +1,2 @@
+.sass-cache/
+*.css.map
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <link rel="stylesheet" href="minesweeper.css" />
+ </head>
+ <body>
+ <script src="minesweeper.js"></script>
+ <script>
+ var board = new Minesweeper(20, 20);
+ var div = document.createElement("div");
+ div.innerHTML = board.render();
+ document.body.appendChild(div);
+ </script>
+ </body>
+</html>
@@ -0,0 +1,28 @@
+.minesweeper-board {
+ border: 2px solid #000;
+ margin: 2em;
+ display: inline-block;
@irvincalloway
irvincalloway Sep 24, 2016

Border: 2pk solid #000;

+ border-radius: 4px;
+ padding: 1px;
+ font: 13px sans-serif;
+ text-align: center; }
+ .minesweeper-board .row .cell {
+ display: table-cell;
+ vertical-align: middle;
+ width: 20px;
+ height: 20px;
+ box-sizing: border-box;
+ border-left: 1px solid #888;
+ border-top: 1px solid #888;
+ background: #aaa;
+ color: #4444ff; }
+ .minesweeper-board .row .cell:last-child {
+ border-right: 1px solid #888; }
+ .minesweeper-board .row .cell.uncovered {
+ background: #fff; }
+ .minesweeper-board .row .cell.bomb {
+ color: #f00; }
+ .minesweeper-board .row:last-child .cell {
+ border-bottom: 1px solid #888; }
+
+/*# sourceMappingURL=minesweeper.css.map */
@@ -0,0 +1,146 @@
+function Minesweeper(nrows, ncols) {
+ var boardLength = nrows * ncols;
+ var board = new Array(boardLength);
+ for (var i = boardLength; --i >= 0;) {
+ board[i] = (Math.random() <= 0.1 ? 1 : 0);
+ }
+
+ function index(row, col) {
+ return row * ncols + col;
+ }
+
+ function getField(row, col) {
+ return board[index(row, col)];
+ }
+
+ function setField(row, col, value) {
+ return board[index(row, col)] = value;
+ }
+
+ function isBomb(row, col) {
+ return getField(row, col) & 1;
+ }
+
+ function isUncovered(row, col) {
+ return getField(row, col) & 2;
+ }
+
+ function uncover(row, col) {
+ setField(row, col, getField(row, col) | 2);
+ }
+
+ function forEach(f) {
+ for (var i = 0; i < nrows; ++i) {
+ for (var j = 0; j < ncols; ++j) {
+ f(i, j);
+ }
+ }
+ }
+
+ function nearBombs(row, col) {
+ var count = 0;
+ if (row > 0) {
+ if (isBomb(row - 1, col)) count++;
+ }
+ if (row < nrows - 1) {
+ if (isBomb(row + 1, col)) count++;
+ }
+ if (col > 0) {
+ if (isBomb(row, col - 1)) count++;
+ }
+ if (col < ncols - 1) {
+ if (isBomb(row, col + 1)) count++;
+ }
+ return count;
+ }
+
+ // XXX: switch to virtual DOM
+ function renderInner() {
+ var out = "";
+ for (var i = 0; i < nrows; ++i) {
+ out += "<div class='row'>";
+ for (var j = 0; j < ncols; ++j) {
+ out += "<div class='cell";
+ if (isUncovered(i, j)) {
+ out += " uncovered";
+ if (isBomb(i, j)) {
+ out += " bomb";
+ }
+ }
+ out += "' data-row='" + i + "' data-col='" + j + "'>";
+ if (isUncovered(i, j)) {
+ if (isBomb(i, j)) {
+ out += "&#x1F4A3;";
+ } else {
+ var count = nearBombs(i, j);
+ if (count > 0) {
+ out += count;
+ }
+ }
+ }
+ out += "</div>";
+ }
+ out += "</div>";
+ }
+ return out;
+ }
+
+ function render() {
+ var out = "";
+ out += "<div class='minesweeper-board'>";
+ out += renderInner();
+ out += "</div>";
+ return out;
+ }
+
+ function leftClick(row, col, boardEl) {
+ if (isUncovered(row, col)) {
+ return;
+ }
+ uncover(row, col);
+ if (isBomb(row, col)) {
+ forEach(function(row, col){
+ uncover(row, col);
+ });
+ }
+ boardEl.innerHTML = renderInner();
+ }
+
+ function rightClick(row, col) {
+ if (isUncovered(row, col)) {
+ return;
+ }
+ }
+
+ document.addEventListener("mousedown", onMouseDown);
+ document.addEventListener("contextmenu", onContextMenu);
+
+ function onMouseDown(ev) {
+ var boardEl = onContextMenu(ev);
+ if (boardEl) {
+ var div = ev.target.closest("div.cell");
+ var row = parseFloat(div.dataset.row);
+ var col = parseFloat(div.dataset.col);
+ if (div) {
+ if (ev.button == 0) {
+ leftClick(row, col, boardEl, div);
+ } else if (ev.button == 2) {
+ rightClick(row, col, boardEl, div);
+ }
+ }
+ }
+ }
+
+ function onContextMenu(ev) {
+ var boardEl = ev.target.closest("div.minesweeper-board");
+ if (boardEl) {
+ ev.stopPropagation();
+ ev.preventDefault();
+ return boardEl;
+ }
+ }
+
+ return {
+ render: render
+ };
+}
@@ -0,0 +1,40 @@
+.minesweeper-board {
+ border: 2px solid #000;
+ margin: 2em;
+ display: inline-block;
+ border-radius: 4px;
+ padding: 1px;
+ font: 13px sans-serif;
+ text-align: center;
+
+ .row {
+ .cell {
+ display: table-cell;
+ vertical-align: middle;
+ width: 20px;
+ height: 20px;
+ box-sizing: border-box;
+ border-left: 1px solid #888;
+ border-top: 1px solid #888;
+ background: #aaa;
+ color: #4444ff;
+
+ &:last-child {
+ border-right: 1px solid #888;
+ }
+
+ &.uncovered {
+ background: #fff;
+ }
+
+ &.bomb {
+ color: #f00;
+ }
+ }
+ &:last-child {
+ .cell {
+ border-bottom: 1px solid #888;
+ }
+ }
+ }
+}

0 comments on commit 4e620a7

Please sign in to comment.