diff --git a/js/CellSet.js b/js/CellSet.js index 7b74eed..e7d7439 100644 --- a/js/CellSet.js +++ b/js/CellSet.js @@ -1,35 +1,59 @@ function CellSet(definition) { definition = definition || {}; this.cells = {}; - if(definition.shape == 'rectangle') { - 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); - } - } - } else if(definition.shape == 'points') { - for(var i = 0; i < definition.points.length; i++) { - this.cells[id(definition.points[i].i, definition.points[i].j)]; - } + 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 { @@ -39,3 +63,13 @@ return { 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); + } + } +} diff --git a/js/Grid.js b/js/Grid.js index e6ed61b..29599af 100644 --- a/js/Grid.js +++ b/js/Grid.js @@ -39,7 +39,7 @@ function makeRow(config) { function clear() { grid.data = generate(function() {return; }); grid.missing = CellSet.make( - {shape: 'rectangle', x: 0, y: 0, width: 8, height: 8} + {type: 'rectangle', x: 0, y: 0, width: 8, height: 8} ); iter(function(row, column) { cell(row, column).className = ''; diff --git a/js/Grid/Color.js b/js/Grid/Color.js index cefdba9..041c557 100644 --- a/js/Grid/Color.js +++ b/js/Grid/Color.js @@ -15,28 +15,8 @@ function colorize(row, column, color) { } function paint(i0, j0) { - var originColor = Grid.get().data[i0][j0]; - var done = CellSet.make(); - var queue = [{i: i0, j: j0}]; - while(queue.length > 0) { - var p0 = queue[0]; - colorize(p0.i, p0.j); - done.add(p0.i, p0.j); - extend(p0, queue, done, originColor); - queue.shift(); - } + var cellSet = CellSet.make( + {type: 'isochrome', x: i0, y: j0, data: Grid.get().data} + ); + cellSet.iter(colorize); } - -function extend(p0, queue, done, originColor) { - var size = Grid.get().size; - for(var d = -1; d < 2; d += 2) { - [{i: p0.i + d, j: p0.j}, {i: p0.i, j: p0.j + d}].forEach(function(p1) { - if(p1.i >= 0 && p1.i < size && p1.j >= 0 && p1.j < size - && !done.contains(p1.i, p1.j) - && Grid.get().data[p1.i][p1.j] == originColor) { - queue.push(p1); - } - }); - } -} -