Sliding tile puzzle

Objectives

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>