import generate from Grid.Util; return { random: random }; function random(size) { var indices = Array.from({length: size}).map(function(x, i) {return i;}); var previousColumn; var columns = [] while(columns.length < 8) { previousColumn = pickNextColumn(indices, previousColumn) columns.push(previousColumn); } return generate(size, size, function(cell) { return columns[cell.row] == cell.column; }); } function pickNextColumn(columnsLeft, previousColumn) { var parts = contiguousParts(columnsLeft); if(parts.length == 1 && columnsLeft.length == 4) { var candidateColumns = [null, columnsLeft[1], columnsLeft[2], null]; } else if(parts.length == 2 && columnsLeft.length < 5 && Math.min(parts[0].length, parts[1].length) < 2) { candidateColumns = parts[0].length == 1 ? [null].concat(parts[1]) : parts[0]; } else { var candidateColumns = columnsLeft; } candidateColumns = candidateColumns.map(maskAround(previousColumn)); return columnsLeft.splice(pickIndex(candidateColumns), 1)[0]; } function maskAround(c0) { return function(c1) { return Math.abs(c1 - c0) < 2 ? null : c1; }; } function pickIndex(t) { var o = {}; var definedCount = 0; for(var i = 0; i < t.length; i++) { if(t[i] != undefined) { o[definedCount] = i; definedCount++; } } return o[Math.floor(definedCount * Math.random())]; } function contiguousParts(t) { var parts = []; var current = []; for(var i = 0; i < t.length; i++) { if(current.length < 1 || t[i] - current[current.length-1] == 1) { current.push(t[i]); } else { parts.push(current); current = [t[i]]; } } parts.push(current); return parts; }