Constellations/js/CellSet.js

76 lines
1.7 KiB
JavaScript

function CellSet(definition) {
definition = definition || {};
this.cells = {};
if(definition.type == 'rectangle') {
this.fromRectangle(definition);
} else if(definition.type == 'isochrome') {
this.fromIsochrome(definition);
}
}
CellSet.prototype.fromRectangle = function(definition) {
var xMax = definition.x + definition.width;
var yMax = definition.y + definition.height;
for(var i = definition.x; i < xMax; i++) {
for(var j = definition.y; j < yMax; j++) {
this.add(i, j);
}
}
};
CellSet.prototype.fromIsochrome = function(definition) {
var originColor = definition.data[definition.x][definition.y];
var queue = [{i: definition.x, j: definition.y}];
while(queue.length > 0) {
var p = queue[0];
this.add(p.i, p.j);
for(var d = -1; d < 2; d += 2) {
[{i: p.i + d, j: p.j}, {i: p.i, j: p.j + d}].forEach(
gateKeeper(this, definition.data, queue, originColor)
);
}
queue.shift();
}
};
CellSet.prototype.add = function(i, j) {
this.cells[id(i, j)] = true;
};
CellSet.prototype.remove = function(i, j) {
delete this.cells[id(i, j)];
};
CellSet.prototype.contains = function(i, j) {
return !!this.cells[id(i, j)];
};
CellSet.prototype.isEmpty = function() {
return Object.keys(this.cells).length < 1;
};
CellSet.prototype.iter = function(f) {
for(var key in this.cells) {
var coordinates = key.split(':');
f(coordinates[0], coordinates[1]);
}
}
return {
make: function(definition) {return new CellSet(definition);},
};
function id(i, j) {
return i + ':' + j;
}
function gateKeeper(cellSet, data, queue, originColor) {
return function(p1) {
if(p1.i >= 0 && p1.i < data.length && p1.j >= 0 && p1.j < data.length
&& !cellSet.contains(p1.i, p1.j)
&& data[p1.i][p1.j] == originColor) {
queue.push(p1);
}
}
}