JSFiddle - React, Tailwind, and code Playground

HTML

<title>Knight's Tour game</title>
<table id="table"></table>
<label for="sizeinput">Size</label>
<input type="number" id="sizeinput" value="8" />
<br />
<button id="undo">Undo</button>
<button id="reset">Reset</button>

CSS

table {
    border-collapse: collapse;
}
td {
    border: 1px solid black;
    height: 30px;
    width: 30px;
    line-height: 30px;
    font-size: 30px;
    text-align: center;
}
tr:nth-child(2n + 1) td:nth-child(2n), tr:nth-child(2n) td:nth-child(2n + 1) {
    background: #aaaaaa;
}

JavaScript

var moves = [], board = [], size, k;
reset.onclick = function() {    // reset is the DOM element with id "reset"
    table.innerHTML = "";       // Clear the board
    size = sizeinput.value;     // adjustable size
    for (var y = 0; y < size; y++) {
        board[y] = []; // HTMLElement.appendChild(childEl) returns childEl
        var row = table.appendChild(document.createElement('tr'));
        for (var x = 0; x < size; x++) {
            var cell = board[y][x] = row.appendChild(document.createElement('td'));
            cell.x = x, cell.y = y;
        }
    }
    k = board[0][0]; // k is the cell with the knight
    k.innerHTML = "&#9816;"; // unicode knight
};
table.onclick = function (e) {
    var t = e.target; // is knight-shaped move && target space is empty
    if (Math.pow(t.x - k.x, 2) + Math.pow(t.y - k.y, 2) == 5 && !t.innerHTML) {
        board[k.y][k.x].innerHTML = 'X'; // Show this space has been 
        moves.push(k), k = t; // moves is an array of table cells the knight has been
        k.innerHTML = "&#9816;"; // Knight's current position is not in moves
        if (moves.length + 1 == size * size) table.innerHTML += "You win!";
    }
};
reset.onclick(); // A hack to remove a line -- originally called newGame
undo.onclick = function () {
    k.innerHTML = '';
    k = moves.pop();
    k.innerHTML = "&#9816;";
};