@logic-pad/core
Version:
100 lines (99 loc) • 3.67 kB
JavaScript
import { ConfigType } from '../config.js';
import GridData from '../grid.js';
import GridZones from '../gridZones.js';
import { Color, State } from '../primitives.js';
import CellCountPerZoneRule from './cellCountPerZoneRule.js';
export default class ExactCountPerZoneRule extends CellCountPerZoneRule {
color;
count;
title = 'Exact Count Per Zone';
static CONFIGS = Object.freeze([
{
type: ConfigType.Color,
default: Color.Light,
allowGray: true,
field: 'color',
description: 'Color',
configurable: true,
},
{
type: ConfigType.Number,
default: 1,
min: 0,
field: 'count',
description: 'Count',
configurable: true,
},
]);
static EXAMPLE_GRID_LIGHT = Object.freeze(GridData.create(['wbbbb', 'bbbwb', 'bbbwb', 'bwbbb'])
.withZones(new GridZones([
{ x1: 0, y1: 1, x2: 0, y2: 2 },
{ x1: 1, y1: 1, x2: 1, y2: 2 },
{ x1: 2, y1: 1, x2: 2, y2: 2 },
{ x1: 3, y1: 1, x2: 3, y2: 2 },
{ x1: 4, y1: 1, x2: 4, y2: 2 },
{ x1: 1, y1: 0, x2: 2, y2: 0 },
{ x1: 1, y1: 1, x2: 2, y2: 1 },
{ x1: 2, y1: 2, x2: 3, y2: 2 },
{ x1: 2, y1: 3, x2: 3, y2: 3 },
]))
.addRule(new ExactCountPerZoneRule(Color.Light, 1)));
static EXAMPLE_GRID_DARK = Object.freeze(ExactCountPerZoneRule.EXAMPLE_GRID_LIGHT.withTiles(tiles => tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Dark ? Color.Light : Color.Dark)))));
static EXAMPLE_GRID_GRAY = Object.freeze(ExactCountPerZoneRule.EXAMPLE_GRID_LIGHT.withTiles(tiles => tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Light ? Color.Gray : tile.color)))));
static SEARCH_VARIANTS = [
new ExactCountPerZoneRule(Color.Light, 1).searchVariant(),
new ExactCountPerZoneRule(Color.Dark, 1).searchVariant(),
];
/**
* **Each zone has <count> <color> cells.**
*
* @param color - The color of the cells to count.
* @param count - The exact count of the cells in each zone.
*/
constructor(color, count) {
super(color);
this.color = color;
this.count = count;
this.count = count;
}
get id() {
return `zone_exact_count`;
}
get explanation() {
return `Each zone has exactly ${this.count} ${this.color} cell${this.count === 1 ? '' : 's'}`;
}
get configs() {
return ExactCountPerZoneRule.CONFIGS;
}
createExampleGrid() {
if (this.color === Color.Light) {
return ExactCountPerZoneRule.EXAMPLE_GRID_LIGHT;
}
else if (this.color === Color.Dark) {
return ExactCountPerZoneRule.EXAMPLE_GRID_DARK;
}
else {
return ExactCountPerZoneRule.EXAMPLE_GRID_GRAY;
}
}
get searchVariants() {
return ExactCountPerZoneRule.SEARCH_VARIANTS;
}
validateGrid(grid) {
const { zones, complete } = this.getZoneCounts(grid);
const errorZone = zones.find(z => z.completed > this.count || z.completed + z.possible < this.count);
if (errorZone) {
return {
state: State.Error,
positions: errorZone.positions,
};
}
else {
return { state: complete ? State.Satisfied : State.Incomplete };
}
}
copyWith({ color, count }) {
return new ExactCountPerZoneRule(color ?? this.color, count ?? this.count);
}
}
export const instance = new ExactCountPerZoneRule(Color.Light, 1);