Skip to content

Instantly share code, notes, and snippets.

@wdehaes
Created September 30, 2016 00:44
Show Gist options
  • Save wdehaes/c23360ee481c7f65e121014c5da9d5fe to your computer and use it in GitHub Desktop.
Save wdehaes/c23360ee481c7f65e121014c5da9d5fe to your computer and use it in GitHub Desktop.
A simple browser-based game of 15-puzzle. Refresh if you are stuck and want to start a new game.
<!DOCTYPE html>
<html>
<head>
<title>Puzzle</title>
<style>
canvas {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
max-height: 100%;
}
</style>
</head>
<body>
<canvas id="a" width="400" height="400">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
<script type='text/javascript' src='main.js'></script>
</body>
</html>
var c = document.getElementById("a");
var ctx = c.getContext("2d");
var pieces = [];
var w = c.width;
var h = c.height;
var horizPcs = 4;
var vertPcs = 4;
var pieceWidth = w / horizPcs;
var pieceHeight = h / vertPcs;
var pieceBorder = 4;
var pieces = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,15];
var won;
// Set up a new game
function init () {
shuffle(pieces);
drawBoard(shuffle(pieces));
won = false;
}
// Add key listeners
window.onkeyup = function(e) {
if (!won) {
var key = e.keyCode ? e.keyCode : e.which;
var direction = 0;
var gap = pieces.indexOf(0);
if (key == 37 && gap % horizPcs !== 3) {
direction = 1; //left
}else if (key == 38 && Math.floor(gap/horizPcs) !== 3) {
direction = horizPcs; //up
}else if (key == 39 && gap % horizPcs !== 0) {
direction = -1; //right
}else if (key == 40 && Math.floor(gap/horizPcs) !== 0) {
direction = -1 * horizPcs; //down
}
if (direction !== 0) {
movePiece(direction);
won = checkWin();
}
}
else {
init();
}
};
// clear the canvas and put each tile on the board
function drawBoard() {
ctx.clearRect(0, 0, w, h);
for (var i = 0; i < pieces.length; i++) {
drawPiece(i % horizPcs + 1, Math.floor(i / horizPcs) + 1, pieces[i]);
}
}
// Given the x and y coordinates of a tile and the number of the tile,
// draw it on the canvas.
function drawPiece (x,y,n) {
if (n !== 0) {
var x_start = (x - 1) * pieceWidth;
var x_end = x * pieceWidth;
var y_start = (y - 1) * pieceHeight;
var y_end = y * pieceHeight;
//Use two colors to make the game more visually appealing
if (n % 2 === 0) {
ctx.fillStyle="#b4d636";
}
else {
ctx.fillStyle="#cc4a40";
}
ctx.fillRect(x_start + pieceBorder, y_start + pieceBorder, pieceWidth - 2 * pieceBorder, pieceHeight - 2 * pieceBorder);
ctx.font = "20px Sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle="white";
ctx.fillText(n,(x_start + x_end)/2, (y_start + y_end)/2);
}
}
// Move a piece to the empty space
function movePiece(direction) {
var gap = pieces.indexOf(0);
pieces[gap] = pieces[gap + direction];
pieces[gap + direction] = 0;
drawBoard(pieces);
}
// Check if all the tiles are in the right place.
function checkWin() {
var win = true;
for (var i = pieces.length - 2; i >= 0; i--) {
if (i+1!==pieces[i]) {
win = false;
break;
}
win = (win && pieces[pieces.length - 1] === 0);
if (win) {
ctx.clearRect(0, 0, w, h);
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle="black";
ctx.fillText("Congrats! You have WON.",w/2, h/3);
ctx.fillText("To start a new game,", w/2, h/2);
ctx.fillText("press any key", w/2, 2*h/3);
}
return win;
}
}
//Fisher-Yates shuffle to randomize the tiles' starting position (http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array)
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment