Compare commits

...

1 Commits

Author SHA1 Message Date
Max Bradbury 444ac17143 wip 2020-07-28 19:12:01 +01:00
18 changed files with 1367 additions and 1514 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
images/Thumbs.db
includes/images/Thumbs.db
/index.html
/.idea/

22
GREETZ.nfo Normal file
View File

@ -0,0 +1,22 @@
......................................................................
a game by max bradbury
......................................................................
inspired by minesweeper, tetris and 2048
......................................................................
gratz 'n' greetz go out to mum and dad, guy, titas, dan, nick, enrico,
ahona, robin, arielle, isy, thom, tom, olu, lovely dave, jen, ed,
david, andy, rachel, isaac, rory, 'partay' pat, al, ant, zoe, john,
charlie, wilkie, george
......................................................................
HELLO's fly out to some cool game devs: porpentine, merritt kopas,
zoe quinn, aniwey, orteil
......................................................................
i listened to a lot of keygenjukebox while coding this
......................................................................
more games coming soon... keep your eyes peeled... peace!
......................................................................
......................................................................
......................................................................
this story is dedicated to all those cyberpunks who fight against
injustice and corruption every day of their lives
......................................................................

3
build.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
pug index.pug

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

2
includes/jquery-3.5.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

631
includes/script.js Normal file
View File

