Making Friends around a Circular Table

by leonbloy

HTML

From <a href="http://math.stackexchange.com/questions/833541/making-friends-around-a-circular-table">Making Friends around a Circular Table</a> (MSE)
<p>Initially, only the cells inside the orange area are painted. After you click on any cell (square), the corresponding row/column pairs will be interchanged (for example, clicking in cell [1,3] will cause rows 1 and 3 to be swapped, and also columns 1 and 3), and the cells that fall inside the orange area will be painted. (This implies that the for cells that surronds the clicked cell will get painted).
<br>
The goal is to have  all cells painted in the mininum number of clicks.
    <p>remaining:<span id="remain" value=""></span>
        <br>
        <canvas id="c" width="400" height="400" onclick="clickcanvas(event,this)"></canvas>
        <br>n=
        <input id="n" value="10" maxlen="2" size="2">
        <button onclick="reset()">Reset</button>
        <br>movs=<span id="movs" value=""></span> 
        <br>
<pre><span id="msg" value=""></span></pre>

        <script>
            reset()
        </script>

CSS

canvas {
    border:1px solid #ddd
}

JavaScript

var n;
var wt = 400;
var w, matrix;
var remain;
var msg = "";
var movs = 0;

function reset() {
    n = parseInt(document.getElementById('n').value, 10);
    if (n < 4 || n > 20) {
        alert("invalid value for n");
        return;
    }
    w = wt / n;
    matrix = [];
    for (var i = 0; i < n; i++) {
        matrix[i] = new Array(n);
        for (var j = 0; j < n; j++) {
            matrix[i][j] = Math.abs(i - j) <= 1 || Math.abs(i - j) == n - 1 ? 2 : 0;
        }
    }
    movs = 0;
    msg = "";
    repaint();
    remain = computeRemain();
    updateLegends();
}

function updateLegends() {
    document.getElementById("msg").innerHTML = msg;
    document.getElementById("movs").innerHTML = movs;
    document.getElementById("remain").innerHTML = remain;
}

function repaint() {
    var canvas = document.getElementById('c');
    if (canvas.getContext) {
        var ctx = canvas.getContext('2d');
        ctx.strokeStyle = "#666666";
        ctx.lineWidth = 1;
        for (var i = 0; i < n; i++) {
            var ii = w * i;
            for (var j = 0; j < n; j++) {
                var jj = w * j;
                ctx.fillStyle = matrix[i][j] == 0 ? "white" : (matrix[i][j] == 1 ? "yellow" : "orange");
                ctx.strokeRect(ii, jj, w, w);
                ctx.fillRect(ii, jj, w, w);
            }
        }
    }

}

function computeRemain() {
    var tot = 0;
    for (var i = 0; i < n; i++) {
        for (var j = 0; j < n; j++) {
            if (matrix[i][j] > 0) tot++;
        }
    }
    return n * n - tot;
}


function clickcanvas(event, canvas) {
    //    var rightc=isrightclick(event);
    var x = event.pageX - canvas.offsetLeft,
        y = event.pageY - canvas.offsetTop;
    var xx = Math.floor(x / w);
    var yy = Math.floor(y / w);
    //if(rightc) xx--; else xx++;
    //if(xx>=n) xx -= n; if(xx<0) xx+=n;
    //  alert("click: ev="+event + " canvas=" +canvas + " x=" + x + " y=" + y + " xx=" + xx + " yy=" + yy );
    if (xx != yy && xx >= 0 & xx <...