UNPKG

@logic-pad/core

Version:
63 lines (62 loc) 2.23 kB
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;