UNPKG

@logic-pad/core

Version:
114 lines (113 loc) 3.53 kB
import { ConfigType } from '../config.js'; import GridData from '../grid.js'; import { array, minBy } from '../dataHelper.js'; import { Color, State } from '../primitives.js'; import Rule from './rule.js'; class ConnectAllRule extends Rule { /** * **Connect all &lt;color&gt; cells** * * @param color - The color of the cells to connect. */ constructor(color) { super(); Object.defineProperty(this, "color", { enumerable: true, configurable: true, writable: true, value: color }); this.color = color; } get id() { return `connect_all`; } get explanation() { return `Connect all ${this.color} cells`; } get configs() { return ConnectAllRule.CONFIGS; } createExampleGrid() { return this.color === Color.Light ? ConnectAllRule.EXAMPLE_GRID_LIGHT : ConnectAllRule.EXAMPLE_GRID_DARK; } get searchVariants() { return ConnectAllRule.SEARCH_VARIANTS; } validateGrid(grid) { let complete = true; const visited = array(grid.width, grid.height, (i, j) => !(grid.getTile(i, j).exists && grid.getTile(i, j).color === this.color)); const islands = []; 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 || tile.color === Color.Gray, (tile, x, y) => { visited[y][x] = true; if (tile.color === Color.Gray) complete = false; positions.push({ x, y }); }); islands.push(positions); } if (islands.length > 1) { return { state: State.Error, positions: minBy(islands, island => island.length), }; } else if (islands.length <= 1) { return { state: complete ? State.Satisfied : State.Incomplete }; } else { return { state: State.Incomplete }; // not reachable but the TS is not happy } } copyWith({ color }) { return new ConnectAllRule(color ?? this.color); } withColor(color) { return this.copyWith({ color }); } } Object.defineProperty(ConnectAllRule, "CONFIGS", { enumerable: true, configurable: true, writable: true, value: Object.freeze([ { type: ConfigType.Color, default: Color.Light, allowGray: false, field: 'color', description: 'Color', configurable: true, }, ]) }); Object.defineProperty(ConnectAllRule, "EXAMPLE_GRID_LIGHT", { enumerable: true, configurable: true, writable: true, value: Object.freeze(GridData.create(['bwwwb', 'bwbww', 'wwwbb', 'wbwww'])) }); Object.defineProperty(ConnectAllRule, "EXAMPLE_GRID_DARK", { enumerable: true, configurable: true, writable: true, value: Object.freeze(GridData.create(['wbbbw', 'wbwbb', 'bbbww', 'bwbbb'])) }); Object.defineProperty(ConnectAllRule, "SEARCH_VARIANTS", { enumerable: true, configurable: true, writable: true, value: [ new ConnectAllRule(Color.Light).searchVariant(), new ConnectAllRule(Color.Dark).searchVariant(), ] }); export default ConnectAllRule; export const instance = new ConnectAllRule(Color.Dark);