@ -0,0 +1,631 @@
const $buttonCancel = $('button.cancel');
const $game = $('#game');
const $gameOver = $('#gameOver');
const $ul = $('ul');
const $tutorial = $('#tutorial');
let gameBoardWidth = 10;
let gameBoardHeight = 9;
let score = 0;
let firstClick = true;
let mineChance = 0.2; // normal
let clickHoldMs = 200;
let mouseHeld = false;
let timeout; // hold timer
let viewportSizingAvailable = (parseInt($game.height) === parseInt($(window).height())); // only run once
let tutorialPages = [];
function drawGameBoard() {
$game.html("");
$('#tutorial .gameBoard').html("");
gameBoardWidth = 10;
// determine aspect ratio so as to fit the screen
gameBoardHeight = determineGameBoardHeight();
for (let i = 0; i < gameBoardHeight; i++) {
$game.append(newRow());
}
}
function determineGameBoardHeight() {
return Math.max(
Math.floor((1 / getAspectRatio()) * 10) - 1,
9 // minimum
);
}
function newTile() {
if (Math.random() < mineChance) {
return '<li class="mine"></li>';
} else {
return '<li></li>';
}
}
function newRow() {
let row = '<ul>';
for (let i = 0; i < gameBoardWidth; i++) {
row += newTile();
}
row += '</ul>';
return row;
}
function saveGame() {
if (typeof(Storage) === "undefined") {
return;
}
// variables
localStorage.setItem("score", score);
localStorage.setItem("mineChance", mineChance);
// game board
localStorage.setItem("gameBoard", $game.html());
}
function loadGame() {
// check if storage available and if saved game exists
if (typeof(Storage) === "undefined" || localStorage.getItem("gameBoard") === null) {
drawGameBoard();
return;
}
// variables
score = parseInt(localStorage.getItem("score"));
mineChance = parseFloat(localStorage.getItem("mineChance"));
firstClick = false;
// game board
$game.html(localStorage.getItem("gameBoard"));
gameBoardHeight = determineGameBoardHeight();
// add rows if there is empty space
while ($ul.length < gameBoardHeight) {
$game.append(newRow());
}
// remove any rows the screen cannot display
$('#game ul:gt(' + (gameBoardHeight - 1) + ')').remove();
refreshMineCounts();
updateScore();
updateMinesLeft();
// click blank tiles
$('li.revealed:not(.mine):empty').mouseup();
$('#setup').hide();
}
$.fn.check = function() {
// unclicked tiles
if ($(this).filter('li:not(.revealed):not(.flagged)').length > 0) {
return false;
}
// incorrectly flagged tiles
if ($(this).filter('li.flagged:not(.mine)').length > 0) {
return false;
}
// clicked mines
if ($(this).filter('li.revealed.mine').length > 0) {
return false;
}
return true;
}
$.fn.checkRow = function() {
return $(this).children().check();
}
$.fn.checkColumn = function() {
return $(this).column().check();
}
window.removeClearedRows = function() {
let rowsToRemove = $('ul:not(.removing)').filter(function() {
return $(this).checkRow();
});
if (rowsToRemove.length > 0) {
suddenDeath();
}
rowsToRemove.each(function() {
score += $(this).children('.mine').length;
$(this).addClass("removing");
$(this).slideUp("slow", function() {
// add new row on bottom
$(this).closest("div").append(newRow());
$(this).remove();
refreshMineCounts();
// click blank tiles
$('li.revealed:not(.mine):empty').mouseup();
});
});
}
window.removeClearedColumns = function() {
let columnsToRemove = $('ul:not(.removing):eq(0) li:not(.removing)').filter(function() {
return $(this).checkColumn();
});
if (columnsToRemove.length > 0) {
suddenDeath();
}
columnsToRemove.each(function() {
score += $(this).column().filter('.mine').length;
$(this).column().addClass("removing");
// animation for top row + deletion of column
$(this).animate({width: 0, borderRadius: 0, padding: 0}, "slow", function() {
$(this).column().remove();
$ul.each(function() {
$(this).append(newTile());
});
refreshMineCounts();
// click blank tiles
$('li.revealed:not(.mine, .removing):empty').mouseup();
});
// then just animation for others
$(this).column().animate({width: 0, borderRadius: 0, padding: 0}, "slow");
});
}
function refreshMineCounts() {
$('ul:not(.removing) li.revealed:not(.mine, .removing)').each(function() {
let mineCount = $(this).countMinesText();
$(this).text(mineCount);
// remove "mines1" etc
$(this).attr(
'class',
$(this).attr('class').replace(
/mines[0-9]/, "mines" + mineCount
)
);
$(this).removeClass("mines mines0");
});
}
function updateScore() {
$('#score').text("Score: " + score);
}
function isGameOver() {
return $ul.has('.mine.revealed').length === gameBoardHeight
&& $ul.first().children().filter(function() {
return $(this).column().filter('.mine.revealed').length > 0;
}).length === gameBoardWidth;
}
function checkGameOver() {
if (isGameOver()) {
$gameOver.show();
let currentHiScore = 0;
if ($.isNumeric(localStorage.getItem("hiscore"))) {
currentHiScore = parseInt(localStorage.getItem("hiscore"));
}
if (score > currentHiScore) {
currentHiScore = score;
}
$('#gameOver .score').text(score);
$('#gameOver .hiscore').text(currentHiScore);
// clear saved game
localStorage.clear();
localStorage.setItem("hiscore", currentHiScore);
}
}
function checkTutorial() {
if ($tutorial.is(':hidden')) {
return;
}
let currentPage = $('#tutorial div:visible');
if (
currentPage.find('.toFlag' ).length === currentPage.find('.toFlag.flagged' ).length
&& currentPage.find('.toClick').length === currentPage.find('.toClick.revealed' ).length
&& (currentPage.find('.flagAny' ).length === 0 || currentPage.find('.flagAny.flagged' ).length > 0)
&& (currentPage.find('.clickAny').length === 0 || currentPage.find('.clickAny.revealed').length > 0)
) {
currentPage.nextPage();
}
}
$.fn.nextPage = function() {
$('.gameBoard').html("");
$(this).hide();
if ($(this).is(':last-child')) {
// end of tutorial!
$tutorial.hide();
$('#setup, #game, #stats').show();
$('#setup button.cancel').hide();
gameBoardWidth = 10;
gameBoardHeight = determineGameBoardHeight();
} else {
$(this).next().show();
$(this).next().children().show();
let nextPage = parseInt($(this).attr('id').replace("page", ""));
$(this).next().children('.gameBoard').html(tutorialPages[nextPage]);
if ($(this).next().children('.gameBoard').hasClass("clearRowsColumns")) {
removeClearedRows();
removeClearedColumns();
}
}
}
function updateMinesLeft() {
// un-flagged mines - revealed mines - flagged not-mines
let count = $('.mine:not(.flagged)').length - $('.mine.revealed').length - $('li:not(.mine).flagged').length;
$('#mines').text("Mines left: " + count);
}
function getAspectRatio() {
return $(window).width() / $(window).height();
}
function resizeToWindow() {
if (!viewportSizingAvailable) {
$('html').css('font-size', Math.min($(window).width(), $(window).height()) / 10);
}
}
$.fn.updateMineCount = function() {
$(this).text(
$(this).countMinesText
);
}
$.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.column = function() {
let x = $(this).getX();
let column = $('');
$ul.each(function() {
column = column.add($(this).children().eq(x));
});
return column;
}
window.oneColumnLeft = function() {
return $ul.first().children().filter(function() {
return $(this).column().filter('.mine:not(.revealed, .flagged)').length === 0;
}).length >= (gameBoardWidth - 1)
}
window.oneRowLeft = function() {
return $ul.filter(function() {
return $(this).children('.mine:not(.revealed, .flagged)').length === 0;
}).length >= (gameBoardHeight - 1);
}
window.isSuddenDeath = function() {
return oneRowLeft() && oneColumnLeft();
}
window.suddenDeath = function() {
if (isSuddenDeath()) {
mineChance += 0.03;
// don't want the chance to get to 100% because that's completely predictable
// ⅔ chance is the most likely to create an unsolvable repeating pattern (xxoxxoxxo, etc.)
if (mineChance > 0.666) {
mineChance = 0.666;
}
}
}
$.fn.getX = function() {
return $(this).index();
}
$.fn.getY = function() {
return $(this).parent('ul').index();
}
$.fn.isMine = function() {
return $(this).hasClass("mine");
}
$.fn.countMinesAdjacent = function() {
return $(this).getAdjacentTiles().filter('.mine').length;
}
$.fn.getAdjacentTiles = function() {
let adjacentTiles = $('');
let x = $(this).getX();
let y = $(this).getY();
if (y > 0) {
let tileAbove = $(this).rowAbove().children().eq(x);
adjacentTiles = adjacentTiles.add(tileAbove.prev());
adjacentTiles = adjacentTiles.add(tileAbove );
adjacentTiles = adjacentTiles.add(tileAbove.next());
}
adjacentTiles = adjacentTiles.add($(this).prev());
adjacentTiles = adjacentTiles.add($(this).next());
if (y < (gameBoardHeight - 1)) {
let tileBelow = $(this).rowBelow().children().eq(x);
adjacentTiles = adjacentTiles.add(tileBelow.prev());
adjacentTiles = adjacentTiles.add(tileBelow );
adjacentTiles = adjacentTiles.add(tileBelow.next());
}
return adjacentTiles;
}
$.fn.countMinesText = function() {
return $(this).countMinesAdjacent().toString().replace("0", "");
}
function detachTutorials() {
// can't have several game boards in play at the same time
// because it messes with mine counts, row counts, etc.
tutorialPages = [];
$('#tutorial .gameBoard').each(function() {
tutorialPages.push($(this).html());
$(this).html("");
});
}
$.fn.cracktro = function() {
// trim long whitespaces to 1 space, remove line breaks, split to individual chars
let text = $(this).html().replace(/ +/g, " ").replace(/(\r\n|\n|\r)/gm, "").replace("&amp;", "&").split("");
let cracktro = "";
for (let i = 0; i < text.length; i++) {
cracktro += "<span>" + text[i].replace(" ", "&nbsp;") + "</span>";
}
$(this).html(cracktro);
}
$('#gameOver button').on("click", function() {
drawGameBoard();
$gameOver.hide();
$buttonCancel.hide();
$('button.start').removeAttr('style');
$('#setup').show();
});
$('button.reset').on("click", function() {
// prompt user with setup screen
$('#setup').show();
$buttonCancel.show();
$('button.start').css('left', '20vmin');
});
$buttonCancel.on("click", function() {
// prompt user with setup screen
$('#setup').hide();
$buttonCancel.hide();
$('button.start').removeAttr('style');
});
$('button.start').on("click", function() {
drawGameBoard();
// reset stats
firstClick = true;
// set difficulty
if ($(this).hasClass("easy")) {
mineChance = 0.13;
} else if ($(this).hasClass("normal")) {
mineChance = 0.2;
} else if ($(this).hasClass("hard")) {
mineChance = 0.285;
}
score = 0;
updateScore();
updateMinesLeft();
$('#setup').hide();
});
$('button.tutorial').on("click", function() {
$tutorial.show();
$tutorial.siblings().hide();
const $page1 = $('#page1');
$page1.show();
$('#page1 *').show();
$page1.siblings('div').hide();
$('#page1 .gameBoard').html(tutorialPages[0]);
$game.html("");
gameBoardWidth = 5;
gameBoardHeight = 5;
});
$.fn.leftClick = function(automated) {
if (!automated) automated = false;
// don't want first click to be a mine
if (firstClick) {
let x = $(this).getX();
x = (x >= 1) ? x : 1;
x = (x <= gameBoardWidth - 2) ? x : gameBoardWidth - 2;
let y = $(this).getY();
y = (y >= 1) ? y : 1;
y = (y <= gameBoardHeight - 2) ? y : gameBoardHeight - 2;
$ul.eq(y - 1).children().slice(x - 1).filter(':lt(3)').removeClass("mine");
$ul.eq(y ).children().slice(x - 1).filter(':lt(3)').removeClass("mine");
$ul.eq(y + 1).children().slice(x - 1).filter(':lt(3)').removeClass("mine");
firstClick = false;
}
if ($(this).hasClass("flagged")) {
return;
}
if ($(this).isMine()) {
$(this).addClass("revealed");
} else if (!automated && parseInt($(this).text()) === $(this).getAdjacentTiles().filter('.flagged, .revealed.mine').length) {
// already clicked; use middle click reveal functionality
// number of flags matches number of adjacent mines
$(this).getAdjacentTiles().filter(':not(.flagged, .revealed)').mouseup();
} else {
$(this).addClass("revealed");
$(this).updateMineCount();
$(this).addClass("mines" + $(this).countMinesAdjacent());
// if no mines adjacent, cascade!
if (parseInt($(this).countMinesAdjacent()) === 0) {
$(this).getAdjacentTiles().filter(':not(.revealed)').mouseup();
}
}
firstClick = false;
}
$.fn.middleClick = function() {
// number of flags matches number of adjacent mines
if (parseInt($(this).text()) === $(this).getAdjacentTiles().filter('.flagged, .revealed.mine').length) {
$(this).getAdjacentTiles().filter(':not(.flagged, .revealed)').mouseup();
}
}
$.fn.rightClick = function() {
if (!$(this).hasClass("revealed")) {
$(this).toggleClass("flagged");
}
clearTimeout(timeout);
}
$(document).on("contextmenu", "body", function(event) {
event.preventDefault();
});
$(document).on("mousedown touchstart", "li", function() {
let x = $(this).getX();
let y = $(this).getY();
timeout = setTimeout(function() {
$('ul:eq(' + y + ') li:eq(' + x + ')').rightClick();
mouseHeld = true;
}, clickHoldMs);
});
$(document).on("mouseleave", "li", function() {
clearTimeout(timeout);
});
$(document).on("mouseup touchend", "li", function(event) {
event.preventDefault();
clearTimeout(timeout);
if (mouseHeld) {
mouseHeld = false;
// rightClick has already been called in a callback, so nothing to do here
} else {
switch (event.which) {
case 3:
$(this).rightClick();
break;
case 2:
$(this).middleClick();
break;
case 1:
$(this).leftClick();
break;
default:
$(this).leftClick(true); // automated
break;
}
}
checkTutorial();
if ($tutorial.is(':hidden')) {
removeClearedRows();
removeClearedColumns();
saveGame();
checkGameOver();
updateScore();
updateMinesLeft();
}
});
$(window).resize(resizeToWindow);
resizeToWindow();
detachTutorials();
// instantiate the game
loadGame(); // loadGame will draw the game board if no saved game is found
$gameOver.hide();
$tutorial.hide();
$buttonCancel.hide();
$('#cracktro').cracktro();

