import {diagonal, isSmaller, key, plus, ofKey, zero} from Geometry.Vector; import {at, generate} from Grid.Util; function CellSet(definition) { definition = definition || {}; this.cells = {}; if(definition.type == 'rectangle') { this.fromRectangle(definition.origin, definition.offset); } else if(definition.type == 'isochrome') { this.fromIsochrome(definition.grid, definition.origin); } else if(definition.type == 'union') { this.fromUnion(definition.sets); } } CellSet.prototype.fromRectangle = function(origin, maxOffset) { generate( maxOffset.row, maxOffset.column, function(offset) { this.add(plus(origin, offset)); }.bind(this) ); }; CellSet.prototype.fromIsochrome = function(grid, origin) { var originColor = at(grid, origin); var queue = [origin]; while(queue.length > 0) { var cell = queue.shift(); this.add(cell); for(var d = -1; d < 2; d += 2) { [plus(cell, vertical(d)), plus(cell, horizontal(d))].forEach( gateKeeper(this, grid, queue, originColor) ); } } }; CellSet.prototype.fromUnion = function(sets) { for(var i = 0; i < sets.length; i++) { for(var k in sets[i].cells) { this.cells[k] = true; } } } CellSet.prototype.add = function(v) { this.cells[key(v)] = true; }; CellSet.prototype.remove = function(v) { delete this.cells[key(v)]; }; CellSet.prototype.contains = function(v) { return !!this.cells[key(v)]; }; CellSet.prototype.isEmpty = function() { return Object.keys(this.cells).length < 1; }; CellSet.prototype.map = function(f) { var result = []; for(var k in this.cells) { result.push(f(ofKey(k))); } return result; } CellSet.prototype.iter = function(f) { this.map(f); } CellSet.prototype.difference = function(cellSet) { var newCellSet = new CellSet(); this.iter(function(v) { if(!cellSet.contains(v)) { newCellSet.add(v); } }); return newCellSet; } return { make: function(definition) {return new CellSet(definition);}, union: function(sets) {return new CellSet({type: 'union', sets: sets});} }; function gateKeeper(cellSet, grid, queue, originColor) { return function(cell) { if(isSmaller(zero(), cell) && isSmaller(cell, diagonal(grid.length-1)) && !cellSet.contains(cell) && at(grid, cell) == originColor) { queue.push(cell); } } }