@logic-pad/core 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/logic-core.global.d.ts +22 -0
- package/dist/benchmark/helper.d.ts +21 -0
- package/dist/benchmark/helper.js +34 -0
- package/dist/benchmark/prepareBench.js +140 -0
- package/dist/benchmark/runBench.js +206 -0
- package/dist/{data → src/data}/dataHelper.js +4 -18
- package/dist/{data → src/data}/grid.js +15 -68
- package/dist/{data → src/data}/gridZones.js +1 -6
- package/dist/{data → src/data}/rules/banPatternRule.js +19 -50
- package/dist/{data → src/data}/rules/cellCountPerZoneRule.js +2 -6
- package/dist/{data → src/data}/rules/cellCountRule.js +62 -96
- package/dist/{data → src/data}/rules/completePatternRule.js +6 -22
- package/dist/{data → src/data}/rules/connectAllRule.js +20 -50
- package/dist/{data → src/data}/rules/connectZonesRule.js +28 -58
- package/dist/{data → src/data}/rules/containsShapeRule.js +29 -65
- package/dist/{data → src/data}/rules/customRule.js +28 -57
- package/dist/{data → src/data}/rules/differentCountPerZoneRule.js +33 -68
- package/dist/{data → src/data}/rules/exactCountPerZoneRule.js +43 -82
- package/dist/{data → src/data}/rules/foresightRule.js +50 -87
- package/dist/{data → src/data}/rules/lyingSymbolRule.js +37 -88
- package/dist/{data → src/data}/rules/musicControlLine.js +69 -131
- package/dist/{data → src/data}/rules/musicGridRule.js +43 -76
- package/dist/{data → src/data}/rules/mysteryRule.js +29 -58
- package/dist/src/data/rules/noLoopsRule.d.ts +29 -0
- package/dist/src/data/rules/noLoopsRule.js +111 -0
- package/dist/{data → src/data}/rules/offByXRule.js +49 -74
- package/dist/{data → src/data}/rules/perfectionRule.js +8 -28
- package/dist/{data → src/data}/rules/regionAreaRule.js +47 -86
- package/dist/{data → src/data}/rules/regionShapeRule.js +2 -6
- package/dist/{data → src/data}/rules/rules.gen.d.ts +1 -0
- package/dist/{data → src/data}/rules/rules.gen.js +1 -0
- package/dist/{data → src/data}/rules/sameCountPerZoneRule.js +33 -68
- package/dist/{data → src/data}/rules/sameShapeRule.js +18 -44
- package/dist/{data → src/data}/rules/symbolsPerRegionRule.js +52 -90
- package/dist/{data → src/data}/rules/undercluedRule.js +11 -27
- package/dist/{data → src/data}/rules/uniqueShapeRule.js +18 -44
- package/dist/{data → src/data}/rules/wrapAroundRule.js +99 -138
- package/dist/{data → src/data}/serializer/serializer_checksum.js +1 -9
- package/dist/{data → src/data}/serializer/serializer_v0.js +1 -9
- package/dist/{data → src/data}/solver/auto/autoSolver.js +11 -40
- package/dist/{data → src/data}/solver/backtrack/backtrackSolver.js +15 -39
- package/dist/{data → src/data}/solver/backtrack/backtrackWorker.js +1 -1
- package/dist/{data → src/data}/solver/backtrack/data.js +16 -48
- package/dist/{data → src/data}/solver/backtrack/rules/banPattern.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/cellCount.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/connectAll.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/regionArea.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/regionShape.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/sameShape.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/rules/symbolsPerRegion.js +2 -12
- package/dist/{data → src/data}/solver/backtrack/rules/uniqueShape.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/areaNumber.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/dart.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/directionLinker.js +3 -13
- package/dist/{data → src/data}/solver/backtrack/symbols/focus.js +3 -13
- package/dist/{data → src/data}/solver/backtrack/symbols/galaxy.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/letter.js +2 -12
- package/dist/{data → src/data}/solver/backtrack/symbols/lotus.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/minesweeper.js +3 -13
- package/dist/{data → src/data}/solver/backtrack/symbols/myopia.js +1 -6
- package/dist/{data → src/data}/solver/backtrack/symbols/viewpoint.js +1 -6
- package/dist/{data → src/data}/solver/cspuz/cspuzSolver.js +22 -46
- package/dist/{data → src/data}/solver/eventIteratingSolver.js +9 -12
- package/dist/{data → src/data}/solver/solver.js +1 -8
- package/dist/src/data/solver/universal/universalSolver.js +20 -0
- package/dist/src/data/solver/universal/universalWorker.d.ts +1 -0
- package/dist/{data → src/data}/solver/z3/modules/areaNumberModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/cellCountModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/connectAllModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/dartModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/letterModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/myopiaModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/regionAreaModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/modules/viewpointModule.js +1 -9
- package/dist/{data → src/data}/solver/z3/z3Solver.js +4 -27
- package/dist/{data → src/data}/solver/z3/z3SolverContext.js +3 -12
- package/dist/{data → src/data}/symbols/areaNumberSymbol.js +28 -44
- package/dist/{data → src/data}/symbols/customIconSymbol.js +40 -64
- package/dist/{data → src/data}/symbols/customSymbol.js +4 -12
- package/dist/{data → src/data}/symbols/customTextSymbol.js +40 -64
- package/dist/{data → src/data}/symbols/dartSymbol.js +39 -59
- package/dist/{data → src/data}/symbols/directionLinkerSymbol.js +34 -63
- package/dist/{data → src/data}/symbols/everyLetterSymbol.js +37 -65
- package/dist/{data → src/data}/symbols/focusSymbol.js +49 -69
- package/dist/{data → src/data}/symbols/galaxySymbol.js +12 -31
- package/dist/{data → src/data}/symbols/hiddenSymbol.js +34 -62
- package/dist/{data → src/data}/symbols/houseSymbol.js +39 -67
- package/dist/{data → src/data}/symbols/letterSymbol.js +40 -68
- package/dist/{data → src/data}/symbols/lotusSymbol.js +58 -81
- package/dist/{data → src/data}/symbols/minesweeperSymbol.js +30 -46
- package/dist/{data → src/data}/symbols/myopiaSymbol.js +45 -69
- package/dist/{data → src/data}/symbols/numberSymbol.js +6 -18
- package/dist/{data → src/data}/symbols/symbol.js +4 -12
- package/dist/{data → src/data}/symbols/viewpointSymbol.js +26 -42
- package/dist/{data → src/data}/tile.js +6 -18
- package/dist/src/data/validateAsync.js +71 -0
- package/dist/src/data/validateAsyncWorker.d.ts +1 -0
- package/dist/{index.d.ts → src/index.d.ts} +2 -1
- package/dist/{index.js → src/index.js} +2 -1
- package/package.json +6 -2
- package/dist/data/solver/universal/universalSolver.js +0 -38
- package/dist/data/validateAsync.js +0 -128
- /package/dist/{data/solver/backtrack/backtrackWorker.d.ts → benchmark/prepareBench.d.ts} +0 -0
- /package/dist/{data/solver/cspuz/cspuzWorker.d.ts → benchmark/runBench.d.ts} +0 -0
- /package/dist/{data → src/data}/config.d.ts +0 -0
- /package/dist/{data → src/data}/config.js +0 -0
- /package/dist/{data → src/data}/configurable.d.ts +0 -0
- /package/dist/{data → src/data}/configurable.js +0 -0
- /package/dist/{data → src/data}/dataHelper.d.ts +0 -0
- /package/dist/{data → src/data}/events/eventHelper.d.ts +0 -0
- /package/dist/{data → src/data}/events/eventHelper.js +0 -0
- /package/dist/{data → src/data}/events/onFinalValidation.d.ts +0 -0
- /package/dist/{data → src/data}/events/onFinalValidation.js +0 -0
- /package/dist/{data → src/data}/events/onGetTile.d.ts +0 -0
- /package/dist/{data → src/data}/events/onGetTile.js +0 -0
- /package/dist/{data → src/data}/events/onGridChange.d.ts +0 -0
- /package/dist/{data → src/data}/events/onGridChange.js +0 -0
- /package/dist/{data → src/data}/events/onGridResize.d.ts +0 -0
- /package/dist/{data → src/data}/events/onGridResize.js +0 -0
- /package/dist/{data → src/data}/events/onSetGrid.d.ts +0 -0
- /package/dist/{data → src/data}/events/onSetGrid.js +0 -0
- /package/dist/{data → src/data}/events/onSymbolDisplay.d.ts +0 -0
- /package/dist/{data → src/data}/events/onSymbolDisplay.js +0 -0
- /package/dist/{data → src/data}/events/onSymbolMerge.d.ts +0 -0
- /package/dist/{data → src/data}/events/onSymbolMerge.js +0 -0
- /package/dist/{data → src/data}/events/onSymbolValidation.d.ts +0 -0
- /package/dist/{data → src/data}/events/onSymbolValidation.js +0 -0
- /package/dist/{data → src/data}/grid.d.ts +0 -0
- /package/dist/{data → src/data}/gridConnections.d.ts +0 -0
- /package/dist/{data → src/data}/gridConnections.js +0 -0
- /package/dist/{data → src/data}/gridZones.d.ts +0 -0
- /package/dist/{data → src/data}/instruction.d.ts +0 -0
- /package/dist/{data → src/data}/instruction.js +0 -0
- /package/dist/{data → src/data}/primitives.d.ts +0 -0
- /package/dist/{data → src/data}/primitives.js +0 -0
- /package/dist/{data → src/data}/puzzle.d.ts +0 -0
- /package/dist/{data → src/data}/puzzle.js +0 -0
- /package/dist/{data → src/data}/rules/banPatternRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/cellCountPerZoneRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/cellCountRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/completePatternRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/connectAllRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/connectZonesRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/containsShapeRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/customRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/differentCountPerZoneRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/exactCountPerZoneRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/foresightRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/index.d.ts +0 -0
- /package/dist/{data → src/data}/rules/index.js +0 -0
- /package/dist/{data → src/data}/rules/lyingSymbolRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/musicControlLine.d.ts +0 -0
- /package/dist/{data → src/data}/rules/musicGridRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/mysteryRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/offByXRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/perfectionRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/regionAreaRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/regionShapeRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/rule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/rule.js +0 -0
- /package/dist/{data → src/data}/rules/sameCountPerZoneRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/sameShapeRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/symbolsPerRegionRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/undercluedRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/uniqueShapeRule.d.ts +0 -0
- /package/dist/{data → src/data}/rules/wrapAroundRule.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/allSerializers.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/allSerializers.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/allCompressors.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/allCompressors.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/checksumCompressor.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/checksumCompressor.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/compressorBase.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/compressorBase.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/deflateCompressor.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/deflateCompressor.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/gzipCompressor.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/gzipCompressor.js +0 -0
- /package/dist/{data → src/data}/serializer/compressor/streamCompressor.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/compressor/streamCompressor.js +0 -0
- /package/dist/{data → src/data}/serializer/serializerBase.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/serializerBase.js +0 -0
- /package/dist/{data → src/data}/serializer/serializer_checksum.d.ts +0 -0
- /package/dist/{data → src/data}/serializer/serializer_v0.d.ts +0 -0
- /package/dist/{data → src/data}/shapes.d.ts +0 -0
- /package/dist/{data → src/data}/shapes.js +0 -0
- /package/dist/{data → src/data}/solver/allSolvers.d.ts +0 -0
- /package/dist/{data → src/data}/solver/allSolvers.js +0 -0
- /package/dist/{data → src/data}/solver/auto/autoSolver.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/backtrackSolver.d.ts +0 -0
- /package/dist/{data/solver/universal/universalWorker.d.ts → src/data/solver/backtrack/backtrackWorker.d.ts} +0 -0
- /package/dist/{data → src/data}/solver/backtrack/data.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/banPattern.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/cellCount.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/connectAll.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/regionArea.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/regionShape.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/sameShape.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/symbolsPerRegion.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/rules/uniqueShape.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/areaNumber.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/dart.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/directionLinker.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/focus.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/galaxy.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/letter.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/lotus.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/minesweeper.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/myopia.d.ts +0 -0
- /package/dist/{data → src/data}/solver/backtrack/symbols/viewpoint.d.ts +0 -0
- /package/dist/{data → src/data}/solver/cspuz/cspuzSolver.d.ts +0 -0
- /package/dist/{data/validateAsyncWorker.d.ts → src/data/solver/cspuz/cspuzWorker.d.ts} +0 -0
- /package/dist/{data → src/data}/solver/cspuz/cspuzWorker.js +0 -0
- /package/dist/{data → src/data}/solver/cspuz/jsonify.d.ts +0 -0
- /package/dist/{data → src/data}/solver/cspuz/jsonify.js +0 -0
- /package/dist/{data → src/data}/solver/eventIteratingSolver.d.ts +0 -0
- /package/dist/{data → src/data}/solver/solver.d.ts +0 -0
- /package/dist/{data → src/data}/solver/universal/universalSolver.d.ts +0 -0
- /package/dist/{data → src/data}/solver/universal/universalWorker.js +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/areaNumberModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/cellCountModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/connectAllModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/dartModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/index.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/index.js +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/letterModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/modules.gen.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/modules.gen.js +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/myopiaModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/regionAreaModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/viewpointModule.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/z3Module.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/modules/z3Module.js +0 -0
- /package/dist/{data → src/data}/solver/z3/utils.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/utils.js +0 -0
- /package/dist/{data → src/data}/solver/z3/z3Solver.d.ts +0 -0
- /package/dist/{data → src/data}/solver/z3/z3SolverContext.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/areaNumberSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/customIconSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/customSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/customTextSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/dartSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/directionLinkerSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/everyLetterSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/focusSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/galaxySymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/hiddenSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/houseSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/index.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/index.js +0 -0
- /package/dist/{data → src/data}/symbols/letterSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/lotusSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/minesweeperSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/myopiaSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/numberSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/symbol.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/symbols.gen.d.ts +0 -0
- /package/dist/{data → src/data}/symbols/symbols.gen.js +0 -0
- /package/dist/{data → src/data}/symbols/viewpointSymbol.d.ts +0 -0
- /package/dist/{data → src/data}/tile.d.ts +0 -0
- /package/dist/{data → src/data}/tileConnections.d.ts +0 -0
- /package/dist/{data → src/data}/tileConnections.js +0 -0
- /package/dist/{data → src/data}/validate.d.ts +0 -0
- /package/dist/{data → src/data}/validate.js +0 -0
- /package/dist/{data → src/data}/validateAsync.d.ts +0 -0
- /package/dist/{data → src/data}/validateAsyncWorker.js +0 -0
- /package/dist/{polyfill → src/polyfill}/streamPolyfill.d.ts +0 -0
- /package/dist/{polyfill → src/polyfill}/streamPolyfill.js +0 -0
|
@@ -2,6 +2,40 @@ import { ConfigType } from '../config.js';
|
|
|
2
2
|
import Configurable from '../configurable.js';
|
|
3
3
|
import { Instrument } from '../primitives.js';
|
|
4
4
|
export class Row extends Configurable {
|
|
5
|
+
note;
|
|
6
|
+
instrument;
|
|
7
|
+
velocity;
|
|
8
|
+
title = 'Music Grid - Row';
|
|
9
|
+
configExplanation = 'Configure the playback settings from this tile onwards.';
|
|
10
|
+
static CONFIGS = Object.freeze([
|
|
11
|
+
{
|
|
12
|
+
type: ConfigType.NullableNote,
|
|
13
|
+
default: 'C4',
|
|
14
|
+
field: 'note',
|
|
15
|
+
description: 'Note',
|
|
16
|
+
explanation: 'The musical note or sample to play.',
|
|
17
|
+
configurable: true,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: ConfigType.NullableInstrument,
|
|
21
|
+
default: Instrument.Piano,
|
|
22
|
+
field: 'instrument',
|
|
23
|
+
description: 'Instrument',
|
|
24
|
+
explanation: 'The musical instrument to use. This has no effect if the current note is a drum sample.',
|
|
25
|
+
configurable: true,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: ConfigType.NullableNumber,
|
|
29
|
+
default: 0.5,
|
|
30
|
+
min: 0,
|
|
31
|
+
max: 1,
|
|
32
|
+
step: 0.2,
|
|
33
|
+
field: 'velocity',
|
|
34
|
+
description: 'Velocity',
|
|
35
|
+
explanation: 'The volume to play the note at.',
|
|
36
|
+
configurable: true,
|
|
37
|
+
},
|
|
38
|
+
]);
|
|
5
39
|
constructor(
|
|
6
40
|
/**
|
|
7
41
|
* The note to play at this row, or null to keep the current note from the previous control line.
|
|
@@ -20,36 +54,9 @@ export class Row extends Configurable {
|
|
|
20
54
|
*/
|
|
21
55
|
velocity) {
|
|
22
56
|
super();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
writable: true,
|
|
27
|
-
value: note
|
|
28
|
-
});
|
|
29
|
-
Object.defineProperty(this, "instrument", {
|
|
30
|
-
enumerable: true,
|
|
31
|
-
configurable: true,
|
|
32
|
-
writable: true,
|
|
33
|
-
value: instrument
|
|
34
|
-
});
|
|
35
|
-
Object.defineProperty(this, "velocity", {
|
|
36
|
-
enumerable: true,
|
|
37
|
-
configurable: true,
|
|
38
|
-
writable: true,
|
|
39
|
-
value: velocity
|
|
40
|
-
});
|
|
41
|
-
Object.defineProperty(this, "title", {
|
|
42
|
-
enumerable: true,
|
|
43
|
-
configurable: true,
|
|
44
|
-
writable: true,
|
|
45
|
-
value: 'Music Grid - Row'
|
|
46
|
-
});
|
|
47
|
-
Object.defineProperty(this, "configExplanation", {
|
|
48
|
-
enumerable: true,
|
|
49
|
-
configurable: true,
|
|
50
|
-
writable: true,
|
|
51
|
-
value: 'Configure the playback settings from this tile onwards.'
|
|
52
|
-
});
|
|
57
|
+
this.note = note;
|
|
58
|
+
this.instrument = instrument;
|
|
59
|
+
this.velocity = velocity;
|
|
53
60
|
this.note = note;
|
|
54
61
|
this.instrument = instrument;
|
|
55
62
|
this.velocity = velocity;
|
|
@@ -61,41 +68,42 @@ export class Row extends Configurable {
|
|
|
61
68
|
return new Row(note !== undefined ? note : this.note, instrument !== undefined ? instrument : this.instrument, velocity !== undefined ? velocity : this.velocity);
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
export class ControlLine extends Configurable {
|
|
72
|
+
column;
|
|
73
|
+
bpm;
|
|
74
|
+
pedal;
|
|
75
|
+
checkpoint;
|
|
76
|
+
rows;
|
|
77
|
+
title = 'Music Grid - Control Line';
|
|
78
|
+
configExplanation = 'Configure the playback settings from this point onwards.';
|
|
79
|
+
static CONFIGS = Object.freeze([
|
|
69
80
|
{
|
|
70
|
-
type: ConfigType.
|
|
71
|
-
default:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
type: ConfigType.NullableNumber,
|
|
82
|
+
default: 120,
|
|
83
|
+
min: 20,
|
|
84
|
+
max: 1000,
|
|
85
|
+
field: 'bpm',
|
|
86
|
+
description: 'BPM',
|
|
87
|
+
explanation: 'Beats per minute for the playback.',
|
|
75
88
|
configurable: true,
|
|
76
89
|
},
|
|
77
90
|
{
|
|
78
|
-
type: ConfigType.
|
|
79
|
-
default:
|
|
80
|
-
field: '
|
|
81
|
-
description: '
|
|
82
|
-
explanation: '
|
|
91
|
+
type: ConfigType.NullableBoolean,
|
|
92
|
+
default: false,
|
|
93
|
+
field: 'pedal',
|
|
94
|
+
description: 'Pedal',
|
|
95
|
+
explanation: 'For piano notes, whether the pedal is pressed to sustain the sound.',
|
|
83
96
|
configurable: true,
|
|
84
97
|
},
|
|
85
98
|
{
|
|
86
|
-
type: ConfigType.
|
|
87
|
-
default:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
field: 'velocity',
|
|
92
|
-
description: 'Velocity',
|
|
93
|
-
explanation: 'The volume to play the note at.',
|
|
99
|
+
type: ConfigType.Boolean,
|
|
100
|
+
default: false,
|
|
101
|
+
field: 'checkpoint',
|
|
102
|
+
description: 'Checkpoint',
|
|
103
|
+
explanation: 'Whether players can start playback from this position.',
|
|
94
104
|
configurable: true,
|
|
95
105
|
},
|
|
96
|
-
])
|
|
97
|
-
});
|
|
98
|
-
export class ControlLine extends Configurable {
|
|
106
|
+
]);
|
|
99
107
|
/**
|
|
100
108
|
* Configure playback settings, taking effect at the given column (inclusive)
|
|
101
109
|
* @param column The column at which the settings take effect
|
|
@@ -106,48 +114,11 @@ export class ControlLine extends Configurable {
|
|
|
106
114
|
*/
|
|
107
115
|
constructor(column, bpm, pedal, checkpoint, rows) {
|
|
108
116
|
super();
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
115
|
-
Object.defineProperty(this, "bpm", {
|
|
116
|
-
enumerable: true,
|
|
117
|
-
configurable: true,
|
|
118
|
-
writable: true,
|
|
119
|
-
value: bpm
|
|
120
|
-
});
|
|
121
|
-
Object.defineProperty(this, "pedal", {
|
|
122
|
-
enumerable: true,
|
|
123
|
-
configurable: true,
|
|
124
|
-
writable: true,
|
|
125
|
-
value: pedal
|
|
126
|
-
});
|
|
127
|
-
Object.defineProperty(this, "checkpoint", {
|
|
128
|
-
enumerable: true,
|
|
129
|
-
configurable: true,
|
|
130
|
-
writable: true,
|
|
131
|
-
value: checkpoint
|
|
132
|
-
});
|
|
133
|
-
Object.defineProperty(this, "rows", {
|
|
134
|
-
enumerable: true,
|
|
135
|
-
configurable: true,
|
|
136
|
-
writable: true,
|
|
137
|
-
value: rows
|
|
138
|
-
});
|
|
139
|
-
Object.defineProperty(this, "title", {
|
|
140
|
-
enumerable: true,
|
|
141
|
-
configurable: true,
|
|
142
|
-
writable: true,
|
|
143
|
-
value: 'Music Grid - Control Line'
|
|
144
|
-
});
|
|
145
|
-
Object.defineProperty(this, "configExplanation", {
|
|
146
|
-
enumerable: true,
|
|
147
|
-
configurable: true,
|
|
148
|
-
writable: true,
|
|
149
|
-
value: 'Configure the playback settings from this point onwards.'
|
|
150
|
-
});
|
|
117
|
+
this.column = column;
|
|
118
|
+
this.bpm = bpm;
|
|
119
|
+
this.pedal = pedal;
|
|
120
|
+
this.checkpoint = checkpoint;
|
|
121
|
+
this.rows = rows;
|
|
151
122
|
this.column = Math.floor(column);
|
|
152
123
|
this.bpm = bpm;
|
|
153
124
|
this.pedal = pedal;
|
|
@@ -193,37 +164,4 @@ export class ControlLine extends Configurable {
|
|
|
193
164
|
!this.rows.some(row => row.note !== null || row.velocity !== null));
|
|
194
165
|
}
|
|
195
166
|
}
|
|
196
|
-
Object.defineProperty(ControlLine, "CONFIGS", {
|
|
197
|
-
enumerable: true,
|
|
198
|
-
configurable: true,
|
|
199
|
-
writable: true,
|
|
200
|
-
value: Object.freeze([
|
|
201
|
-
{
|
|
202
|
-
type: ConfigType.NullableNumber,
|
|
203
|
-
default: 120,
|
|
204
|
-
min: 20,
|
|
205
|
-
max: 1000,
|
|
206
|
-
field: 'bpm',
|
|
207
|
-
description: 'BPM',
|
|
208
|
-
explanation: 'Beats per minute for the playback.',
|
|
209
|
-
configurable: true,
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
type: ConfigType.NullableBoolean,
|
|
213
|
-
default: false,
|
|
214
|
-
field: 'pedal',
|
|
215
|
-
description: 'Pedal',
|
|
216
|
-
explanation: 'For piano notes, whether the pedal is pressed to sustain the sound.',
|
|
217
|
-
configurable: true,
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
type: ConfigType.Boolean,
|
|
221
|
-
default: false,
|
|
222
|
-
field: 'checkpoint',
|
|
223
|
-
description: 'Checkpoint',
|
|
224
|
-
explanation: 'Whether players can start playback from this position.',
|
|
225
|
-
configurable: true,
|
|
226
|
-
},
|
|
227
|
-
])
|
|
228
|
-
});
|
|
229
167
|
export const instance = undefined;
|
|
@@ -15,10 +15,49 @@ const DEFAULT_SCALE = [
|
|
|
15
15
|
new Row('D4', Instrument.Piano, null),
|
|
16
16
|
new Row('C4', Instrument.Piano, null),
|
|
17
17
|
];
|
|
18
|
-
class MusicGridRule extends Rule {
|
|
18
|
+
export default class MusicGridRule extends Rule {
|
|
19
|
+
controlLines;
|
|
20
|
+
track;
|
|
21
|
+
normalizeVelocity;
|
|
22
|
+
title = 'Music Grid';
|
|
19
23
|
get configExplanation() {
|
|
20
24
|
return 'Solve the grid by listening to the solution being played back.';
|
|
21
25
|
}
|
|
26
|
+
static EXAMPLE_GRID = Object.freeze(GridData.create(['.']).addSymbol(new CustomIconSymbol('', GridData.create([]), 0, 0, 'MdMusicNote')));
|
|
27
|
+
static CONFIGS = Object.freeze([
|
|
28
|
+
{
|
|
29
|
+
type: ConfigType.ControlLines,
|
|
30
|
+
default: [new ControlLine(0, 120, false, false, DEFAULT_SCALE)],
|
|
31
|
+
field: 'controlLines',
|
|
32
|
+
description: 'Control Lines',
|
|
33
|
+
configurable: false,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: ConfigType.NullableGrid,
|
|
37
|
+
default: null,
|
|
38
|
+
nonNullDefault: GridData.create([
|
|
39
|
+
'wwwww',
|
|
40
|
+
'wwwww',
|
|
41
|
+
'wwwww',
|
|
42
|
+
'wwwww',
|
|
43
|
+
]).addRule(new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALE)], null)),
|
|
44
|
+
field: 'track',
|
|
45
|
+
description: 'Track',
|
|
46
|
+
explanation: 'If set, this grid will be played instead of the solution.',
|
|
47
|
+
configurable: true,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: ConfigType.Boolean,
|
|
51
|
+
default: true,
|
|
52
|
+
field: 'normalizeVelocity',
|
|
53
|
+
description: 'Normalize Velocity',
|
|
54
|
+
explanation: 'Whether to adjust note velocities by their pitch such that every note has the same perceived loudness.',
|
|
55
|
+
configurable: true,
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
static SEARCH_VARIANTS = [
|
|
59
|
+
new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALE)], null).searchVariant(),
|
|
60
|
+
];
|
|
22
61
|
/**
|
|
23
62
|
* **Music Grid: Listen to the solution**
|
|
24
63
|
* @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback.
|
|
@@ -27,30 +66,9 @@ class MusicGridRule extends Rule {
|
|
|
27
66
|
*/
|
|
28
67
|
constructor(controlLines, track, normalizeVelocity = true) {
|
|
29
68
|
super();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
writable: true,
|
|
34
|
-
value: controlLines
|
|
35
|
-
});
|
|
36
|
-
Object.defineProperty(this, "track", {
|
|
37
|
-
enumerable: true,
|
|
38
|
-
configurable: true,
|
|
39
|
-
writable: true,
|
|
40
|
-
value: track
|
|
41
|
-
});
|
|
42
|
-
Object.defineProperty(this, "normalizeVelocity", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
configurable: true,
|
|
45
|
-
writable: true,
|
|
46
|
-
value: normalizeVelocity
|
|
47
|
-
});
|
|
48
|
-
Object.defineProperty(this, "title", {
|
|
49
|
-
enumerable: true,
|
|
50
|
-
configurable: true,
|
|
51
|
-
writable: true,
|
|
52
|
-
value: 'Music Grid'
|
|
53
|
-
});
|
|
69
|
+
this.controlLines = controlLines;
|
|
70
|
+
this.track = track;
|
|
71
|
+
this.normalizeVelocity = normalizeVelocity;
|
|
54
72
|
this.controlLines = MusicGridRule.deduplicateControlLines(controlLines);
|
|
55
73
|
this.track = track;
|
|
56
74
|
this.normalizeVelocity = normalizeVelocity;
|
|
@@ -191,55 +209,4 @@ class MusicGridRule extends Rule {
|
|
|
191
209
|
return Array.from(columns.values()).map(lines => lines.length > 1 ? MusicGridRule.mergeControlLines(...lines) : lines[0]);
|
|
192
210
|
}
|
|
193
211
|
}
|
|
194
|
-
Object.defineProperty(MusicGridRule, "EXAMPLE_GRID", {
|
|
195
|
-
enumerable: true,
|
|
196
|
-
configurable: true,
|
|
197
|
-
writable: true,
|
|
198
|
-
value: Object.freeze(GridData.create(['.']).addSymbol(new CustomIconSymbol('', GridData.create([]), 0, 0, 'MdMusicNote')))
|
|
199
|
-
});
|
|
200
|
-
Object.defineProperty(MusicGridRule, "CONFIGS", {
|
|
201
|
-
enumerable: true,
|
|
202
|
-
configurable: true,
|
|
203
|
-
writable: true,
|
|
204
|
-
value: Object.freeze([
|
|
205
|
-
{
|
|
206
|
-
type: ConfigType.ControlLines,
|
|
207
|
-
default: [new ControlLine(0, 120, false, false, DEFAULT_SCALE)],
|
|
208
|
-
field: 'controlLines',
|
|
209
|
-
description: 'Control Lines',
|
|
210
|
-
configurable: false,
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
type: ConfigType.NullableGrid,
|
|
214
|
-
default: null,
|
|
215
|
-
nonNullDefault: GridData.create([
|
|
216
|
-
'wwwww',
|
|
217
|
-
'wwwww',
|
|
218
|
-
'wwwww',
|
|
219
|
-
'wwwww',
|
|
220
|
-
]).addRule(new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALE)], null)),
|
|
221
|
-
field: 'track',
|
|
222
|
-
description: 'Track',
|
|
223
|
-
explanation: 'If set, this grid will be played instead of the solution.',
|
|
224
|
-
configurable: true,
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
type: ConfigType.Boolean,
|
|
228
|
-
default: true,
|
|
229
|
-
field: 'normalizeVelocity',
|
|
230
|
-
description: 'Normalize Velocity',
|
|
231
|
-
explanation: 'Whether to adjust note velocities by their pitch such that every note has the same perceived loudness.',
|
|
232
|
-
configurable: true,
|
|
233
|
-
},
|
|
234
|
-
])
|
|
235
|
-
});
|
|
236
|
-
Object.defineProperty(MusicGridRule, "SEARCH_VARIANTS", {
|
|
237
|
-
enumerable: true,
|
|
238
|
-
configurable: true,
|
|
239
|
-
writable: true,
|
|
240
|
-
value: [
|
|
241
|
-
new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALE)], null).searchVariant(),
|
|
242
|
-
]
|
|
243
|
-
});
|
|
244
|
-
export default MusicGridRule;
|
|
245
212
|
export const instance = new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALE)], null);
|
|
@@ -4,33 +4,43 @@ import { array } from '../dataHelper.js';
|
|
|
4
4
|
import { Color, State } from '../primitives.js';
|
|
5
5
|
import CustomTextSymbol from '../symbols/customTextSymbol.js';
|
|
6
6
|
import Rule from './rule.js';
|
|
7
|
-
class MysteryRule extends Rule {
|
|
7
|
+
export default class MysteryRule extends Rule {
|
|
8
|
+
solution;
|
|
9
|
+
visible;
|
|
10
|
+
title = 'Alternate Solution';
|
|
8
11
|
get configExplanation() {
|
|
9
12
|
return 'You may use multiple instances of this rule to provide multiple alternate solutions.';
|
|
10
13
|
}
|
|
14
|
+
static EXAMPLE_GRID = Object.freeze(GridData.create(['.']).addSymbol(new CustomTextSymbol('', GridData.create([]), 0, 0, '?')));
|
|
15
|
+
static CONFIGS = Object.freeze([
|
|
16
|
+
{
|
|
17
|
+
type: ConfigType.Tile,
|
|
18
|
+
default: MysteryRule.EXAMPLE_GRID,
|
|
19
|
+
resizable: false,
|
|
20
|
+
field: 'solution',
|
|
21
|
+
description: 'Solution',
|
|
22
|
+
explanation: 'The alternate solution to the puzzle. Does not need to satisfy puzzle rules / symbols.',
|
|
23
|
+
configurable: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: ConfigType.Boolean,
|
|
27
|
+
default: true,
|
|
28
|
+
field: 'visible',
|
|
29
|
+
description: 'Visible',
|
|
30
|
+
explanation: 'Display this rule to the player.',
|
|
31
|
+
configurable: true,
|
|
32
|
+
},
|
|
33
|
+
]);
|
|
34
|
+
static SEARCH_VARIANTS = [
|
|
35
|
+
new MysteryRule(MysteryRule.EXAMPLE_GRID, true).searchVariant(),
|
|
36
|
+
];
|
|
11
37
|
/**
|
|
12
38
|
* **Mystery: alternate solution**
|
|
13
39
|
*/
|
|
14
40
|
constructor(solution, visible) {
|
|
15
41
|
super();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
configurable: true,
|
|
19
|
-
writable: true,
|
|
20
|
-
value: solution
|
|
21
|
-
});
|
|
22
|
-
Object.defineProperty(this, "visible", {
|
|
23
|
-
enumerable: true,
|
|
24
|
-
configurable: true,
|
|
25
|
-
writable: true,
|
|
26
|
-
value: visible
|
|
27
|
-
});
|
|
28
|
-
Object.defineProperty(this, "title", {
|
|
29
|
-
enumerable: true,
|
|
30
|
-
configurable: true,
|
|
31
|
-
writable: true,
|
|
32
|
-
value: 'Alternate Solution'
|
|
33
|
-
});
|
|
42
|
+
this.solution = solution;
|
|
43
|
+
this.visible = visible;
|
|
34
44
|
this.solution = MysteryRule.cleanSolution(solution);
|
|
35
45
|
this.visible = visible;
|
|
36
46
|
}
|
|
@@ -133,43 +143,4 @@ class MysteryRule extends Rule {
|
|
|
133
143
|
return GridData.create(baseGrid?.width ?? solution.width, baseGrid?.height ?? solution.height, tiles);
|
|
134
144
|
}
|
|
135
145
|
}
|
|
136
|
-
Object.defineProperty(MysteryRule, "EXAMPLE_GRID", {
|
|
137
|
-
enumerable: true,
|
|
138
|
-
configurable: true,
|
|
139
|
-
writable: true,
|
|
140
|
-
value: Object.freeze(GridData.create(['.']).addSymbol(new CustomTextSymbol('', GridData.create([]), 0, 0, '?')))
|
|
141
|
-
});
|
|
142
|
-
Object.defineProperty(MysteryRule, "CONFIGS", {
|
|
143
|
-
enumerable: true,
|
|
144
|
-
configurable: true,
|
|
145
|
-
writable: true,
|
|
146
|
-
value: Object.freeze([
|
|
147
|
-
{
|
|
148
|
-
type: ConfigType.Tile,
|
|
149
|
-
default: MysteryRule.EXAMPLE_GRID,
|
|
150
|
-
resizable: false,
|
|
151
|
-
field: 'solution',
|
|
152
|
-
description: 'Solution',
|
|
153
|
-
explanation: 'The alternate solution to the puzzle. Does not need to satisfy puzzle rules / symbols.',
|
|
154
|
-
configurable: true,
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
type: ConfigType.Boolean,
|
|
158
|
-
default: true,
|
|
159
|
-
field: 'visible',
|
|
160
|
-
description: 'Visible',
|
|
161
|
-
explanation: 'Display this rule to the player.',
|
|
162
|
-
configurable: true,
|
|
163
|
-
},
|
|
164
|
-
])
|
|
165
|
-
});
|
|
166
|
-
Object.defineProperty(MysteryRule, "SEARCH_VARIANTS", {
|
|
167
|
-
enumerable: true,
|
|
168
|
-
configurable: true,
|
|
169
|
-
writable: true,
|
|
170
|
-
value: [
|
|
171
|
-
new MysteryRule(MysteryRule.EXAMPLE_GRID, true).searchVariant(),
|
|
172
|
-
]
|
|
173
|
-
});
|
|
174
|
-
export default MysteryRule;
|
|
175
146
|
export const instance = new MysteryRule(GridData.create([]), true);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color, RuleState } from '../primitives.js';
|
|
4
|
+
import Rule, { SearchVariant } from './rule.js';
|
|
5
|
+
export default class NoLoopsRule extends Rule {
|
|
6
|
+
readonly color: Color;
|
|
7
|
+
readonly title = "No Loops";
|
|
8
|
+
private static readonly CONFIGS;
|
|
9
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
10
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
11
|
+
private static readonly SEARCH_VARIANTS;
|
|
12
|
+
/**
|
|
13
|
+
* **No loops in <color> cells**
|
|
14
|
+
*
|
|
15
|
+
* @param color - The color of the cells to check.
|
|
16
|
+
*/
|
|
17
|
+
constructor(color: Color);
|
|
18
|
+
get id(): string;
|
|
19
|
+
get explanation(): string;
|
|
20
|
+
get configs(): readonly AnyConfig[] | null;
|
|
21
|
+
createExampleGrid(): GridData;
|
|
22
|
+
get searchVariants(): SearchVariant[];
|
|
23
|
+
validateGrid(grid: GridData): RuleState;
|
|
24
|
+
copyWith({ color }: {
|
|
25
|
+
color?: Color;
|
|
26
|
+
}): this;
|
|
27
|
+
withColor(color: Color): this;
|
|
28
|
+
}
|
|
29
|
+
export declare const instance: NoLoopsRule;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData, { NEIGHBOR_OFFSETS } from '../grid.js';
|
|
3
|
+
import { array } from '../dataHelper.js';
|
|
4
|
+
import { Color, State } from '../primitives.js';
|
|
5
|
+
import Rule from './rule.js';
|
|
6
|
+
import CustomIconSymbol from '../symbols/customIconSymbol.js';
|
|
7
|
+
export default class NoLoopsRule extends Rule {
|
|
8
|
+
color;
|
|
9
|
+
title = 'No Loops';
|
|
10
|
+
static CONFIGS = Object.freeze([
|
|
11
|
+
{
|
|
12
|
+
type: ConfigType.Color,
|
|
13
|
+
default: Color.Light,
|
|
14
|
+
allowGray: false,
|
|
15
|
+
field: 'color',
|
|
16
|
+
description: 'Color',
|
|
17
|
+
configurable: true,
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
static EXAMPLE_GRID_LIGHT = Object.freeze(GridData.create(['bwwwb', 'bwbww', 'wwwwb', 'wbbww']).withSymbols([
|
|
21
|
+
new CustomIconSymbol('', GridData.create([]), 1, 0, 'MdClear'),
|
|
22
|
+
new CustomIconSymbol('', GridData.create([]), 2, 0, 'MdClear'),
|
|
23
|
+
new CustomIconSymbol('', GridData.create([]), 3, 0, 'MdClear'),
|
|
24
|
+
new CustomIconSymbol('', GridData.create([]), 3, 1, 'MdClear'),
|
|
25
|
+
new CustomIconSymbol('', GridData.create([]), 3, 2, 'MdClear'),
|
|
26
|
+
new CustomIconSymbol('', GridData.create([]), 2, 2, 'MdClear'),
|
|
27
|
+
new CustomIconSymbol('', GridData.create([]), 1, 2, 'MdClear'),
|
|
28
|
+
new CustomIconSymbol('', GridData.create([]), 1, 1, 'MdClear'),
|
|
29
|
+
]));
|
|
30
|
+
static EXAMPLE_GRID_DARK = Object.freeze(NoLoopsRule.EXAMPLE_GRID_LIGHT.withTiles(tiles => tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Dark ? Color.Light : Color.Dark)))));
|
|
31
|
+
static SEARCH_VARIANTS = [
|
|
32
|
+
new NoLoopsRule(Color.Light).searchVariant(),
|
|
33
|
+
new NoLoopsRule(Color.Dark).searchVariant(),
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* **No loops in <color> cells**
|
|
37
|
+
*
|
|
38
|
+
* @param color - The color of the cells to check.
|
|
39
|
+
*/
|
|
40
|
+
constructor(color) {
|
|
41
|
+
super();
|
|
42
|
+
this.color = color;
|
|
43
|
+
this.color = color;
|
|
44
|
+
}
|
|
45
|
+
get id() {
|
|
46
|
+
return `no_loops`;
|
|
47
|
+
}
|
|
48
|
+
get explanation() {
|
|
49
|
+
return `*No loops* in ${this.color} cells`;
|
|
50
|
+
}
|
|
51
|
+
get configs() {
|
|
52
|
+
return NoLoopsRule.CONFIGS;
|
|
53
|
+
}
|
|
54
|
+
createExampleGrid() {
|
|
55
|
+
return this.color === Color.Light
|
|
56
|
+
? NoLoopsRule.EXAMPLE_GRID_LIGHT
|
|
57
|
+
: NoLoopsRule.EXAMPLE_GRID_DARK;
|
|
58
|
+
}
|
|
59
|
+
get searchVariants() {
|
|
60
|
+
return NoLoopsRule.SEARCH_VARIANTS;
|
|
61
|
+
}
|
|
62
|
+
validateGrid(grid) {
|
|
63
|
+
const visited = array(grid.width, grid.height, (i, j) => !grid.getTile(i, j).exists);
|
|
64
|
+
while (true) {
|
|
65
|
+
const seed = grid.find((tile, x, y) => !visited[y][x] && tile.color === this.color);
|
|
66
|
+
if (!seed)
|
|
67
|
+
break;
|
|
68
|
+
let invalid = false;
|
|
69
|
+
const positions = [];
|
|
70
|
+
const stack = [[seed, null]];
|
|
71
|
+
while (stack.length > 0) {
|
|
72
|
+
const [{ x, y }, from] = stack.pop();
|
|
73
|
+
const { x: arrX, y: arrY } = grid.toArrayCoordinates(x, y);
|
|
74
|
+
positions.push({ x, y });
|
|
75
|
+
if (visited[arrY][arrX]) {
|
|
76
|
+
invalid = true;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
visited[arrY][arrX] = true;
|
|
80
|
+
for (const offset of NEIGHBOR_OFFSETS) {
|
|
81
|
+
if (-offset.x === from?.x && -offset.y === from?.y)
|
|
82
|
+
continue;
|
|
83
|
+
const next = { x: x + offset.x, y: y + offset.y };
|
|
84
|
+
if (grid.isPositionValid(next.x, next.y)) {
|
|
85
|
+
const nextTile = grid.getTile(next.x, next.y);
|
|
86
|
+
if (nextTile.exists && nextTile.color === this.color)
|
|
87
|
+
stack.push([next, offset]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (invalid) {
|
|
92
|
+
return {
|
|
93
|
+
state: State.Error,
|
|
94
|
+
positions,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
state: visited.some(row => row.some(v => !v))
|
|
100
|
+
? State.Incomplete
|
|
101
|
+
: State.Satisfied,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
copyWith({ color }) {
|
|
105
|
+
return new NoLoopsRule(color ?? this.color);
|
|
106
|
+
}
|
|
107
|
+
withColor(color) {
|
|
108
|
+
return this.copyWith({ color });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export const instance = new NoLoopsRule(Color.Dark);
|