@logic-pad/core 0.4.4 → 0.4.5

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.
@@ -368,7 +368,7 @@ declare global {
368
368
  readonly x: number;
369
369
  readonly y: number;
370
370
  constructor(x: number, y: number);
371
- abstract validateSymbol(grid: GridData): State;
371
+ abstract validateSymbol(grid: GridData, solution: GridData | null): State;
372
372
  modeVariant(_mode: Mode): Symbol$1 | null;
373
373
  onGridResize(
374
374
  _grid: GridData,
@@ -521,6 +521,7 @@ declare global {
521
521
  {
522
522
  readonly controlLines: readonly ControlLine[];
523
523
  readonly track: GridData | null;
524
+ readonly normalizeVelocity: boolean;
524
525
  private static readonly EXAMPLE_GRID;
525
526
  private static readonly CONFIGS;
526
527
  private static readonly SEARCH_VARIANTS;
@@ -528,8 +529,13 @@ declare global {
528
529
  * **Music Grid: Listen to the solution**
529
530
  * @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback.
530
531
  * @param track The grid to be played when "listen" is clicked. Set as null to play the solution.
532
+ * @param normalizeVelocity Whether to normalize the velocity of the notes by their pitch such that lower notes are played softer.
531
533
  */
532
- constructor(controlLines: readonly ControlLine[], track: GridData | null);
534
+ constructor(
535
+ controlLines: readonly ControlLine[],
536
+ track: GridData | null,
537
+ normalizeVelocity?: boolean
538
+ );
533
539
  get id(): string;
534
540
  get explanation(): string;
535
541
  get configs(): readonly AnyConfig[] | null;
@@ -558,9 +564,11 @@ declare global {
558
564
  copyWith({
559
565
  controlLines,
560
566
  track,
567
+ normalizeVelocity,
561
568
  }: {
562
569
  controlLines?: readonly ControlLine[];
563
570
  track?: GridData | null;
571
+ normalizeVelocity?: boolean;
564
572
  }): this;
565
573
  get validateWithSolution(): boolean;
566
574
  get isSingleton(): boolean;
@@ -1194,12 +1202,14 @@ declare global {
1194
1202
  * Controls whether a symbol should be visible in the grid.
1195
1203
  *
1196
1204
  * @param grid The grid that is being displayed.
1205
+ * @param solution The solution grid, if it is available.
1197
1206
  * @param symbol The symbol that is being displayed.
1198
1207
  * @param editing Whether the grid is being edited.
1199
1208
  * @returns True if the symbol should be displayed, false otherwise. The symbol will not be displayed if any handler returns false.
1200
1209
  */
1201
1210
  onSymbolDisplay(
1202
1211
  grid: GridData,
1212
+ solution: GridData | null,
1203
1213
  symbol: Symbol$1,
1204
1214
  editing: boolean
1205
1215
  ): boolean;
@@ -6028,7 +6038,6 @@ declare global {
6028
6038
  {
6029
6039
  readonly x: number;
6030
6040
  readonly y: number;
6031
- readonly color: Color;
6032
6041
  readonly revealLocation: boolean;
6033
6042
  private static readonly CONFIGS;
6034
6043
  private static readonly EXAMPLE_GRID;
@@ -6037,10 +6046,9 @@ declare global {
6037
6046
  *
6038
6047
  * @param x - The x-coordinate of the symbol.
6039
6048
  * @param y - The y-coordinate of the symbol.
6040
- * @param color - The target color of the cell.
6041
6049
  * @param revealLocation - Whether to reveal the location of the symbol.
6042
6050
  */
6043
- constructor(x: number, y: number, color: Color, revealLocation?: boolean);
6051
+ constructor(x: number, y: number, revealLocation?: boolean);
6044
6052
  get id(): string;
6045
6053
  get explanation(): string;
6046
6054
  get configs(): readonly AnyConfig[] | null;
@@ -6048,24 +6056,22 @@ declare global {
6048
6056
  get necessaryForCompletion(): boolean;
6049
6057
  get visibleWhenSolving(): boolean;
6050
6058
  get sortOrder(): number;
6051
- validateSymbol(grid: GridData): State;
6059
+ validateSymbol(grid: GridData, solution: GridData | null): State;
6052
6060
  onSymbolDisplay(
6053
6061
  grid: GridData,
6062
+ solution: GridData | null,
6054
6063
  symbol: Symbol$1,
6055
6064
  editing: boolean
6056
6065
  ): boolean;
6057
6066
  copyWith({
6058
6067
  x,
6059
6068
  y,
6060
- color,
6061
6069
  revealLocation,
6062
6070
  }: {
6063
6071
  x?: number;
6064
6072
  y?: number;
6065
- color?: Color;
6066
6073
  revealLocation?: boolean;
6067
6074
  }): this;
6068
- withColor(color: Color): this;
6069
6075
  withRevealLocation(revealLocation: boolean): this;
6070
6076
  }
6071
6077
  export declare const allSymbols: Map<string, Symbol$1>;
@@ -6,10 +6,11 @@ export interface SymbolDisplayHandler {
6
6
  * Controls whether a symbol should be visible in the grid.
7
7
  *
8
8
  * @param grid The grid that is being displayed.
9
+ * @param solution The solution grid, if it is available.
9
10
  * @param symbol The symbol that is being displayed.
10
11
  * @param editing Whether the grid is being edited.
11
12
  * @returns True if the symbol should be displayed, false otherwise. The symbol will not be displayed if any handler returns false.
12
13
  */
13
- onSymbolDisplay(grid: GridData, symbol: Symbol, editing: boolean): boolean;
14
+ onSymbolDisplay(grid: GridData, solution: GridData | null, symbol: Symbol, editing: boolean): boolean;
14
15
  }
15
16
  export declare function handlesSymbolDisplay<T extends Instruction>(val: T): val is T & SymbolDisplayHandler;
@@ -49,7 +49,7 @@ Object.defineProperty(Row, "CONFIGS", {
49
49
  },
50
50
  {
51
51
  type: ConfigType.NullableNumber,
52
- default: 0.6,
52
+ default: 0.5,
53
53
  min: 0,
54
54
  max: 1,
55
55
  step: 0.2,
@@ -9,6 +9,7 @@ import Rule, { SearchVariant } from './rule.js';
9
9
  export default class MusicGridRule extends Rule implements GridChangeHandler, SetGridHandler, GridResizeHandler {
10
10
  readonly controlLines: readonly ControlLine[];
11
11
  readonly track: GridData | null;
12
+ readonly normalizeVelocity: boolean;
12
13
  private static readonly EXAMPLE_GRID;
13
14
  private static readonly CONFIGS;
14
15
  private static readonly SEARCH_VARIANTS;
@@ -16,8 +17,9 @@ export default class MusicGridRule extends Rule implements GridChangeHandler, Se
16
17
  * **Music Grid: Listen to the solution**
17
18
  * @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback.
18
19
  * @param track The grid to be played when "listen" is clicked. Set as null to play the solution.
20
+ * @param normalizeVelocity Whether to normalize the velocity of the notes by their pitch such that lower notes are played softer.
19
21
  */
20
- constructor(controlLines: readonly ControlLine[], track: GridData | null);
22
+ constructor(controlLines: readonly ControlLine[], track: GridData | null, normalizeVelocity?: boolean);
21
23
  get id(): string;
22
24
  get explanation(): string;
23
25
  get configs(): readonly AnyConfig[] | null;
@@ -34,9 +36,10 @@ export default class MusicGridRule extends Rule implements GridChangeHandler, Se
34
36
  */
35
37
  setControlLine(controlLine: ControlLine): this;
36
38
  withTrack(track: GridData | null): this;
37
- copyWith({ controlLines, track, }: {
39
+ copyWith({ controlLines, track, normalizeVelocity, }: {
38
40
  controlLines?: readonly ControlLine[];
39
41
  track?: GridData | null;
42
+ normalizeVelocity?: boolean;
40
43
  }): this;
41
44
  get validateWithSolution(): boolean;
42
45
  get isSingleton(): boolean;
@@ -6,22 +6,23 @@ import CustomIconSymbol from '../symbols/customIconSymbol.js';
6
6
  import { ControlLine, Row } from './musicControlLine.js';
7
7
  import Rule from './rule.js';
8
8
  const DEFAULT_SCALLE = [
9
- new Row('C5', 0.6),
10
- new Row('B4', 0.6),
11
- new Row('A4', 0.6),
12
- new Row('G4', 0.6),
13
- new Row('F4', 0.6),
14
- new Row('E4', 0.6),
15
- new Row('D4', 0.6),
16
- new Row('C4', 0.6),
9
+ new Row('C5', null),
10
+ new Row('B4', null),
11
+ new Row('A4', null),
12
+ new Row('G4', null),
13
+ new Row('F4', null),
14
+ new Row('E4', null),
15
+ new Row('D4', null),
16
+ new Row('C4', null),
17
17
  ];
18
18
  class MusicGridRule extends Rule {
19
19
  /**
20
20
  * **Music Grid: Listen to the solution**
21
21
  * @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback.
22
22
  * @param track The grid to be played when "listen" is clicked. Set as null to play the solution.
23
+ * @param normalizeVelocity Whether to normalize the velocity of the notes by their pitch such that lower notes are played softer.
23
24
  */
24
- constructor(controlLines, track) {
25
+ constructor(controlLines, track, normalizeVelocity = true) {
25
26
  super();
26
27
  Object.defineProperty(this, "controlLines", {
27
28
  enumerable: true,
@@ -35,8 +36,15 @@ class MusicGridRule extends Rule {
35
36
  writable: true,
36
37
  value: track
37
38
  });
39
+ Object.defineProperty(this, "normalizeVelocity", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: normalizeVelocity
44
+ });
38
45
  this.controlLines = MusicGridRule.deduplicateControlLines(controlLines);
39
46
  this.track = track;
47
+ this.normalizeVelocity = normalizeVelocity;
40
48
  }
41
49
  get id() {
42
50
  return MajorRule.MusicGrid;
@@ -134,8 +142,8 @@ class MusicGridRule extends Rule {
134
142
  withTrack(track) {
135
143
  return this.copyWith({ track });
136
144
  }
137
- copyWith({ controlLines, track, }) {
138
- return new MusicGridRule(controlLines ?? this.controlLines, track !== undefined ? track : this.track);
145
+ copyWith({ controlLines, track, normalizeVelocity, }) {
146
+ return new MusicGridRule(controlLines ?? this.controlLines, track !== undefined ? track : this.track, normalizeVelocity ?? this.normalizeVelocity);
139
147
  }
140
148
  get validateWithSolution() {
141
149
  return true;
@@ -197,6 +205,13 @@ Object.defineProperty(MusicGridRule, "CONFIGS", {
197
205
  description: 'Track',
198
206
  configurable: true,
199
207
  },
208
+ {
209
+ type: ConfigType.Boolean,
210
+ default: true,
211
+ field: 'normalizeVelocity',
212
+ description: 'Normalize Velocity',
213
+ configurable: true,
214
+ },
200
215
  ])
201
216
  });
202
217
  Object.defineProperty(MusicGridRule, "SEARCH_VARIANTS", {
@@ -173,8 +173,10 @@ export default class SerializerV0 extends SerializerBase {
173
173
  parseConfig(configs, entry) {
174
174
  const [key, value] = entry.split('=');
175
175
  const config = configs.find(x => x.field === key);
176
- if (!config)
177
- throw new Error(`Unknown config: ${key}`);
176
+ if (!config) {
177
+ console.warn(`Unknown config: ${key} when parsing ${entry}`);
178
+ return [key, value];
179
+ }
178
180
  switch (config.type) {
179
181
  case ConfigType.Boolean:
180
182
  return [config.field, value === '1'];
@@ -1,12 +1,11 @@
1
1
  import { AnyConfig } from '../config.js';
2
2
  import { SymbolDisplayHandler } from '../events/onSymbolDisplay.js';
3
3
  import GridData from '../grid.js';
4
- import { Color, State } from '../primitives.js';
4
+ import { State } from '../primitives.js';
5
5
  import Symbol from './symbol.js';
6
6
  export default class HiddenSymbol extends Symbol implements SymbolDisplayHandler {
7
7
  readonly x: number;
8
8
  readonly y: number;
9
- readonly color: Color;
10
9
  readonly revealLocation: boolean;
11
10
  private static readonly CONFIGS;
12
11
  private static readonly EXAMPLE_GRID;
@@ -15,10 +14,9 @@ export default class HiddenSymbol extends Symbol implements SymbolDisplayHandler
15
14
  *
16
15
  * @param x - The x-coordinate of the symbol.
17
16
  * @param y - The y-coordinate of the symbol.
18
- * @param color - The target color of the cell.
19
17
  * @param revealLocation - Whether to reveal the location of the symbol.
20
18
  */
21
- constructor(x: number, y: number, color: Color, revealLocation?: boolean);
19
+ constructor(x: number, y: number, revealLocation?: boolean);
22
20
  get id(): string;
23
21
  get explanation(): string;
24
22
  get configs(): readonly AnyConfig[] | null;
@@ -26,15 +24,13 @@ export default class HiddenSymbol extends Symbol implements SymbolDisplayHandler
26
24
  get necessaryForCompletion(): boolean;
27
25
  get visibleWhenSolving(): boolean;
28
26
  get sortOrder(): number;
29
- validateSymbol(grid: GridData): State;
30
- onSymbolDisplay(grid: GridData, symbol: Symbol, editing: boolean): boolean;
31
- copyWith({ x, y, color, revealLocation, }: {
27
+ validateSymbol(grid: GridData, solution: GridData | null): State;
28
+ onSymbolDisplay(grid: GridData, solution: GridData | null, symbol: Symbol, editing: boolean): boolean;
29
+ copyWith({ x, y, revealLocation, }: {
32
30
  x?: number;
33
31
  y?: number;
34
- color?: Color;
35
32
  revealLocation?: boolean;
36
33
  }): this;
37
- withColor(color: Color): this;
38
34
  withRevealLocation(revealLocation: boolean): this;
39
35
  }
40
36
  export declare const instance: HiddenSymbol;
@@ -9,10 +9,9 @@ class HiddenSymbol extends Symbol {
9
9
  *
10
10
  * @param x - The x-coordinate of the symbol.
11
11
  * @param y - The y-coordinate of the symbol.
12
- * @param color - The target color of the cell.
13
12
  * @param revealLocation - Whether to reveal the location of the symbol.
14
13
  */
15
- constructor(x, y, color, revealLocation = false) {
14
+ constructor(x, y, revealLocation = false) {
16
15
  super(x, y);
17
16
  Object.defineProperty(this, "x", {
18
17
  enumerable: true,
@@ -26,19 +25,12 @@ class HiddenSymbol extends Symbol {
26
25
  writable: true,
27
26
  value: y
28
27
  });
29
- Object.defineProperty(this, "color", {
30
- enumerable: true,
31
- configurable: true,
32
- writable: true,
33
- value: color
34
- });
35
28
  Object.defineProperty(this, "revealLocation", {
36
29
  enumerable: true,
37
30
  configurable: true,
38
31
  writable: true,
39
32
  value: revealLocation
40
33
  });
41
- this.color = color;
42
34
  this.revealLocation = revealLocation;
43
35
  }
44
36
  get id() {
@@ -62,14 +54,20 @@ class HiddenSymbol extends Symbol {
62
54
  get sortOrder() {
63
55
  return 0;
64
56
  }
65
- validateSymbol(grid) {
57
+ validateSymbol(grid, solution) {
66
58
  const thisX = Math.floor(this.x);
67
59
  const thisY = Math.floor(this.y);
68
- return grid.getTile(thisX, thisY).color === this.color
69
- ? State.Satisfied
70
- : State.Incomplete;
60
+ const thisColor = grid.getTile(thisX, thisY).color;
61
+ if (solution) {
62
+ return thisColor === solution.getTile(thisX, thisY).color
63
+ ? State.Satisfied
64
+ : State.Incomplete;
65
+ }
66
+ else {
67
+ return thisColor !== Color.Gray ? State.Satisfied : State.Incomplete;
68
+ }
71
69
  }
72
- onSymbolDisplay(grid, symbol, editing) {
70
+ onSymbolDisplay(grid, solution, symbol, editing) {
73
71
  if (editing)
74
72
  return true;
75
73
  const thisX = Math.floor(this.x);
@@ -78,17 +76,17 @@ class HiddenSymbol extends Symbol {
78
76
  const symY = Math.floor(symbol.y);
79
77
  if (thisX !== symX || thisY !== symY)
80
78
  return true;
81
- const colorMatch = grid.getTile(thisX, thisY).color === this.color;
79
+ const thisColor = grid.getTile(thisX, thisY).color;
80
+ const colorMatch = solution
81
+ ? thisColor === solution.getTile(thisX, thisY).color
82
+ : thisColor !== Color.Gray;
82
83
  if (symbol.id === this.id) {
83
84
  return !colorMatch;
84
85
  }
85
86
  return colorMatch;
86
87
  }
87
- copyWith({ x, y, color, revealLocation, }) {
88
- return new HiddenSymbol(x ?? this.x, y ?? this.y, color ?? this.color, revealLocation ?? this.revealLocation);
89
- }
90
- withColor(color) {
91
- return this.copyWith({ color });
88
+ copyWith({ x, y, revealLocation, }) {
89
+ return new HiddenSymbol(x ?? this.x, y ?? this.y, revealLocation ?? this.revealLocation);
92
90
  }
93
91
  withRevealLocation(revealLocation) {
94
92
  return this.copyWith({ revealLocation });
@@ -113,14 +111,6 @@ Object.defineProperty(HiddenSymbol, "CONFIGS", {
113
111
  description: 'Y',
114
112
  configurable: false,
115
113
  },
116
- {
117
- type: ConfigType.Color,
118
- default: Color.Light,
119
- field: 'color',
120
- allowGray: true,
121
- description: 'Show on color',
122
- configurable: true,
123
- },
124
114
  {
125
115
  type: ConfigType.Boolean,
126
116
  default: false,
@@ -138,4 +128,4 @@ Object.defineProperty(HiddenSymbol, "EXAMPLE_GRID", {
138
128
  ))
139
129
  });
140
130
  export default HiddenSymbol;
141
- export const instance = new HiddenSymbol(0, 0, Color.Light);
131
+ export const instance = new HiddenSymbol(0, 0);
@@ -6,7 +6,7 @@ export default abstract class Symbol extends Instruction implements GridResizeHa
6
6
  readonly x: number;
7
7
  readonly y: number;
8
8
  constructor(x: number, y: number);
9
- abstract validateSymbol(grid: GridData): State;
9
+ abstract validateSymbol(grid: GridData, solution: GridData | null): State;
10
10
  modeVariant(_mode: Mode): Symbol | null;
11
11
  onGridResize(_grid: GridData, mode: 'insert' | 'remove', direction: 'row' | 'column', index: number): this | null;
12
12
  /**
@@ -64,7 +64,7 @@ export default function validateGrid(grid, solution) {
64
64
  grid.symbols.forEach((symbolList, id) => symbolStates.set(id, symbolList.map(s => {
65
65
  if (s.validateWithSolution)
66
66
  requireSolution = true;
67
- return applySymbolOverrides(grid, grid.rules, s, g => s.validateSymbol(g));
67
+ return applySymbolOverrides(grid, grid.rules, s, g => s.validateSymbol(g, solution));
68
68
  })));
69
69
  // apply the result of symbol overrides to the rules that provided them
70
70
  symbolOverrideStates.forEach((states, i) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logic-pad/core",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",