Knight's Tour

HTML

<canvas id="board"></canvas>

JavaScript

var WIDTH = 50;
var SIZE = 5;

function draw(board) {
  var canvas = document.getElementById("board");
  var ctx = canvas.getContext("2d");
  //ctx.translate(.5, .5);

  canvas.width = WIDTH * board.length;
  canvas.height = WIDTH * board.length;

  function randHex() {
    return Math.floor(Math.random() * 16).toString(16);
  }

  board.forEach(function (row, y) {
    row.forEach(function (cell, x) {
      ctx.strokeStyle = "#333";
      ctx.strokeRect(x * WIDTH, y * WIDTH, WIDTH, WIDTH);
      if (cell === start) {
        ctx.fillStyle = "#cfc";
        ctx.fillRect(x * WIDTH + 1, y * WIDTH + 1, WIDTH - 2, WIDTH - 2);
      } else if (cell.edges.length > 2) {
        ctx.fillStyle = "#fee";
        ctx.fillRect(x * WIDTH + 1, y * WIDTH + 1, WIDTH - 2, WIDTH - 2);
      }
    });
  });

  board.forEach(function (row, y) {
    row.forEach(function (cell, x) {
      //ctx.strokeStyle = "#" + randHex() + randHex() + randHex();
      cell.edges.forEach(function (edge) {
        ctx.strokeStyle = edge.necessary ? "#6c6" : "#666";
        var neighbor = edge.cell;
        ctx.beginPath();
        ctx.moveTo((x + .5) * WIDTH, (y + .5) * WIDTH);
        ctx.lineTo((neighbor.x + .5) * WIDTH, (neighbor.y + .5) * WIDTH);
        ctx.stroke();
      });
    });
  });
}

var board = [];
for (var y = 0; y < SIZE; y++) {
  var row = [];
  for (var x = 0; x < SIZE; x++) {
    row.push({
      x: x,
      y: y
    });
  }
  board.push(row);
}

board.getEdge = function (cell, dx, dy) {
  var x = cell.x + dx,
    y = cell.y + dy,
    row = this[y];
  if (row) {
    var dest = row[x];
    if (dest) {
      var from = {
        cell: dest,
        twin: function() {
          return from.cell.edges.find(function(edge) {
            return edge.cell === cell;
          });
        },
        safeDelete: function () {
          if (dest.edges.length > 2 && (
              cell.edges.length > 2 || (cell === start && cell.edges.length === 2)
            )) {
           ...