@logic-pad/core
Version:
63 lines (62 loc) • 2.23 kB
JavaScript
import { array } from '../dataHelper.js';
import { Color } from '../primitives.js';
import { normalizeShape, positionsToShape, shapeEquals, } from '../shapes.js';
import Rule from './rule.js';
export default class RegionShapeRule extends Rule {
/**
* @param color - The color of the regions to compare.
*/
constructor(color) {
super();
Object.defineProperty(this, "color", {
enumerable: true,
configurable: true,
writable: true,
value: color
});
this.color = color;
}
getShapeRegions(grid) {
let complete = true;
const visited = array(grid.width, grid.height, (i, j) => {
const tile = grid.getTile(i, j);
if (tile.exists && tile.color === Color.Gray)
complete = false;
return !(tile.exists && tile.color === this.color);
});
const regions = [];
while (true) {
const seed = grid.find((_tile, x, y) => !visited[y][x]);
if (!seed)
break;
const positions = [];
grid.iterateArea(seed, tile => tile.color === this.color, (_, x, y, logX, logY) => {
visited[y][x] = true;
positions.push({ x: logX, y: logY });
});
const incomplete = grid.iterateArea(seed, tile => tile.color === this.color || tile.color === Color.Gray, tile => {
if (tile.color === Color.Gray)
return true;
});
if (incomplete)
continue;
const shape = normalizeShape(positionsToShape(positions, this.color));
const existing = regions.find(island => shapeEquals(island.shape, shape));
if (existing) {
existing.count++;
}
else {
regions.push({
positions: positions.map(pos => grid.toArrayCoordinates(pos.x, pos.y)),
shape,
count: 1,
});
}
}
return { regions, complete };
}
withColor(color) {
return this.copyWith({ color });
}
}
export const instance = undefined;