パズル

HTML5のCanvasとJavaScriptを使ったパズルです。
ソースコードは次のとおり。

<script>
function draw()
{
  var dxd=screen.deviceXDPI;
  var nowMagniFication=dxd/96;
  var chgZoom=1/nowMagniFication;
  var size = 100; // 升目の大きさ
  var margin = 10; // 升目のマージン
  var canvas = document.getElementById("sample");

  if(canvas.getContext)  {
    var context = canvas.getContext('2d'); 
    context.font = "70px serif";
    context.textAlign = "center";
    var rect = canvas.getBoundingClientRect();
    var puzzle = new Puzzle();
    puzzle.draw();
    document.attachEvent("onclick", function (event) {
      puzzle.clicked(event);
    });
    function Puzzle() {
      this.state = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
        [13, 14, 15, -1]
      ];
      this.clicked = function(event) {
        var marginx;
        var marginy;
        var x = event.clientX - rect.left;
        var y = event.clientY - rect.top;
        bsize = size * chgZoom;
        var i = Math.floor(y / bsize);
        marginy = i * bsize + margin * chgZoom;
        if(y < marginy)  {
           i = -1;
        }
        var j = Math.floor(x / bsize);
        marginx = j * bsize + margin * chgZoom;
        if(x < marginx)  {
            j = -1;
        }
        if (i >= 0 && i <= 3 && j >= 0 && j <= 3) {
          this.move(i, j);
        }
      };
      this.move = function(i, j) {
        if (j >= 1 && this.empty(i, j-1)) { // 左
           this.exchange(i, j, i, j-1);
        }
        else if (j <= 2 && this.empty(i, j+1)) { // 右
           this.exchange(i, j, i, j+1);
        }
        else if (i >= 1 && this.empty(i-1, j)) { // 上
           this.exchange(i, j, i-1, j);
        }
        else if (i <= 2 && this.empty(i+1, j)) { // 下
           this.exchange(i, j, i+1, j);
        }
      };
      this.exchange = function(i1, j1, i2, j2) {
        this.state[i2][j2] = this.state[i1][j1];
        this.state[i1][j1] = -1;
        this.drawPiece(i1, j1);
        this.drawPiece(i2, j2);
      };
      this.draw = function() {
        for (var i = 0; i <= 3; i++) {
          for (var j = 0; j <= 3; j++) {
            this.drawPiece(i, j);
          }
        }
      };
      this.drawPiece = function(i, j) {
        var n = this.state[i][j];
        if (n == -1) {
          context.clearRect(j*size, i*size, size, size);
        }
        else {
          context.fillStyle = "green";
          context.fillRect(j * size + margin, i * size + margin,
          size - margin, size - margin);
          context.fillStyle = "white";
          context.fillText(n,
          j*size + size * 0.55, i*size + size * 0.78);
        }
      };
      this.empty = function(i, j) {
        return this.state[i][j] == -1;
      };
    }
  }
  else  {
    document.write('canvas Null<br>');
  }
}
<form action="" name="form1"> 
<input type="button" value="開始ボタン" onClick="draw()">
</form>
<canvas id="sample" width="400" height="400"></canvas>

 
パズル実行