UNPKG

@logic-pad/core

Version:
1,422 lines (1,417 loc) 108 kB
/* prettier-ignore-start */ /* eslint-disable */ // @ts-nocheck // noinspection JSUnusedGlobalSymbols declare global { // Generated by dts-bundle-generator v9.5.1 import { RegionConstrainer, SymbolGrid } from 'grilops'; import { PuzzleData as PuzzleData$1 } from 'logic-pad-solver-core'; import { Optimize, Solver as Solver$1, Z3LowLevel } from 'z3-solver'; import { z } from 'zod'; interface Position$1 { readonly x: number; readonly y: number; } export interface Edge { readonly x1: number; readonly y1: number; readonly x2: number; readonly y2: number; } /** * Major rules are frequently referenced in grids to provide additional UI. */ export declare enum MajorRule { MusicGrid = 'music', CompletePattern = 'complete_pattern', Underclued = 'underclued', WrapAround = 'wrap_around', } /** * General puzzle types for categorization. One puzzle can have multiple types. */ export declare enum PuzzleType { Logic = 'logic', Underclued = 'underclued', Pattern = 'pattern', Music = 'music', } export declare enum State { /** * Describes the violation of a rule. */ Error = 'error', /** * Describes that a rule is satisfied and complete in the current grid. */ Satisfied = 'satisfied', /** * Describes that a rule is not violated, but is not yet complete in the current grid. */ Incomplete = 'incomplete', /** * Describes that a rule is violated but ignored due to the effect of another rule. */ Ignored = 'ignored', } export declare namespace State { function isSatisfied(state: State): boolean; } export type RuleState = | { readonly state: State.Error; readonly positions: readonly Position$1[]; } | { readonly state: State.Satisfied; } | { readonly state: State.Incomplete; } | { readonly state: State.Ignored; }; export interface GridState { final: State; rules: readonly RuleState[]; symbols: ReadonlyMap<string, State[]>; } export declare enum Color { Dark = 'dark', Light = 'light', Gray = 'gray', } export declare enum Comparison { Equal = 'eq', AtLeast = 'ge', AtMost = 'le', } export declare const COMPARISONS: readonly Comparison[]; export declare enum Wrapping { None = 'none', Wrap = 'wrap', WrapReverse = 'wrap-reverse', ReflectReverse = 'reflect-reverse', } export declare const WRAPPINGS: readonly Wrapping[]; export declare enum Direction { Up = 'up', Down = 'down', Left = 'left', Right = 'right', } export declare const DIRECTIONS: readonly Direction[]; export type DirectionMap<T> = Record<Direction, T>; export type DirectionToggle = Readonly<DirectionMap<boolean>>; export declare function directionToggle( ...directions: readonly Direction[] ): { up: boolean; down: boolean; left: boolean; right: boolean; }; export declare enum Orientation { Up = 'up', UpRight = 'up-right', Right = 'right', DownRight = 'down-right', Down = 'down', DownLeft = 'down-left', Left = 'left', UpLeft = 'up-left', } export declare const ORIENTATIONS: readonly Orientation[]; export type OrientationMap<T> = Record<Orientation, T>; export type OrientationToggle = Readonly<OrientationMap<boolean>>; export declare function orientationToggle( ...orientations: readonly Orientation[] ): { up: boolean; 'up-right': boolean; right: boolean; 'down-right': boolean; down: boolean; 'down-left': boolean; left: boolean; 'up-left': boolean; }; export declare enum Mode { Create = 'create', Solve = 'solve', Perfection = 'perfection', } export declare class GridZones { readonly edges: readonly Edge[]; constructor(edges?: readonly Edge[]); addEdge(edge: Edge): GridZones; removeEdge(edge: Edge): GridZones; hasEdge(edge: Edge): boolean; getEdgesAt({ x, y }: Position$1): readonly Edge[]; /** * Check if two GridZones objects are equal. * @param other The other GridZones object to compare to. * @returns Whether the two objects are equal. */ equals(other: GridZones): boolean; /** * Deduplicate an array of edges. * @param edges The array of edges to deduplicate. * @returns The deduplicated array of edges. */ static deduplicateEdges(edges: readonly Edge[]): readonly Edge[]; static validateEdges( connections: GridZones, width: number, height: number ): GridZones; insertColumn(index: number): GridZones; insertRow(index: number): GridZones; removeColumn(index: number): GridZones; removeRow(index: number): GridZones; } export declare class TileConnections { [y: number]: { [x: number]: boolean; }; constructor(); get topLeft(): boolean; set topLeft(value: boolean); get top(): boolean; set top(value: boolean); get topRight(): boolean; set topRight(value: boolean); get left(): boolean; set left(value: boolean); get center(): boolean; set center(value: boolean); get right(): boolean; set right(value: boolean); get bottomLeft(): boolean; set bottomLeft(value: boolean); get bottom(): boolean; set bottom(value: boolean); get bottomRight(): boolean; set bottomRight(value: boolean); equals(other: TileConnections): boolean; } export declare class GridConnections extends GridZones { constructor(edges?: readonly Edge[]); addEdge(edge: Edge): GridConnections; removeEdge(edge: Edge): GridConnections; getForTile({ x, y }: Position$1): TileConnections; getConnectedTiles({ x, y }: Position$1): readonly Position$1[]; /** * Create new GridConnections from a string array. * * - Use `.` for cells that don't connect to anything. * - Use any other character for cells that connect to the same character. * * @param array - The string array to create the connections from. * @returns The created connections. You can apply this to a GridData object using GridData.withConnections. */ static create(array: string[]): GridConnections; static validateEdges( connections: GridConnections, width: number, height: number ): GridConnections; insertColumn(index: number): GridConnections; insertRow(index: number): GridConnections; removeColumn(index: number): GridConnections; removeRow(index: number): GridConnections; } /** * Offset the given position by a given step in the given direction. * @param position The position to offset. * @param direction The direction to offset in. * @param step The distance to offset by. * @returns The offset position. */ export declare function move( position: Position$1, direction: Direction | Orientation, step?: number ): { x: number; y: number; }; /** * Check if two edges are the same, regardless of direction. * @param a The first edge. * @param b The second edge. * @returns Whether the edges are the same. */ export declare function isSameEdge(a: Edge, b: Edge): boolean; /** * Convert the given direction to a rotation in degrees. * @param direction The direction to convert. * @returns The rotation in degrees. */ export declare function directionToRotation( direction: Direction ): 0 | 270 | 90 | 180; /** * Convert the given orientation to a rotation in degrees. * @param orientation The orientation to convert. * @returns The rotation in degrees. */ export declare function orientationToRotation( orientation: Orientation ): 0 | 270 | 90 | 180 | 225 | 125 | 315 | 45; /** * Create a new 2D array with the given dimensions and values. * @param width The width of the array. * @param height The height of the array. * @param value A function that returns the value for each x,y coordinate. * @returns The 2D array. */ export declare function array<T>( width: number, height: number, value: (x: number, y: number) => T ): T[][]; /** * Resize the given array to the new size, cutting off or padding with the default value. * @param array The array to resize. * @param newSize The new size of the array. * @param defaultValue A function that returns the default value for each new element. * @returns The resized array. */ export declare function resize<T>( array: T[], newSize: number, defaultValue: () => T ): T[]; export declare function resize<T>( array: readonly T[], newSize: number, defaultValue: () => T ): readonly T[]; /** * Check if all the given values are equal. * @param values The values to compare. * @returns Whether all the values are equal. */ export declare function allEqual<T>(...values: T[]): boolean; /** * Return the first element of the array which has the minimum mapped value. * * @param values The array of values. * @param mapper The function to map each value to a number. * @returns The first element with the minimum mapped value. */ export declare function minBy<T>( values: readonly T[], mapper: (element: T) => number ): T | undefined; /** * Return the first element of the array which has the maximum mapped value. * * @param values The array of values. * @param mapper The function to map each value to a number. * @returns The first element with the maximum mapped value. */ export declare function maxBy<T>( values: readonly T[], mapper: (element: T) => number ): T | undefined; /** * Escape the given text by replacing the specified characters with HTML escape sequences. * @param text The text to escape. * @param escapeCharacters The characters to escape. * @returns The escaped text. */ declare function escape$1(text: string, escapeCharacters?: string): string; /** * Unescape the given text by replacing HTML escape sequences with the corresponding characters. * @param text The text to unescape. * @param escapeCharacters The characters to unescape. This should match the characters escaped by the `escape` function. * @returns The unescaped text. */ declare function unescape$1(text: string, escapeCharacters?: string): string; export declare class CachedAccess<T> { private readonly getter; private static readonly UNCACHED; private cache; private constructor(); static of<T>(getter: () => T): CachedAccess<T>; get value(): T; } export declare abstract class Configurable { abstract get title(): string; abstract get configExplanation(): string; get configs(): readonly AnyConfig[] | null; abstract copyWith(props: Record<string, unknown>): this; /** * Check if this instruction is equal to another instruction by comparing their IDs and configs. * * @param other The other instruction to compare to. * @returns Whether the two instructions are equal. */ equals(other: Configurable): boolean; } export declare abstract class Instruction extends Configurable { abstract get id(): string; abstract get explanation(): string; get configExplanation(): string; abstract createExampleGrid(): GridData; /** * Indicates that validation by logic is not available and the solution must be used for validation */ get validateWithSolution(): boolean; get necessaryForCompletion(): boolean; get visibleWhenSolving(): boolean; /** * Return a variant of this instruction that is suitable for the given mode. */ abstract modeVariant(mode: Mode): Instruction | null; /** * Check if this instruction is equal to another instruction by comparing their IDs and configs. * * @param other The other instruction to compare to. * @returns Whether the two instructions are equal. */ equals(other: Instruction): boolean; } export interface SearchVariant { description: string; rule: Rule; } export declare abstract class Rule extends Instruction { abstract validateGrid(grid: GridData): RuleState; abstract get searchVariants(): SearchVariant[]; searchVariant(): SearchVariant; modeVariant(_mode: Mode): Rule | null; /** * Whether only one instance of this rule is allowed in a grid. */ get isSingleton(): boolean; } export interface GridResizeHandler { /** * Update itself when the grid is resized. */ onGridResize( grid: GridData, mode: 'insert' | 'remove', direction: 'row' | 'column', index: number ): this | null; } export declare function handlesGridResize<T extends Instruction>( val: T ): val is T & GridResizeHandler; declare abstract class Symbol$1 extends Instruction implements GridResizeHandler { readonly x: number; readonly y: number; constructor(x: number, y: number); abstract validateSymbol(grid: GridData, solution: GridData | null): State; modeVariant(_mode: Mode): Symbol$1 | null; onGridResize( _grid: GridData, mode: 'insert' | 'remove', direction: 'row' | 'column', index: number ): this | null; /** * The step size for the x and y coordinates of the symbol. */ get placementStep(): number; /** * The order in which symbols are displayed on the instruction list. Lower values are displayed first. */ get sortOrder(): number; withX(x: number): this; withY(y: number): this; withPosition(x: number, y: number): this; } export declare class TileData { readonly exists: boolean; readonly fixed: boolean; readonly color: Color; constructor(exists: boolean, fixed: boolean, color: Color); /** * Create a gray tile. */ static empty(): TileData; /** * Create a non-existent tile. */ static doesNotExist(): TileData; copyWith({ exists, fixed, color, }: { exists?: boolean; fixed?: boolean; color?: Color; }): this; withExists(exists: boolean): this; withFixed(fixed: boolean): this; withColor(color: Color): this; get isFixed(): boolean; equals(other: TileData): boolean; static create(char: string): TileData; } export interface GridChangeHandler { onGridChange(newGrid: GridData): this; } export declare function handlesGridChange<T extends Instruction>( val: T ): val is T & GridChangeHandler; export interface SetGridHandler { onSetGrid( oldGrid: GridData, newGrid: GridData, solution: GridData | null ): GridData; } export declare function handlesSetGrid<T extends Instruction>( val: T ): val is T & SetGridHandler; export declare function invokeSetGrid( oldGrid: GridData, newGrid: GridData, solution: GridData | null ): GridData; export declare class Row extends Configurable { /** * The note to play at this row, or null to keep the current note from the previous control line. * If this is null from the first control line, the note will be silent. */ readonly note: string | null; /** * The velocity to play the note at, or null to keep the current velocity from the previous control line. * Ranges from 0 to 1 */ readonly velocity: number | null; readonly title = 'Music Grid - Row'; readonly configExplanation = 'Configure the playback settings from this tile onwards.'; private static readonly CONFIGS; constructor( /** * The note to play at this row, or null to keep the current note from the previous control line. * If this is null from the first control line, the note will be silent. */ note: string | null, /** * The velocity to play the note at, or null to keep the current velocity from the previous control line. * Ranges from 0 to 1 */ velocity: number | null ); get configs(): readonly AnyConfig[] | null; copyWith({ note, velocity, }: { note?: string | null; velocity?: number | null; }): this; } export declare class ControlLine extends Configurable { readonly column: number; readonly bpm: number | null; readonly pedal: boolean | null; readonly checkpoint: boolean; readonly rows: readonly Row[]; readonly title = 'Music Grid - Control Line'; readonly configExplanation = 'Configure the playback settings from this point onwards.'; private static readonly CONFIGS; /** * Configure playback settings, taking effect at the given column (inclusive) * @param column The column at which the settings take effect * @param bpm The new beats per minute, or null to keep the current value from the previous control line * @param pedal Whether the pedal is pressed, or null to keep the current value from the previous control line * @param checkpoint Whether this control line is a checkpoint * @param rows The notes to play at each row. This list is automatically resized to match the height of the grid. You may pass in an empty list if none of the rows need to be changed. */ constructor( column: number, bpm: number | null, pedal: boolean | null, checkpoint: boolean, rows: readonly Row[] ); get configs(): readonly AnyConfig[] | null; copyWith({ column, bpm, pedal, checkpoint, rows, }: { column?: number; bpm?: number | null; pedal?: boolean | null; checkpoint?: boolean; rows?: readonly Row[]; }): this; withColumn(column: number): this; withBpm(bpm: number | null): this; withPedal(pedal: boolean | null): this; withCheckpoint(checkpoint: boolean): this; withRows(rows: readonly Row[]): this; equals(other: ControlLine): boolean; get isEmpty(): boolean; } export declare class MusicGridRule extends Rule implements GridChangeHandler, SetGridHandler, GridResizeHandler { readonly controlLines: readonly ControlLine[]; readonly track: GridData | null; readonly normalizeVelocity: boolean; readonly title = 'Music Grid'; get configExplanation(): string; private static readonly EXAMPLE_GRID; private static readonly CONFIGS; private static readonly SEARCH_VARIANTS; /** * **Music Grid: Listen to the solution** * @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback. * @param track The grid to be played when "listen" is clicked. Set as null to play the solution. * @param normalizeVelocity Whether to normalize the velocity of the notes by their pitch such that lower notes are played softer. */ constructor( controlLines: readonly ControlLine[], track: GridData | null, normalizeVelocity?: boolean ); get id(): string; get explanation(): string; get configs(): readonly AnyConfig[] | null; createExampleGrid(): GridData; get searchVariants(): SearchVariant[]; validateGrid(_grid: GridData): RuleState; onSetGrid( _oldGrid: GridData, newGrid: GridData, _solution: GridData | null ): GridData; onGridChange(newGrid: GridData): this; onGridResize( _grid: GridData, mode: 'insert' | 'remove', direction: 'row' | 'column', index: number ): this | null; /** * Add or replace a control line. * @param controlLine The control line to set. * @returns A new rule with the control line set. */ setControlLine(controlLine: ControlLine): this; withTrack(track: GridData | null): this; copyWith({ controlLines, track, normalizeVelocity, }: { controlLines?: readonly ControlLine[]; track?: GridData | null; normalizeVelocity?: boolean; }): this; get validateWithSolution(): boolean; get isSingleton(): boolean; static mergeControlLines(...lines: ControlLine[]): ControlLine; static deduplicateControlLines( lines: readonly ControlLine[] ): ControlLine[]; } export declare class CompletePatternRule extends Rule { readonly title = 'Complete The Pattern'; get configExplanation(): string; private static readonly EXAMPLE_GRID; private static readonly SEARCH_VARIANTS; /** * **Complete the pattern** * * This rule validates answers based on the provided solution. */ constructor(); get id(): string; get explanation(): string; createExampleGrid(): GridData; get searchVariants(): SearchVariant[]; validateGrid(_grid: GridData): RuleState; copyWith(_: object): this; get validateWithSolution(): boolean; get isSingleton(): boolean; } export declare class UndercluedRule extends Rule { readonly title = 'Underclued'; get configExplanation(): string; private static readonly EXAMPLE_GRID; private static readonly SEARCH_VARIANTS; /** * **Underclued Grid: Mark only what is definitely true** * * This rule validates answers based on the provided solution. */ constructor(); get id(): string; get explanation(): string; createExampleGrid(): GridData; get searchVariants(): SearchVariant[]; validateGrid(_grid: GridData): RuleState; copyWith(_: object): this; get validateWithSolution(): boolean; get isSingleton(): boolean; } export interface GetTileHandler { onGetTile(x: number, y: number, grid: GridData): Position$1; } export declare function handlesGetTile<T extends Instruction>( val: T ): val is T & GetTileHandler; export declare class WrapAroundRule extends Rule implements GetTileHandler { readonly horizontal: Wrapping; readonly vertical: Wrapping; readonly title = 'Wrap Around'; get configExplanation(): string; private static readonly EXAMPLE_GRID_NONE; private static readonly EXAMPLE_GRID_HORIZONTAL; private static readonly EXAMPLE_GRID_VERTICAL; private static readonly SEARCH_VARIANTS; private static readonly CONFIGS; /** * **The left and right edges are connected (in reverse)** * * @param horizontal - The horizontal wrapping. * @param vertical - The vertical wrapping. */ constructor(horizontal: Wrapping, vertical: Wrapping); onGetTile(x: number, y: number, grid: GridData): Position$1; get id(): string; get explanation(): string; createExampleGrid(): GridData; get configs(): readonly AnyConfig[] | null; get searchVariants(): SearchVariant[]; validateGrid(grid: GridData): RuleState; copyWith({ horizontal, vertical, }: { horizontal?: Wrapping; vertical?: Wrapping; }): this; get isSingleton(): boolean; } export declare const NEIGHBOR_OFFSETS: Position$1[]; export declare class GridData { readonly width: number; readonly height: number; readonly tiles: readonly (readonly TileData[])[]; readonly connections: GridConnections; readonly zones: GridZones; readonly symbols: ReadonlyMap<string, readonly Symbol$1[]>; readonly rules: readonly Rule[]; readonly musicGrid: CachedAccess<MusicGridRule | undefined>; readonly completePattern: CachedAccess<CompletePatternRule | undefined>; readonly underclued: CachedAccess<UndercluedRule | undefined>; readonly wrapAround: CachedAccess<WrapAroundRule | undefined>; /** * Create a new grid with tiles, connections, symbols and rules. * * @param width The width of the grid. * @param height The height of the grid. * @param tiles The tiles of the grid. * @param connections The connections of the grid, which determines which tiles are merged. * @param zones The zones of the grid. * @param symbols The symbols in the grid. * @param rules The rules of the grid. */ constructor( width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol$1[]>, rules?: readonly Rule[] ); /** * Create a new GridData object from a string array. * * - Use `b` for dark cells, `w` for light cells, and `n` for gray cells. * - Capitalize the letter to make the tile fixed. * - Use `.` to represent empty space. * * @param array - The string array to create the grid from. * @returns The created grid. */ static create(array: string[]): GridData; /** * Create a new grid with tiles, connections, symbols and rules. Sanitize the provided list of symbols and rules, * and trigger grid change events. * * @param width The width of the grid. * @param height The height of the grid. * @param tiles The tiles of the grid. * @param connections The connections of the grid, which determines which tiles are merged. * @param zones The zones of the grid. * @param symbols The symbols in the grid. * @param rules The rules of the grid. */ static create( width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol$1[]>, rules?: readonly Rule[], sanitize?: boolean, triggerEvents?: boolean ): GridData; /** * Copy the current grid while modifying the provided properties. * @param param0 The properties to modify. * @returns The new grid with the modified properties. */ copyWith( { width, height, tiles, connections, zones, symbols, rules, }: { width?: number; height?: number; tiles?: readonly (readonly TileData[])[]; connections?: GridConnections; zones?: GridZones; symbols?: ReadonlyMap<string, readonly Symbol$1[]>; rules?: readonly Rule[]; }, sanitize?: boolean, triggerEvents?: boolean ): GridData; toArrayCoordinates(x: number, y: number): Position$1; isPositionValid(x: number, y: number): boolean; /** * Safely get the tile at the given position. * @param x The x-coordinate of the tile. * @param y The y-coordinate of the tile. * @returns The tile at the given position, or a non-existent tile if the position is invalid. */ getTile(x: number, y: number): TileData; /** * Safely set the tile at the given position. * If the position is invalid, the tile array is returned unchanged. * If the tile is merged with other tiles, the colors of all connected tiles are changed. * * @param x The x-coordinate of the tile. * @param y The y-coordinate of the tile. * @param tile The new tile to set. * @returns The new tile array with updated tiles. */ setTile( x: number, y: number, tile: TileData | ((tile: TileData) => TileData) ): readonly (readonly TileData[])[]; /** * Replace or modify all tiles in the grid. * * @param tiles The new tile array or a function to mutate the existing tile array. * @returns The new grid with the new tiles. */ withTiles( tiles: | readonly (readonly TileData[])[] | ((value: TileData[][]) => readonly (readonly TileData[])[]) ): GridData; /** * Add or modify the connections in the grid. * @param connections The new connections to add or modify. * @returns The new grid with the new connections. */ withConnections( connections: | GridConnections | ((value: GridConnections) => GridConnections) ): GridData; /** * Add or modify the zones in the grid. * @param zones The new zones to add or modify. * @returns The new grid with the new zones. */ withZones(zones: GridZones | ((value: GridZones) => GridZones)): GridData; /** * Add or modify the symbols in the grid. * @param symbols The new symbols to add or modify. * @returns The new grid with the new symbols. */ withSymbols( symbols: | readonly Symbol$1[] | ReadonlyMap<string, readonly Symbol$1[]> | (( value: Map<string, readonly Symbol$1[]> ) => ReadonlyMap<string, readonly Symbol$1[]>) ): GridData; /** * Add a new symbol to the grid. * @param symbol The symbol to add. * @returns The new grid with the new symbol. */ addSymbol(symbol: Symbol$1): GridData; /** * Remove an instance of the symbol from the grid. * @param symbol The symbol to remove. * @returns The new grid with the symbol removed. */ removeSymbol(symbol: Symbol$1): GridData; /** * Remove all symbols that satisfy the predicate. * @param predicate The predicate to test each symbol with. * @returns The new grid with the symbols removed. */ removeSymbolIf(predicate: (symbol: Symbol$1) => boolean): GridData; /** * Find the first symbol that satisfies the predicate. * @param predicate The predicate to test each symbol with. * @returns The first symbol that satisfies the predicate, or undefined if no symbol is found. */ findSymbol(predicate: (symbol: Symbol$1) => boolean): Symbol$1 | undefined; /** * Replace an existing symbol with a new symbol. * @param oldSymbol The symbol to replace. * @param newSymbol The new symbol to replace with. * @returns The new grid with the symbol replaced. */ replaceSymbol(oldSymbol: Symbol$1, newSymbol: Symbol$1): GridData; /** * Add or modify the rules in the grid. * @param rules The new rules to add or modify. * @returns The new grid with the new rules. */ withRules( rules: readonly Rule[] | ((value: readonly Rule[]) => readonly Rule[]) ): GridData; /** * Add a new rule to the grid. * @param rule The rule to add. * @returns The new grid with the new rule. */ addRule(rule: Rule): GridData; /** * Remove an instance of the rule from the grid. * @param rule The rule to remove. * @returns The new grid with the rule removed. */ removeRule(rule: Rule): GridData; /** * Remove all rules that satisfy the predicate. * @param predicate The predicate to test each rule with. * @returns The new grid with the rules removed. */ removeRuleIf(predicate: (rule: Rule) => boolean): GridData; /** * Find the first rule that satisfies the predicate. * @param predicate The predicate to test each rule with. * @returns The first rule that satisfies the predicate, or undefined if no rule is found. */ findRule(predicate: (rule: Rule) => boolean): Rule | undefined; /** * Replace an existing rule with a new rule. * @param oldRule The rule to replace. * @param newRule The new rule to replace with. * @returns The new grid with the rule replaced. */ replaceRule(oldRule: Rule, newRule: Rule): GridData; /** * Insert a new column at the given index, shifting all components of the grid accordingly. Newly inserted tiles are gray. * @param index The index to insert the column at. * @returns The new grid with the new column inserted. */ insertColumn(index: number): GridData; /** * Insert a new row at the given index, shifting all components of the grid accordingly. Newly inserted tiles are gray. * @param index The index to insert the row at. * @returns The new grid with the new row inserted. */ insertRow(index: number): GridData; /** * Remove a column at the given index, shifting all components of the grid accordingly. * @param index The index to remove the column at. * @returns The new grid with the column removed. */ removeColumn(index: number): GridData; /** * Remove a row at the given index, shifting all components of the grid accordingly. * @param index The index to remove the row at. * @returns The new grid with the row removed. */ removeRow(index: number): GridData; /** * Resize the grid to the new width and height, shifting all components of the grid accordingly. Newly inserted tiles are gray. * @param width The new width of the grid. * @param height The new height of the grid. * @returns The new grid with the new dimensions. */ resize(width: number, height: number): this; /** * Create a new mutable TileData array from a string array. * * - Use `b` for dark cells, `w` for light cells, and `n` for gray cells. * - Capitalize the letter to make the tile fixed. * - Use `.` to represent empty space. * * @param array - The string array to create the tiles from. * @returns The created tile array. */ static createTiles(array: string[]): TileData[][]; /** * Find a tile in the grid that satisfies the predicate. * * @param predicate The predicate to test each tile with. * @returns The position of the first tile that satisfies the predicate, or undefined if no tile is found. */ find( predicate: (tile: TileData, x: number, y: number) => boolean ): Position$1 | undefined; /** * Iterate over all tiles in the same region as the given position that satisfy the predicate. * The iteration stops when the callback returns a value that is not undefined. * Non-existent tiles are not included in the iteration. * * @param position The position to start the iteration from. This position is included in the iteration. * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate. * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined. * @param visited A 2D array to keep track of visited tiles. This array is modified by the function. * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed. */ iterateArea<T>( position: Position$1, predicate: (tile: TileData) => boolean, callback: ( tile: TileData, x: number, y: number, logicalX: number, logicalY: number ) => undefined | T, visited?: boolean[][] ): T | undefined; /** * Iterate over all tiles in a straight line from the given position in the given direction that satisfy the predicate. * The iteration stops when the callback returns a value that is not undefined. * Non-existent tiles break the iteration. * * @param position The position to start the iteration from. This position is included in the iteration. * @param direction The direction to iterate in. * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate. * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined. * @param visited A 2D array to keep track of visited tiles. This array is modified by the function. * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed. */ iterateDirection<T>( position: Position$1, direction: Direction | Orientation, predicate: (tile: TileData) => boolean, callback: ( tile: TileData, x: number, y: number, logicalX: number, logicalY: number ) => T | undefined, visited?: boolean[][] ): T | undefined; /** * Iterate over all tiles in a straight line from the given position in the given direction that satisfy the predicate. * The iteration stops when the callback returns a value that is not undefined. * Non-existent tiles are included in the iteration. * * @param position The position to start the iteration from. This position is included in the iteration. * @param direction The direction to iterate in. * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate. * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined. * @param visited A 2D array to keep track of visited tiles. This array is modified by the function. * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed. */ iterateDirectionAll<T>( position: Position$1, direction: Direction | Orientation, predicate: (tile: TileData) => boolean, callback: ( tile: TileData, x: number, y: number, logicalX: number, logicalY: number ) => T | undefined, visited?: boolean[][] ): T | undefined; /** * Check if every tile in the grid is filled with a color other than gray. * * @returns True if every tile is filled with a color other than gray, false otherwise. */ isComplete(): boolean; /** * Iterate over all tiles in the grid. * The iteration stops when the callback returns a value that is not undefined. * * @param callback The callback to call for each tile. * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed. */ forEach<T>( callback: (tile: TileData, x: number, y: number) => T | undefined ): T | undefined; /** * Flood fill a continuous region starting from the given position with the given color. * * @param position The position to start the flood fill from. * @param from The color of the tiles to fill. * @param to The color to fill the tiles with. * @param allowFixed Whether to fill fixed tiles. * @returns The new grid with the region filled with the new color. */ floodFill( position: Position$1, from: Color, to: Color, allowFixed: boolean ): GridData; /** * Flood fill all tiles with the given color to a new color, even if they are not connected. * * @param from The color of the tiles to fill. * @param to The color to fill the tiles with. * @param allowFixed Whether to fill fixed tiles. * @returns The new grid with all tiles filled with the new color. */ floodFillAll(from: Color, to: Color, allowFixed: boolean): GridData; /** * Check if the grid has any instructions that require a custom solution. * @returns True if the grid has any instructions that require a custom solution, false otherwise. */ requireSolution(): boolean; /** * Reset all non-fixed tiles to gray. * * @returns The new grid with all non-fixed tiles reset to gray. */ resetTiles(): this; /** * Copy the tiles in the given region to a new grid. * All connections and symbols within the selected region are copied. * All rules are included as well. * * @param origin The top-left corner of the region to copy. * @param width The width of the region to copy. * @param height The height of the region to copy. * @returns The new grid with the copied tiles. */ copyTiles(origin: Position$1, width: number, height: number): GridData; /** * Paste the tiles from the given grid to the current grid at the given position. * All connections, symbols, and rules are merged. * * @param origin The top-left corner of the region to paste the tiles to. * @param grid The grid to paste the tiles from. * @returns The new grid with the pasted tiles. */ pasteTiles(origin: Position$1, grid: GridData): GridData; /** * Paste the tiles from the given array to the current grid at the given position. * * @param origin The top-left corner of the region to paste the tiles to. * @param tile The array of tiles to paste. * @returns The new grid with the pasted tiles. */ pasteTiles( origin: Position$1, tile: readonly (readonly TileData[])[] ): GridData; /** * Check if this grid is equal to another grid in terms of size and tile colors. * Rules, symbols, and connections are not compared. * * @param grid The grid to compare with. * @returns True if the grids are equal in size and tile colors, false otherwise. */ colorEquals(grid: GridData): boolean; /** * Check if this grid is equal to another grid in terms of size, tile colors, connections, symbols, and rules. * * @param other The grid to compare with. * @returns True if the grids are equal, false otherwise. */ equals(other: GridData): boolean; /** * Get the count of tiles that satisfy the given conditions. * @param exists Whether the tile exists or not. * @param fixed Whether the tile is fixed or not. If undefined, the fixed state is ignored. * @param color The color of the tile. If undefined, all colors are included. * @returns The count of tiles that satisfy the given conditions. */ getTileCount(exists: boolean, fixed?: boolean, color?: Color): number; /** * Get the count of tiles that satisfy the given conditions for each color. * @param color The color of the tiles. * @returns The count of tiles that satisfy the given conditions for each color. */ getColorCount(color: Color): { min: number; max: number; }; /** * Deduplicate the rules in the given list. * * @param rules The list of rules to deduplicate. * @returns The deduplicated list of rules. */ static deduplicateRules(rules: readonly Rule[]): Rule[]; /** * Deduplicate the singleton rules in the given list. * * @param rules The list of rules to deduplicate. * @returns The deduplicated list of rules. */ static deduplicateSingletonRules(rules: readonly Rule[]): Rule[]; /** * Deduplicate the symbols in the given map. * * @param symbols The map of symbols to deduplicate. * @returns The deduplicated map of symbols. */ static deduplicateSymbols( symbols: ReadonlyMap<string, readonly Symbol$1[]> ): Map<string, Symbol$1[]>; } export declare enum ConfigType { Boolean = 'boolean', NullableBoolean = 'nullableBoolean', Number = 'number', NullableNumber = 'nullableNumber', String = 'string', Color = 'color', Comparison = 'comparison', Wrapping = 'wrapping', Direction = 'direction', DirectionToggle = 'directionToggle', Orientation = 'orientation', OrientationToggle = 'orientationToggle', Tile = 'tile', Shape = 'shape', Grid = 'grid', NullableGrid = 'nullableGrid', Icon = 'icon', ControlLines = 'controlLines', NullableNote = 'nullableNote', SolvePath = 'solvePath', } export interface Config<T> { readonly type: ConfigType; readonly field: string; readonly description: string; readonly explanation?: string; readonly default: T; readonly configurable: boolean; } export interface BooleanConfig extends Config<boolean> { readonly type: ConfigType.Boolean; } export interface NullableBooleanConfig extends Config<boolean | null> { readonly type: ConfigType.NullableBoolean; } export interface NumberConfig extends Config<number> { readonly type: ConfigType.Number; readonly min?: number; readonly max?: number; readonly step?: number; } export interface NullableNumberConfig extends Config<number | null> { readonly type: ConfigType.NullableNumber; readonly min?: number; readonly max?: number; readonly step?: number; } export interface StringConfig extends Config<string> { readonly type: ConfigType.String; readonly maxLength?: number; readonly placeholder?: string; } export interface ColorConfig extends Config<Color> { readonly type: ConfigType.Color; readonly allowGray: boolean; } export interface ComparisonConfig extends Config<Comparison> { readonly type: ConfigType.Comparison; } export interface WrappingConfig extends Config<Wrapping> { readonly type: ConfigType.Wrapping; } export interface DirectionConfig extends Config<Direction> { readonly type: ConfigType.Direction; } export interface DirectionToggleConfig extends Config<DirectionToggle> { readonly type: ConfigType.DirectionToggle; } export interface OrientationConfig extends Config<Orientation> { readonly type: ConfigType.Orientation; } export interface OrientationToggleConfig extends Config<OrientationToggle> { readonly type: ConfigType.OrientationToggle; } export interface TileConfig extends Config<GridData> { readonly type: ConfigType.Tile; readonly resizable: boolean; } export interface ShapeConfig extends Config<GridData> { readonly type: ConfigType.Shape; readonly resizable: boolean; } export interface GridConfig extends Config<GridData> { readonly type: ConfigType.Grid; } export interface NullableGridConfig extends Config<GridData | null> { readonly type: ConfigType.NullableGrid; readonly nonNullDefault: GridData; } export interface IconConfig extends Config<string> { readonly type: ConfigType.Icon; } export interface ControlLinesConfig extends Config<ControlLine[]> { readonly type: ConfigType.ControlLines; } export interface NullableNoteConfig extends Config<string | null> { readonly type: ConfigType.NullableNote; } export interface SolvePathConfig extends Config<Position$1[]> { readonly type: ConfigType.SolvePath; } export type AnyConfig = | BooleanConfig | NullableBooleanConfig | NumberConfig | NullableNumberConfig | StringConfig | ColorConfig | ComparisonConfig | WrappingConfig | DirectionConfig | DirectionToggleConfig | OrientationConfig | OrientationToggleConfig | TileConfig | ShapeConfig | GridConfig | NullableGridConfig | IconConfig | ControlLinesConfig | NullableNoteConfig | SolvePathConfig; /** * Compare two config values for equality, using an appropriate method for the config type. * * @param type The type of the config. * @param a The first value to compare. * @param b The second value to compare. * @returns Whether the two values are equal. */ export declare function configEquals<C extends AnyConfig>( type: C['type'], a: C['default'], b: C['default'] ): boolean; export declare function isEventHandler<T>( val: unknown, event: string ): val is T; export interface FinalValidationHandler { /** * Edits the final grid state after all rules and symbols have been validated. * * @param grid The grid that is being validated. * @param solution The solution grid, or null if the solution is not available. * @param state The current state of the grid. */ onFinalValidation( grid: GridData, solution: GridData | null, state: GridState ): GridState; } export declare function handlesFinalValidation<T extends Instruction>( val: T ): val is T & FinalValidationHandler; export interface SymbolDisplayHandler { /** * Controls whether a symbol should be visible in the grid. * * @param grid The grid that is being displayed. * @param solution The solution grid, if it is available. * @param symbol The symbol that is being displayed. * @param editing Whether the grid is being edited. * @returns True if the symbol should be displayed, false otherwise. The symbol will not be displayed if any handler returns false. */ onSymbolDisplay( grid: GridData, solution: GridData | null, symbol: Symbol$1, editing: boolean ): boolean; } export declare function handlesSymbolDisplay<T extends Instruction>( val: T ): val is T & SymbolDisplayHandler; export interface SymbolValidationHandler { /** * Overrides the validation of symbols. * * You can return a different validation result, or call the original validation logic with a modified grid. * * @param grid - The grid to validate. * @param _symbol - The symbol to validate. * @param validator - The original validation logic for the symbol. * @returns The state of the symbol after validation. */ onSymbolValidation( grid: GridData, symbol: Symbol$1, validator: (grid: GridData) => State ): State | undefined; } export declare function handlesSymbolValidation<T extends Rule>( val: T ): val is T & SymbolValidationHandler; export type PuzzleMetadata = { /** * The title of the puzzle. (required) */ title: string; /** * The author of the puzzle. (required) */ author: string; /** * A description of the puzzle. (can be empty) */ description: string; /** * The difficulty of the puzzle, from 0 to 10. (required) * * 0 represents an unrated puzzle, 6-10 represent star difficulties. */ difficulty: number; }; export declare const MetadataSchema: z.ZodObject< { title: z.ZodString; author: z.ZodS