Sliding tile puzzle
Objectives
- use jQuery for animation
- create a sliding tile puzzle
In-class demonstration code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>15 Puzzle</title>
<script src="jquery.min.js"></script>
<script>
var marginTop = 20;
var marginLeft = 20;
var spacingVertical = 5;
var spacingHorizontal = 5;
var width = 30;
var height = 30;
var board = new Array();
function Cell(id, number) {
this.id = id;
this.number = number;
}
function Point(row, column) {
this.row = row;
this.column = column;
}
$(document).ready( function() {
$('body').css('background-color', 'blue');
createBoard();
});
function findCellInBoard(id) {
for (var r=0; r<4; r++) {
for (var c=0; c<4; c++) {
if (board[r][c].id == id) return new Point(r, c);
}
}
return null;
}
function getRandomPoint() {
var r = Math.floor(Math.random() * 4);
var c = Math.floor(Math.random() * 4);
return new Point(r, c);
}
function shuffleBoard() {
for (var i=0; i<40; i++) {
var p1 = getRandomPoint();
var p2 = getRandomPoint();
while (p1.row==p2.row && p1.column==p2.column) {
p2 = getRandomPoint();
}
var temp = board[p1.row][p1.column];
board[p1.row][p1.column] = board[p2.row][p2.column];
board[p2.row][p2.column] = temp;
}
for (var r=0; r<4; r++) {
for (var c=0; c<4; c++) {
var id = board[r][c].id;
if (id == 'c0') continue;
var left = (width+spacingHorizontal) * c + marginLeft;
var top = r * (height+spacingVertical) + marginTop;
$('#' + id).css('top', top + 'px');
$('#' + id).css('left', left + 'px');
}
}
}
function getParityOfBoard() {
var parity = 0;
for (var n=0; n<16; n++) {
var r = Math.floor(n/4);
var c = n % 4;
if (board[r][c].number == 0) {
parity += (r + 1);
continue;
}
for (var nxt=n+1; nxt<16; nxt++) {
var r2 = Math.floor(nxt/4);
var c2 = nxt % 4;
if (board[r2][c2].number < board[r][c].number) {
parity++;
}
}
}
return parity;
}
function swapCells(p1, p2) {
var toRow = p2.row;
var toColumn = p2.column;
var movingId = board[p1.row][p1.column].id;
var left = (width+spacingHorizontal) * toColumn + marginLeft;
var top = toRow * (height+spacingVertical) + marginTop;
$('#'+movingId).animate({top:top+"px", left:left+"px"}, 500);
var temp = board[p1.row][p1.column];
board[p1.row][p1.column] = board[p2.row][p2.column];
board[p2.row][p2.column] = temp;
}
function handleMove(id) {
var p = findCellInBoard(id);
var e = findCellInBoard('c0');
if (p == null || e == null) {
alert('Error: Could not find cell');
return;
}
if (p.row == e.row) {
if (p.column == e.column-1) swapCells(p, e);
else if (p.column == e.column+1) swapCells(p, e);
} else if (p.column == e.column) {
if (p.row == e.row-1) swapCells(p, e);
else if (p.row == e.row+1) swapCells(p, e);
}
}
function createBoard() {
for (var n=1; n<=15; n++) {
var row = Math.floor((n-1)/4);
var col = (n-1) % 4;
if (((n-1)%4) == 0) { board[row] = new Array(); }
board[row][col] = new Cell("c" + n, n);
$('<div/>', {
id: "c" + n,
text: n,
class: "cell",
css: {
position: "absolute",
left: ((width+spacingHorizontal) * ((n-1)%4) + marginLeft) + "px",
top: (Math.floor((n-1)/4)*(height+spacingVertical) + marginTop) + "px",
backgroundColor: "pink",
fontSize: "22pt",
fontWeight: "bold",
width: width + "px",
height: height + "px",
textAlign: "center"
}
}).appendTo('body');
$('#c' + n).click(function() { handleMove(this.id); });
}
board[3][3] = new Cell("c0", 0);
shuffleBoard();
while (getParityOfBoard() % 2 == 1) {
alert("Reshuffling board");
shuffleBoard();
}
}
</script>
</head>
<body>
</body>
</html>