UNPKG

@logic-pad/core

Version:
105 lines (104 loc) 3.55 kB
import { ConfigType } from '../config.js'; import GridData from '../grid.js'; import { array } from '../dataHelper.js'; import { Color } from '../primitives.js'; import NumberSymbol from './numberSymbol.js'; export default class HouseSymbol extends NumberSymbol { x; y; number; title = 'House'; static CONFIGS = Object.freeze([ { type: ConfigType.Number, default: 0, field: 'x', description: 'X', configurable: false, }, { type: ConfigType.Number, default: 0, field: 'y', description: 'Y', configurable: false, }, { type: ConfigType.Number, default: 2, field: 'number', description: 'Number', explanation: 'Number of houses in this region', configurable: true, }, ]); static EXAMPLE_GRID = Object.freeze(GridData.create(['bbbww', 'wwwbw', 'wbbbw', 'wwwww']) .addSymbol(new HouseSymbol(0, 0, 2)) .addSymbol(new HouseSymbol(2, 0, 2)) .addSymbol(new HouseSymbol(3, 0, 2)) .addSymbol(new HouseSymbol(2, 1, 2)) .addSymbol(new HouseSymbol(3, 1, 2)) .addSymbol(new HouseSymbol(1, 2, 2))); /** * **Houses must connect to exactly one other house** * * @param x - The x-coordinate of the symbol. * @param y - The y-coordinate of the symbol. * @param number - The number of houses in this region. */ constructor(x, y, number) { super(x, y, number); this.x = x; this.y = y; this.number = number; } get id() { return `house`; } get explanation() { return '*House numbers* count the number of houses in the region'; } get configs() { return HouseSymbol.CONFIGS; } createExampleGrid() { return HouseSymbol.EXAMPLE_GRID; } countTiles(grid) { if (!this.validateSubtilePlacement(grid)) return null; const thisX = Math.floor(this.x); const thisY = Math.floor(this.y); const visited = array(grid.width, grid.height, () => false); const connected = array(grid.width, grid.height, () => false); const color = grid.getTile(thisX, thisY).color; if (color === Color.Gray) return { completed: 0, possible: Number.MAX_SAFE_INTEGER }; grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === Color.Gray || tile.color === color, (_, x, y) => { visited[y][x] = true; }); grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === color, (_, x, y) => { connected[y][x] = true; }); let completedHouses = 0; let possibleHouses = 0; for (const symbol of grid.symbols.get(this.id) ?? []) { if (symbol instanceof HouseSymbol) { const symbolX = Math.floor(symbol.x); const symbolY = Math.floor(symbol.y); if (connected[symbolY][symbolX]) completedHouses++; else if (visited[symbolY][symbolX]) possibleHouses++; } } return { completed: completedHouses, possible: completedHouses + possibleHouses, }; } copyWith({ x, y, number, }) { return new HouseSymbol(x ?? this.x, y ?? this.y, number ?? this.number); } } export const instance = new HouseSymbol(0, 0, 2);