sliding puzzle

http://guny.kr/archives/50

by Tsuneo Yoshioka

HTML

<div id="board"></div>

CSS

#board .num {background-color: yellow; border:1px solid #000; position: absolute; width: 98px; height: 98px; text-align: center; vertical-align: middle;}
#board .blank {position: absolute; }

JavaScript

(function($) {
        "use strict";
        var YLEN = 4, // 행 길이
            XLEN = 4, // 열 길이
            blank = YLEN * XLEN - 1, // 빈칸 위치
            BLANK = 0, // 빈칸의 값
            board = [], // 보드 배열 (YLEN x XLEN)
            boardEl = $('#board'); // 테이블 엘리먼트

        function initPuzzle() { // 퍼즐 데이터를 초기화
            board = [];
            for (var y = 0; y < YLEN; y++) {
                board[y] = []; // 각 행마다 열 배열 설정
                for (var x = 0; x < XLEN; x++) {
                    var idx = y * XLEN + x;
                    if (idx < blank) board[y][x] = idx + 1; // 순서대로 숫자 할당
                    else board[y][x] = BLANK; // 마지막 빈칸 설정
                }
            }
            // 이동 방향
            var moves = ['r', 'l', 'd', 'u'];
            for (var z = 0; z < 500; z++) { // 500회 동안 무작위로 이동
                move(moves[parseInt(Math.random() * 4,10)], false);
            }
            // 데이터 초기화 후 화면 갱신
            updateBoard();
        }

        function updateBoard() { // 퍼즐 데이터를 화면에 표시
            boardEl.empty(); // 테이블을 비우고
            var html = '';
            for (var y = 0; y < YLEN; y++) {
                for (var x = 0; x < XLEN; x++) {
                    if (board[y][x] != BLANK) html += '<div class="num num' + board[y][x] + '" style="left:' + (x * 100) + 'px;top:' + (y * 100) + 'px;">' + board[y][x] + '</div>';
                    else html += '<div class="blank" style="left:20px; top: 20px">&nbsp;</div>'; // 빈칸
                }
            }
            boardEl.html(html);
        }

        function moveTo(to, fAnimate) { // 빈칸을 to 위치로 이동
            console.log("blank=", blank, "to=", to);
            var toNum = board[parseInt(to / YLEN,10)][to % XLEN];
            $('.num' + toNum).animate({
                'top': '' + (parseInt(blank / YLEN,10)*100) + 'px',
                'left': '' + ((blank % XLEN)*100) + 'px'
            });
            $('.blank').animate({
                'top': '' + (parseInt(to / XLEN,10)*100) +...