65 lines
1.6 KiB
JavaScript
65 lines
1.6 KiB
JavaScript
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;
|
|
}
|