Created
September 30, 2016 00:44
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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