342
includes/style.css Normal file
View File

@ -0,0 +1,342 @@
@font-face {
font-family: Helsinki;
src: url('helsinki.eot');
src: url('helsinki.eot?#iefix') format('embedded-opentype'),
url('helsinki.woff2') format('woff2'),
url('helsinki.woff') format('woff'),
url('helsinki.ttf') format('truetype'),
url('helsinki.svg#helsinkiregular') format('svg');
font-weight: normal;
font-style: normal;
}
* {
box-sizing: border-box;
font-family: "Helsinki", sans-serif;
}
html {
background-color: #272822;
margin: 0;
height: 100vh;
width: 100vw;
overflow: hidden;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
body {
height: 100vh;
margin: 0 auto;
width: 100vmin;
}
@keyframes scrollLeft {
from {left: 0;}
to {left: -7200vmin;}
}
@keyframes bounce {
0% {top: 0; left: 0;}
50% {top: 12vmin; left: 2vmin;}
100% {top: 0; left: 0;}
}
@keyframes rainbow {
0% {color: #c6fe7a;}
33% {color: #7ac5fe;}
67% {color: #fe7ac6;}
100% {color: #c6fe7a;} /* back to start */
}
#cracktro {
color: #c6fe7a;
font-size: 6vmin;
height: 20vmin;
margin: 4vmin 0;
overflow: hidden;
white-space: nowrap;
width: 7200vmin;
position: relative;
animation: scrollLeft 420s linear infinite;
}
#cracktro span {
margin-right: 1vmin;
position: relative;
animation: bounce 4s infinite ease-in-out,rainbow 5s infinite;
text-shadow: 0.5vmin 0.5vmin black;
}
#cracktro span:nth-child(10n+1) {
animation-delay: 0.4s;
}
#cracktro span:nth-child(10n+2) {
animation-delay: 0.8s;
}
#cracktro span:nth-child(10n+3) {
animation-delay: 1.2s;
}
#cracktro span:nth-child(10n+4) {
animation-delay: 1.6s;
}
#cracktro span:nth-child(10n+5) {
animation-delay: 2s;
}
#cracktro span:nth-child(10n+6) {
animation-delay: 2.4s;
}
#cracktro span:nth-child(10n+7) {
animation-delay: 2.8s;
}
#cracktro span:nth-child(10n+8) {
animation-delay: 3.2s;
}
#cracktro span:nth-child(10n+9) {
animation-delay: 3.6s;
}
#game {
background-color: #1b1c17;
float: left;
margin: 0 auto;
height: 100%;
overflow: hidden;
}
#stats {
height: 10vmin;
width: 100vmin;
float: left;
background: #768087;
background: linear-gradient(to bottom, #768087 0%,#53595e 100%);
}
#stats button {
margin: 1vmin;
float: right;
font-size: 3vmin;
border-radius: 2vmin;
padding: 1.75vmin;
box-shadow: 0.5vmin 0.5vmin 0 #000;
border: 0.4vmin solid #454e52;
position: relative;
top: auto;
left: auto;
}
#stats div {
float: left;
font-size: 5.4vmin;
margin: 2vmin;
width: auto;
}
#gameOver, #setup, #tutorial {
background-color: rgba(0, 0, 0, 0.6);
width: 100vmin;
height: 100vh;
overflow: hidden;
position: absolute;
}
#gameOver .score {
margin-right: 12vmin;
}
#setup h2 {
margin-top: 0;
}
#setup h2,
#setup label {
margin: 4vmin 3.5vmin;
font-size: 6vmin;
color: #fe7ac6;
text-shadow: 0.5vmin 0.5vmin 0 #a4f4b4; /* x y blur-radius colour */
}
#tutorial .gameBoard {
float: left;
padding: 5vmin;
padding-top: 0;
}
#tutorial p {
padding: 0 5vmin;
}
.centre {
clear: both;
margin-top: 2vmin;
text-align: center;
}
.subtitle {
text-align: center;
}
button {
font-size: 6vmin;
border-radius: 2vmin;
padding: 2vmin;
margin: 0 auto;
box-shadow: 1vmin 1vmin 0 #000;
border: none;
background: #768087;
background: linear-gradient(to bottom, #768087 0%,#53595e 100%);
}
button.cancel {
right: 20vmin;
left: auto;
}
button.donate {
background: #ffefa7;
background: linear-gradient(to bottom, #ffefa7 0%, #feae27 100%);
}
button.twitter {
background: #51aaea;
background: linear-gradient(to bottom, #51aaea 0%,#3375a6 100%);
}
form {
display: inline;
}
h1, h2 {
text-align: center;
}
h1 {
color: #a4f4b4;
font-size: 12vmin;
margin-top: 6vmin;
margin-bottom: 6vmin;
text-shadow: 1vmin 1vmin 0 #fe7ac6; /* x y blur-radius colour */
}
h2 {
color: #7ac5fe;
font-size: 6vmin;
}
ul {
float: left;
clear: both;
height: 10vmin;
list-style-type: none;
padding: 0;
margin: 0;
overflow: hidden;
}
li {
color: white;
font-size: 8vmin;
padding: 1vmin;
padding-top: 0.5vmin;
padding-bottom: 1.5vmin;
text-align: center;
vertical-align: middle;
float: left;
height: 10vmin;
width: 10vmin;
background-color: #454e52;
border-radius: 2vmin;
cursor: default;
}
li.revealed {
background-color: #1b1c17;
}
li:not(.revealed):hover {
background-color: #a0a9af;
}
li.flagged {
background-color: #b5fe52;
background-image: url("includes/images/flag.png");
background-size: 100% 100%;
}
li.flagged:hover {
background-color: #c6fe7a;
}
li.highlighted {
border: 1vmin solid #fe7ac6;
padding: 0;
}
li.mine.revealed {
background-color: #d23000;
background-image: url("includes/images/skull.png");
background-size: 100% 100%;
}
li.mines1 {
color: #c6fe7a;
}
li.mines2 {
color: #7ac5fe;
}
li.mines3 {
color: #fe7ac6;
}
li.mines4 {
color: #b17afe;
}
li.mines5 {
color: #feb27a;
}
li.mines6 {
color: #7afeb2;
}
li.mines7 {
color: #d74600;
}
li.mines8 {
color: #8c4600;
}
p {
color: #fff;
font-size: 4.3vmin;
padding: 0 10vmin;
}
strong {
color: #fe7ac6;
}
table {
color: #fe7ac6;
font-size: 4vmin;
margin: 0 auto;
text-align: center;
}
th, td {
width: 50%;
}
td {
color: #fff;
font-size: 8vmin;
}

297
includes/tutorial.pug Normal file
View File

@ -0,0 +1,297 @@
<h2>tutorial</h2>
<div id="page1">
<div class="gameBoard">
<ul>
<li class="mine"></li><li></li><li></li><li></li><li></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine toFlag"></li><li></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines2 highlighted">2</li><li class="revealed mines2">2</li><li></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine toFlag"></li><li></li>
</ul>
<ul>
<li class="mine"></li><li></li><li></li><li></li><li></li>
</ul>
</div>
<p>take a look at the <strong>highlighted tile</strong>.</p>
<p>the <strong>2</strong> means there are <strong>2 mines</strong> next to it.</p>
<p>there are only <strong>2 tiles</strong> next to it, so we know they are both mines.</p>
<p><strong>right-click</strong> or <strong>press and hold</strong> to flag these mines.</p>
</div>
<div id="page2">
<div class="gameBoard">
<ul>
<li class="mine"></li><li></li><li></li><li></li><li></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="toClick"></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines2">2</li><li class="revealed mines2 highlighted">2</li><li class="toClick"></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="toClick"></li>
</ul>
<ul>
<li class="mine"></li><li></li><li></li><li></li><li></li>
</ul>
</div>
<p>take a look at the next <strong>highlighted tile</strong>.</p>
<p>this also has <strong>2 mines</strong> next to it- but we already know which ones are mines.</p>
<p><strong>click</strong> or <strong>tap</strong> the other adjacent tiles to clear them.</p>
</div>
<div id="page3">
<div class="gameBoard">
<ul>
<li class="mine"></li><li class="toClick"></li><li class="toClick"></li><li class="toClick"></li><li class="toClick"></li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="mine"></li><li class="toClick"></li><li class="toClick"></li><li class="toClick"></li><li class="toClick"></li>
</ul>
</div>
<p>there are some more tiles that are definitely not mines. clear these too.</p>
<p>if you <strong>click or tap</strong> a <strong>number</strong>, any unflagged adjacent tiles will be clicked.</p>
<p>this can save you a lot of time!</p>
</div>
<div id="page4">
<div class="gameBoard">
<ul>
<li class="mine"></li><li class="revealed mines1 highlighted">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li>
</ul>
<ul>
<li></li><li class="revealed mines1 highlighted">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="toClick"></li><li class="revealed mines1">1</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li>
</ul>
<ul>
<li></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="mine"></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li>
</ul>
</div>
<p>look at these 2 <strong>highlighted</strong> tiles.</p>
<p>the <strong>first</strong> has 1 mine next to it.</p>
<p>the <strong>second</strong> also has 1 mine next to it.</p>
<p>however, the <strong>second</strong> spans the same tiles as the <strong>first</strong>, plus one extra.</p>
<p>the extra tile the <strong>second</strong> tile spans cannot be a mine. clear it!</p>
</div>
<div id="page5">
<div class="gameBoard">
<ul>
<li class="mine toFlag"></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="revealed"></li><li class="revealed mines1">1</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li><li class="revealed mines2">2</li>
</ul>
<ul>
<li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="mine flagged"></li><li class="revealed mines1">1</li>
</ul>
<ul>
<li class="mine toFlag"></li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li><li class="revealed mines1">1</li>
</ul>
</div>
<p>when you clear a tile with <strong>no adjacent mines</strong>, the surrounding tiles will all clear as well.</p>
<p>flag the <strong>remaining mines</strong>.</p>
</div>
<div id="page6">
<div class="gameBoard">
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines2">2</li>
<li class="mine"></li>
</ul>
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines3">3</li>
<li class="mine"></li>
</ul>
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines3">3</li>
<li class="mine toFlag highlighted"></li>
</ul>
<ul>
<li class="revealed mines2">2</li>
<li class="revealed mines3">3</li>
<li class="revealed mines3">3</li>
<li class="revealed mines4">4</li>
<li class="mine"></li>
</ul>
<ul>
<li class="mine"></li>
<li class="mine"></li>
<li class="mine"></li>
<li class="mine"></li>
<li class="revealed mines2">2</li>
</ul>
</div>
<p>in this tutorial so far, the game board has been static.</p>
<p>but in <strong>endless mines</strong>, <strong>rows</strong> and <strong>columns</strong> slide away when cleared!</p>
<p>flag the <strong>highlighted</strong> tile to continue.</p>
</div>
<div id="page7">
<div class="gameBoard clearRowsColumns">
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines2">2</li>
<li class="mine"></li>
</ul>
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines3">3</li>
<li class="mine"></li>
</ul>
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines3">3</li>
<li class="mine flagged"></li>
</ul>
<ul>
<li class="revealed mines2">2</li>
<li class="revealed mines3">3</li>
<li class="revealed mines3">3</li>
<li class="revealed mines4">4</li>
<li class="mine"></li>
</ul>
<ul>
<li class="mine"></li>
<li class="mine"></li>
<li class="mine"></li>
<li class="mine"></li>
<li class="revealed mines2">2</li>
</ul>
</div>
<p>in this tutorial so far, the game board has been static.</p>
<p>but in <strong>endless mines</strong>, <strong>rows</strong> and <strong>columns</strong> slide away when cleared!</p>
<p>flag the <strong>highlighted</strong> tile to continue.</p>
</div>
<div id="page8">
<div class="gameBoard">
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines2">2</li>
<li class="mine toFlag"></li>
</ul>
<ul>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed"></li>
<li class="revealed mines3">3</li>
<li class="mine toFlag"></li>
</ul>
<ul>
<li class="revealed mines2">2</li>
<li class="revealed mines3">3</li>
<li class="revealed mines3">3</li>
<li class="revealed mines4">4</li>
<li class="mine toFlag"></li>
</ul>
<ul>
<li class="mine toFlag"></li>
<li class="mine toFlag"></li>
<li class="mine toFlag"></li>
<li class="mine toFlag"></li>
<li class="revealed mines2">2</li>
</ul>
<ul>
<li></li><li></li><li></li><li></li><li></li>
</ul>
</div>
<p>a <strong>new row</strong> has appeared at the bottom.</p>
<p>notice how you can't clear any columns now!</p>
<br>
<p><strong>flag</strong> the <strong>remaining mines</strong> to continue.</p>
</div>
<div id="page9">
<div class="gameBoard clearRowsColumns">
<ul><li></li><li></li><li></li><li></li><li></li></ul>
<ul><li class="mine"></li><li></li><li class="mine"></li><li class="mine"></li><li class="mine"></li></ul>
<ul><li class="revealed mines2">2</li><li class="revealed mines4">4</li><li class="revealed mines4">4</li><li class="highlighted revealed mines7">7</li><li class="mine toFlag"></li></ul>
<ul><li class="mine"></li><li></li><li class="mine"></li><li class="mine"></li><li class="mine"></li></ul>
<ul><li></li><li></li><li></li><li></li><li></li></ul>
</div>
<p>look at the <strong>highlighted</strong> tile.</p>
<p>it has 7 adjacent mines and 7 adjacent tiles.</p>
<p>flag the 7 <strong>adjacent mines</strong>.</p>
</div>
<div id="page10">
<div class="gameBoard clearRowsColumns">
<ul><li></li><li></li><li></li><li></li><li></li></ul>
<ul><li class="mine"></li><li></li><li class="mine"></li><li class="mine"></li><li class="mine"></li></ul>
<ul><li class="revealed mines2">2</li><li class="revealed mines4">4</li><li class="revealed mines4">4</li><li class="revealed mines7">7</li><li class="mine highlighted flagged"></li></ul>
<ul><li class="mine"></li><li></li><li class="mine"></li><li class="mine"></li><li class="mine"></li></ul>
<ul><li></li><li></li><li></li><li></li><li></li></ul>
</div>
<p>oh no! we've lost all our hints!</p>
<p>sometimes it's best to wait before clearing a row.</p>
<br>
<p>the best we can do is guess now.</p>
<p>click <strong>any tile</strong> to continue.</p>
</div>
<div id="page11">
<div class="gameBoard clearRowsColumns">
<ul><li></li><li></li><li></li><li></li><li></li></ul>
<ul><li></li><li class="revealed mines1">1</li><li></li><li class="revealed mines1">1</li><li></li></ul>
<ul><li></li><li></li><li></li><li></li><li></li></ul>
<ul><li></li><li class="revealed mines3">3</li><li class="revealed mines3">3</li><li class="revealed mines3">3</li><li></li></ul>
<ul><li></li><li></li><li class="revealed mines3">3</li><li></li><li></li></ul>
</div>
<p>sorry! I feel bad leading you into a trap like that!</p>
<p>but I think mistakes are a good way to learn.</p>
<p>this is the end of the <strong>tutorial</strong> for now. I hope it has helped in some way.</p>
<p>have fun!</p>
</div>

1509
index.html

File diff suppressed because it is too large Load Diff

67
index.pug Normal file
View File

@ -0,0 +1,67 @@
doctype html
html(lang="en-gb")
head
meta(charset="utf-8")
title endless mines
style
include includes/style.css
body
#stats
#score Score: 0
#mines Mines left: 0
button.reset reset
#game
#gameOver
h1 game over
table
thead
tr
th score
th personal best
tbody
tr
td.score
td.hiscore
#cracktro
include GREETZ.nfo
.centre
form(action="https:// twitter.com/synth_ruiner" target="_blank")
button.twitter say hi
.centre
button play again
#setup
h1 endless mines
p.subtitle ruin, 2015
p.
<strong>left click</strong> or <strong>tap</strong> to clear a tile. <br>
<strong>right click</strong> or <strong>hold</strong> to flag a mine. <br>
rows and columns with <strong>exploded mines</strong> cannot be cleared.
h2 Start game
.centre
button.start.easy easy
button.start.normal normal
button.start.hard hard
.centre
button.tutorial tutorial
button.cancel cancel
#tutorial
include includes/tutorial
script
include includes/jquery-3.5.1.min.js
script
include includes/script.js

4
jquery-2.1.3.min.js vendored

File diff suppressed because one or more lines are too long