2015-02-28 15:40:37 +00:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>endless mines</title>
|
|
|
|
<style type="text/css">
|
|
|
|
@font-face {
|
|
|
|
font-family: Helsinki;
|
|
|
|
font-weight: normal;
|
|
|
|
src: url(helsinki.ttf);
|
|
|
|
}
|
|
|
|
|
|
|
|
html {
|
|
|
|
background-color: #272822;
|
|
|
|
margin: 0;
|
|
|
|
height: 100vh;
|
|
|
|
width: 100vw;
|
|
|
|
}
|
|
|
|
|
|
|
|
body {
|
|
|
|
height: 100vh;
|
|
|
|
margin: 0 auto;
|
|
|
|
width: 100vmin;
|
|
|
|
}
|
|
|
|
|
|
|
|
#game {
|
|
|
|
background-color: #2b2113;
|
|
|
|
float: left;
|
|
|
|
margin: 0 auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
ul {
|
|
|
|
float: left;
|
|
|
|
clear: both;
|
|
|
|
list-style-type: none;
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
li {
|
|
|
|
color: white;
|
|
|
|
font-size: 8vmin;
|
|
|
|
font-family: Helsinki;
|
|
|
|
padding: 1vmin;
|
2015-02-28 16:53:40 +00:00
|
|
|
padding-top: 0.5vmin;
|
|
|
|
padding-bottom: 1.5vmin;
|
2015-02-28 15:40:37 +00:00
|
|
|
text-align: center;
|
|
|
|
vertical-align: middle;
|
|
|
|
float: left;
|
|
|
|
height: 8vmin;
|
|
|
|
width: 8vmin;
|
|
|
|
background-color: #4e3c23;
|
|
|
|
border-radius: 2vmin;
|
|
|
|
cursor: default;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.revealed {
|
|
|
|
background-color: #2b2113;
|
|
|
|
}
|
|
|
|
|
|
|
|
li:not(.revealed):hover {
|
|
|
|
background-color: #614a2c;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.flagged {
|
|
|
|
background-color: #b5fe52;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.flagged:hover {
|
|
|
|
background-color: #c6fe7a;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.mine.revealed {
|
|
|
|
background-color: #d23000;
|
|
|
|
}
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
li.mines1 {
|
|
|
|
color: #c6fe7a;
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
li.mines2 {
|
|
|
|
color: #7ac5fe;
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
li.mines3 {
|
|
|
|
color: #fe7ac6;
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
2015-02-28 19:20:27 +00:00
|
|
|
|
|
|
|
li.mines4 {
|
|
|
|
color: #b17afe;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.mines5 {
|
|
|
|
color: #feb27a;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.mines6 {
|
|
|
|
color: #7afeb2;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.mines7 {
|
|
|
|
color: #d74600;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.mines8 {
|
|
|
|
color: #8c4600;
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
</style>
|
|
|
|
<script src="jquery-2.1.3.min.js"></script>
|
|
|
|
<script>
|
2015-02-28 19:20:27 +00:00
|
|
|
var gameBoardWidth = 10;
|
|
|
|
var gameBoardHeight = 10;
|
|
|
|
var gameBoard = [];
|
|
|
|
var score = 0;
|
|
|
|
var firstClick = true;
|
2015-02-28 15:40:37 +00:00
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
$(document).ready(function() {
|
2015-02-28 15:40:37 +00:00
|
|
|
function newTile() {
|
|
|
|
var tile = {};
|
|
|
|
|
|
|
|
tile.revealed = false;
|
|
|
|
tile.mine = (Math.random() < 0.2);
|
|
|
|
|
|
|
|
return tile;
|
|
|
|
}
|
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
function newRow() {
|
|
|
|
var newRow = [];
|
2015-02-28 15:40:37 +00:00
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
for (var i = 0; i < gameBoardWidth; i++) {
|
|
|
|
newRow.push(newTile());
|
|
|
|
};
|
|
|
|
|
|
|
|
return newRow;
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
function initGameBoard() {
|
|
|
|
for (var i = 0; i < gameBoardHeight; i++) {
|
|
|
|
gameBoard.push(newRow());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawGameBoard() {
|
|
|
|
$('#game').html("");
|
|
|
|
|
|
|
|
for (var i = 0; i < gameBoard.length; i++) {
|
|
|
|
$('#game').append("<ul></ul>");
|
|
|
|
}
|
|
|
|
|
|
|
|
$('#game ul').each(function() {
|
|
|
|
for (var i = 0; i < gameBoard[0].length; i++) {
|
|
|
|
if (gameBoard[$(this).index()][i].mine) {
|
|
|
|
$(this).append('<li class="mine"></li>');
|
|
|
|
} else {
|
|
|
|
$(this).append("<li></li>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.checkRow = function() {
|
2015-02-28 19:20:27 +00:00
|
|
|
//unclicked tiles
|
|
|
|
if ($(this).parent('ul').children('li:not(.revealed):not(.flagged)').length > 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
//incorrectly flagged tiles
|
|
|
|
if ($(this).parent('ul').children('li.flagged:not(.mine)').length > 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//clicked mines
|
|
|
|
if ($(this).parent('ul').children('li.revealed.mine').length > 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.rowScore = function() {
|
|
|
|
return $(this).children('.mine').length;
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.rowAbove = function() {
|
|
|
|
return $(this).parent('ul').prev();
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.rowBelow = function() {
|
|
|
|
return $(this).parent('ul').next();
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.getX = function() {
|
|
|
|
return $(this).index();
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.getY = function() {
|
|
|
|
return $(this).parent('ul').index();
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.getGameboardPos = function() {
|
|
|
|
return gameBoard[$(this).getY()][$(this).getX()];
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.isMine = function() {
|
|
|
|
return $(this).getGameboardPos().mine
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.countMinesAdjacent = function() {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
$.each($(this).getAdjacentTiles(), function() {
|
|
|
|
if ($(this).isMine()) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.getAdjacentTiles = function() {
|
2015-02-28 16:53:40 +00:00
|
|
|
var adjacentTiles = $('');
|
2015-02-28 15:40:37 +00:00
|
|
|
|
|
|
|
//row above
|
|
|
|
if ($(this).getY() > 0) {
|
|
|
|
if ($(this).getX() > 0) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowAbove().children().eq($(this).getX() - 1).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowAbove().children().eq($(this).getX()).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
|
|
|
|
if ($(this).getX() < (gameBoard[0].length - 1)) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowAbove().children().eq($(this).getX() + 1).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//this row
|
|
|
|
if ($(this).getX() > 0) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).prev().toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($(this).getX() < (gameBoard[0].length - 1)) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).next().toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//row below
|
|
|
|
if ($(this).getY() < (gameBoard.length - 1)) {
|
|
|
|
if ($(this).getX() > 0) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowBelow().children().eq($(this).getX() - 1).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowBelow().children().eq($(this).getX()).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
|
|
|
|
if ($(this).getX() < (gameBoard[0].length - 1)) {
|
2015-02-28 16:53:40 +00:00
|
|
|
adjacentTiles = adjacentTiles.add($(this).rowBelow().children().eq($(this).getX() + 1).toArray());
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return adjacentTiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.countMinesText = function() {
|
|
|
|
return $(this).countMinesAdjacent().toString().replace("0", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.leftClick = function() {
|
2015-02-28 16:53:40 +00:00
|
|
|
//don't want first click to be a mine
|
|
|
|
if (firstClick && $(this).getGameboardPos().mine) {
|
|
|
|
$(this).getGameboardPos().mine = false;
|
2015-02-28 19:20:27 +00:00
|
|
|
$(this).removeClass("mine");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(this).hasClass("flagged")) {
|
|
|
|
return;
|
2015-02-28 16:53:40 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 15:40:37 +00:00
|
|
|
$(this).getGameboardPos().revealed = true;
|
|
|
|
$(this).addClass("revealed");
|
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
if ($(this).getGameboardPos().mine == true) {
|
2015-02-28 15:40:37 +00:00
|
|
|
//game over, or lose a life, or whatever
|
|
|
|
$(this).addClass("mine");
|
|
|
|
} else {
|
|
|
|
$(this).text(
|
|
|
|
$(this).countMinesText()
|
|
|
|
);
|
|
|
|
|
2015-02-28 16:53:40 +00:00
|
|
|
$(this).addClass("mines" + $(this).countMinesAdjacent());
|
2015-02-28 19:20:27 +00:00
|
|
|
|
|
|
|
//if no mines adjacent, cascade!
|
|
|
|
if ($(this).countMinesAdjacent() == 0) {
|
|
|
|
$(this).getAdjacentTiles().filter(':not(.revealed)').mousedown();
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
2015-02-28 19:20:27 +00:00
|
|
|
if (false && $(this).checkRow()) {
|
|
|
|
//hide this row and add a new one at the bottom
|
|
|
|
|
|
|
|
var x = $(this).getX();
|
|
|
|
var y = $(this).getY();
|
|
|
|
|
|
|
|
//remove row from game board
|
|
|
|
//gameBoard.splice(y, 1);
|
|
|
|
console.debug(gameBoard);
|
|
|
|
|
|
|
|
//add new row at bottom
|
|
|
|
gameBoard.push(newRow());
|
|
|
|
|
|
|
|
$(this).parent('ul').slideUp("slow", function() {$(this).remove();});
|
|
|
|
|
|
|
|
//redo the numbers on the rows above and below
|
|
|
|
|
|
|
|
//add new row on bottom
|
|
|
|
$('#game').append('<ul></ul>');
|
|
|
|
|
|
|
|
for (var i = 0; i < gameBoard[0].length; i++) {
|
|
|
|
if (gameBoard[gameBoardHeight][i].mine) {
|
|
|
|
$('#game ul:last-child').append('<li class="mine"></li>');
|
|
|
|
} else {
|
|
|
|
$('#game ul:last-child').append('<li></li>');
|
|
|
|
}
|
|
|
|
}
|
2015-02-28 16:53:40 +00:00
|
|
|
}
|
2015-02-28 19:20:27 +00:00
|
|
|
|
|
|
|
firstClick = false;
|
2015-02-28 16:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.middleClick = function() {
|
|
|
|
//number of flags matches number of adjacent mines
|
|
|
|
if ($(this).text() == $(this).getAdjacentTiles().filter('.flagged').length) {
|
|
|
|
$(this).getAdjacentTiles().filter(':not(.flagged)').each(function() {
|
|
|
|
$(this).mousedown();
|
|
|
|
});
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.rightClick = function() {
|
2015-02-28 16:53:40 +00:00
|
|
|
if (!$(this).hasClass("revealed")) {
|
|
|
|
$(this).toggleClass("flagged");
|
|
|
|
}
|
2015-02-28 15:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$(document).on("contextmenu", "li", function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
});
|
|
|
|
|
|
|
|
$(document).on("mousedown", "li", function(event) {
|
|
|
|
switch (event.which) {
|
2015-02-28 16:53:40 +00:00
|
|
|
case 3:
|
2015-02-28 15:40:37 +00:00
|
|
|
$(this).rightClick();
|
|
|
|
break;
|
2015-02-28 16:53:40 +00:00
|
|
|
case 2:
|
|
|
|
$(this).middleClick();
|
|
|
|
break;
|
|
|
|
case 1:
|
2015-02-28 15:40:37 +00:00
|
|
|
default:
|
|
|
|
$(this).leftClick();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
initGameBoard();
|
|
|
|
drawGameBoard();
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="game"></div>
|
|
|
|
</body>
|
|
|
|
</html>
|