cubegin 0.0.1
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/CHANGELOG.md +17 -0
- package/LICENSE +674 -0
- package/NOTICE +11 -0
- package/README.md +49 -0
- package/dist/scramble-core/src/batch.mjs +18 -0
- package/dist/scramble-core/src/generator.d.mts +35 -0
- package/dist/scramble-core/src/generator.mjs +136 -0
- package/dist/scramble-core/src/generators/clock.d.mts +11 -0
- package/dist/scramble-core/src/generators/clock.mjs +32 -0
- package/dist/scramble-core/src/generators/cube-random-turns.d.mts +11 -0
- package/dist/scramble-core/src/generators/cube-random-turns.mjs +54 -0
- package/dist/scramble-core/src/generators/four-by-four.d.mts +14 -0
- package/dist/scramble-core/src/generators/four-by-four.mjs +43 -0
- package/dist/scramble-core/src/generators/megaminx.d.mts +11 -0
- package/dist/scramble-core/src/generators/megaminx.mjs +18 -0
- package/dist/scramble-core/src/generators/pyraminx.d.mts +11 -0
- package/dist/scramble-core/src/generators/pyraminx.mjs +17 -0
- package/dist/scramble-core/src/generators/skewb.d.mts +11 -0
- package/dist/scramble-core/src/generators/skewb.mjs +17 -0
- package/dist/scramble-core/src/generators/square1.d.mts +11 -0
- package/dist/scramble-core/src/generators/square1.mjs +28 -0
- package/dist/scramble-core/src/generators/three-by-three.d.mts +25 -0
- package/dist/scramble-core/src/generators/three-by-three.mjs +85 -0
- package/dist/scramble-core/src/generators/two-by-two.d.mts +11 -0
- package/dist/scramble-core/src/generators/two-by-two.mjs +17 -0
- package/dist/scramble-core/src/random-source.d.mts +7 -0
- package/dist/scramble-core/src/random-source.mjs +8 -0
- package/dist/scramble-core/src/solvers/min2phase/coord-cube.mjs +10 -0
- package/dist/scramble-core/src/solvers/min2phase/cubie-cube.mjs +246 -0
- package/dist/scramble-core/src/solvers/min2phase/engine.mjs +1281 -0
- package/dist/scramble-core/src/solvers/min2phase/search-wca.mjs +21 -0
- package/dist/scramble-core/src/solvers/min2phase/search.mjs +25 -0
- package/dist/scramble-core/src/solvers/min2phase/tools.mjs +169 -0
- package/dist/scramble-core/src/solvers/min2phase/util.mjs +30 -0
- package/dist/scramble-core/src/solvers/pyraminx-solver.d.mts +17 -0
- package/dist/scramble-core/src/solvers/pyraminx-solver.mjs +350 -0
- package/dist/scramble-core/src/solvers/skewb-solver.d.mts +15 -0
- package/dist/scramble-core/src/solvers/skewb-solver.mjs +399 -0
- package/dist/scramble-core/src/solvers/sq12phase/full-cube.mjs +212 -0
- package/dist/scramble-core/src/solvers/sq12phase/search.mjs +520 -0
- package/dist/scramble-core/src/solvers/sq12phase/shape.mjs +214 -0
- package/dist/scramble-core/src/solvers/sq12phase/square.mjs +135 -0
- package/dist/scramble-core/src/solvers/threephase/center.mjs +798 -0
- package/dist/scramble-core/src/solvers/threephase/edge.mjs +632 -0
- package/dist/scramble-core/src/solvers/threephase/full-cube.mjs +554 -0
- package/dist/scramble-core/src/solvers/threephase/search.mjs +262 -0
- package/dist/scramble-core/src/solvers/threephase/tables.mjs +201 -0
- package/dist/scramble-core/src/solvers/two-by-two-solver.d.mts +15 -0
- package/dist/scramble-core/src/solvers/two-by-two-solver.mjs +298 -0
- package/dist/scramble-core.d.mts +15 -0
- package/dist/scramble-core.mjs +15 -0
- package/dist/scramble-image/src/color.d.mts +12 -0
- package/dist/scramble-image/src/color.mjs +11 -0
- package/dist/scramble-image/src/render.d.mts +10 -0
- package/dist/scramble-image/src/render.mjs +71 -0
- package/dist/scramble-image/src/renderers/clock.d.mts +6 -0
- package/dist/scramble-image/src/renderers/clock.mjs +145 -0
- package/dist/scramble-image/src/renderers/cube-isometric.d.mts +8 -0
- package/dist/scramble-image/src/renderers/cube-isometric.mjs +204 -0
- package/dist/scramble-image/src/renderers/cube-net.d.mts +8 -0
- package/dist/scramble-image/src/renderers/cube-net.mjs +52 -0
- package/dist/scramble-image/src/renderers/megaminx-isometric.d.mts +9 -0
- package/dist/scramble-image/src/renderers/megaminx-isometric.mjs +320 -0
- package/dist/scramble-image/src/renderers/megaminx.d.mts +9 -0
- package/dist/scramble-image/src/renderers/megaminx.mjs +173 -0
- package/dist/scramble-image/src/renderers/pyraminx-isometric.d.mts +9 -0
- package/dist/scramble-image/src/renderers/pyraminx-isometric.mjs +185 -0
- package/dist/scramble-image/src/renderers/pyraminx.d.mts +9 -0
- package/dist/scramble-image/src/renderers/pyraminx.mjs +111 -0
- package/dist/scramble-image/src/renderers/skewb-isometric.d.mts +9 -0
- package/dist/scramble-image/src/renderers/skewb-isometric.mjs +233 -0
- package/dist/scramble-image/src/renderers/skewb.d.mts +9 -0
- package/dist/scramble-image/src/renderers/skewb.mjs +187 -0
- package/dist/scramble-image/src/renderers/square1.d.mts +10 -0
- package/dist/scramble-image/src/renderers/square1.mjs +253 -0
- package/dist/scramble-image/src/svg/svg-document.d.mts +6 -0
- package/dist/scramble-image/src/svg/svg-document.mjs +7 -0
- package/dist/scramble-image/src/svg/svg-elements.d.mts +15 -0
- package/dist/scramble-image/src/svg/svg-elements.mjs +25 -0
- package/dist/scramble-image/src/svg/svg-serialize.mjs +29 -0
- package/dist/scramble-image.d.mts +15 -0
- package/dist/scramble-image.mjs +15 -0
- package/dist/scramble-puzzle/src/algorithm.d.mts +8 -0
- package/dist/scramble-puzzle/src/algorithm.mjs +16 -0
- package/dist/scramble-puzzle/src/algorithm2.mjs +16 -0
- package/dist/scramble-puzzle/src/clock/clock-definition.d.mts +8 -0
- package/dist/scramble-puzzle/src/clock/clock-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/clock/clock-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/clock/clock-parser.d.mts +18 -0
- package/dist/scramble-puzzle/src/clock/clock-parser.mjs +35 -0
- package/dist/scramble-puzzle/src/clock/clock-parser2.mjs +35 -0
- package/dist/scramble-puzzle/src/clock/clock-state.d.mts +8 -0
- package/dist/scramble-puzzle/src/clock/clock-state.mjs +212 -0
- package/dist/scramble-puzzle/src/clock/clock-state2.d.mts +13 -0
- package/dist/scramble-puzzle/src/clock/clock-state2.mjs +212 -0
- package/dist/scramble-puzzle/src/cube/cube-definition.d.mts +9 -0
- package/dist/scramble-puzzle/src/cube/cube-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/cube/cube-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/cube/cube-move.d.mts +4 -0
- package/dist/scramble-puzzle/src/cube/cube-move2.d.mts +17 -0
- package/dist/scramble-puzzle/src/cube/cube-parser.d.mts +7 -0
- package/dist/scramble-puzzle/src/cube/cube-parser.mjs +60 -0
- package/dist/scramble-puzzle/src/cube/cube-parser2.mjs +60 -0
- package/dist/scramble-puzzle/src/cube/cube-state.d.mts +12 -0
- package/dist/scramble-puzzle/src/cube/cube-state.mjs +187 -0
- package/dist/scramble-puzzle/src/cube/cube-state2.d.mts +15 -0
- package/dist/scramble-puzzle/src/cube/cube-state2.mjs +187 -0
- package/dist/scramble-puzzle/src/errors.d.mts +15 -0
- package/dist/scramble-puzzle/src/errors.mjs +24 -0
- package/dist/scramble-puzzle/src/errors2.mjs +30 -0
- package/dist/scramble-puzzle/src/events.d.mts +5 -0
- package/dist/scramble-puzzle/src/events.mjs +90 -0
- package/dist/scramble-puzzle/src/events2.d.mts +98 -0
- package/dist/scramble-puzzle/src/events2.mjs +109 -0
- package/dist/scramble-puzzle/src/index.mjs +22 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-definition.d.mts +8 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-parser.d.mts +5 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-parser.mjs +57 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-parser2.d.mts +20 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-parser2.mjs +57 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-state.d.mts +9 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-state.mjs +112 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-state2.d.mts +14 -0
- package/dist/scramble-puzzle/src/megaminx/megaminx-state2.mjs +112 -0
- package/dist/scramble-puzzle/src/puzzle-definition.d.mts +19 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition.d.mts +8 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser.d.mts +5 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser.mjs +34 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser2.d.mts +21 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser2.mjs +34 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-state.d.mts +11 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-state.mjs +90 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-state2.d.mts +14 -0
- package/dist/scramble-puzzle/src/pyraminx/pyraminx-state2.mjs +90 -0
- package/dist/scramble-puzzle/src/registry.d.mts +11 -0
- package/dist/scramble-puzzle/src/registry.mjs +13 -0
- package/dist/scramble-puzzle/src/skewb/skewb-definition.d.mts +8 -0
- package/dist/scramble-puzzle/src/skewb/skewb-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/skewb/skewb-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/skewb/skewb-parser.d.mts +5 -0
- package/dist/scramble-puzzle/src/skewb/skewb-parser.mjs +33 -0
- package/dist/scramble-puzzle/src/skewb/skewb-parser2.d.mts +14 -0
- package/dist/scramble-puzzle/src/skewb/skewb-parser2.mjs +33 -0
- package/dist/scramble-puzzle/src/skewb/skewb-state.d.mts +11 -0
- package/dist/scramble-puzzle/src/skewb/skewb-state.mjs +75 -0
- package/dist/scramble-puzzle/src/skewb/skewb-state2.d.mts +14 -0
- package/dist/scramble-puzzle/src/skewb/skewb-state2.mjs +75 -0
- package/dist/scramble-puzzle/src/square1/square1-definition.d.mts +8 -0
- package/dist/scramble-puzzle/src/square1/square1-definition.mjs +18 -0
- package/dist/scramble-puzzle/src/square1/square1-definition2.mjs +18 -0
- package/dist/scramble-puzzle/src/square1/square1-parser.d.mts +17 -0
- package/dist/scramble-puzzle/src/square1/square1-parser.mjs +43 -0
- package/dist/scramble-puzzle/src/square1/square1-parser2.mjs +47 -0
- package/dist/scramble-puzzle/src/square1/square1-state.d.mts +9 -0
- package/dist/scramble-puzzle/src/square1/square1-state.mjs +115 -0
- package/dist/scramble-puzzle/src/square1/square1-state2.d.mts +21 -0
- package/dist/scramble-puzzle/src/square1/square1-state2.mjs +115 -0
- package/dist/scramble-puzzle.d.mts +25 -0
- package/dist/scramble-puzzle.mjs +23 -0
- package/package.json +37 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-image/src/svg/svg-elements.d.ts
|
|
2
|
+
type SvgElementName = 'rect' | 'circle' | 'path' | 'text' | 'g';
|
|
3
|
+
interface SvgNode {
|
|
4
|
+
name: SvgElementName;
|
|
5
|
+
attrs: Record<string, string | number>;
|
|
6
|
+
children?: readonly SvgNode[];
|
|
7
|
+
text?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const rect: (attrs: Record<string, string | number>) => SvgNode;
|
|
10
|
+
declare const circle: (attrs: Record<string, string | number>) => SvgNode;
|
|
11
|
+
declare const path: (attrs: Record<string, string | number>) => SvgNode;
|
|
12
|
+
declare const text: (attrs: Record<string, string | number>, value: string) => SvgNode;
|
|
13
|
+
declare const group: (attrs: Record<string, string | number>, children: readonly SvgNode[]) => SvgNode;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { SvgNode, circle, group, path, rect, text };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-image/src/svg/svg-elements.ts
|
|
2
|
+
const rect = (attrs) => ({
|
|
3
|
+
name: "rect",
|
|
4
|
+
attrs
|
|
5
|
+
});
|
|
6
|
+
const circle = (attrs) => ({
|
|
7
|
+
name: "circle",
|
|
8
|
+
attrs
|
|
9
|
+
});
|
|
10
|
+
const path = (attrs) => ({
|
|
11
|
+
name: "path",
|
|
12
|
+
attrs
|
|
13
|
+
});
|
|
14
|
+
const text = (attrs, value) => ({
|
|
15
|
+
name: "text",
|
|
16
|
+
attrs,
|
|
17
|
+
text: value
|
|
18
|
+
});
|
|
19
|
+
const group = (attrs, children) => ({
|
|
20
|
+
name: "g",
|
|
21
|
+
attrs,
|
|
22
|
+
children
|
|
23
|
+
});
|
|
24
|
+
//#endregion
|
|
25
|
+
export { circle, group, path, rect, text };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-image/src/svg/svg-serialize.ts
|
|
2
|
+
const ERROR_PREFIX = "@cubegin/scramble-image";
|
|
3
|
+
const SUPPORTED_ELEMENT_NAMES = new Set([
|
|
4
|
+
"rect",
|
|
5
|
+
"circle",
|
|
6
|
+
"path",
|
|
7
|
+
"text",
|
|
8
|
+
"g"
|
|
9
|
+
]);
|
|
10
|
+
const SVG_NAME_PATTERN = /^[A-Za-z_:][A-Za-z0-9_.:-]*$/;
|
|
11
|
+
const escapeAttr = (value) => String(value).replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
12
|
+
const assertValidElementName = (name) => {
|
|
13
|
+
if (!SUPPORTED_ELEMENT_NAMES.has(name)) throw new Error(`${ERROR_PREFIX}: invalid SVG element name '${name}'`);
|
|
14
|
+
};
|
|
15
|
+
const assertValidAttrName = (name) => {
|
|
16
|
+
if (!SVG_NAME_PATTERN.test(name)) throw new Error(`${ERROR_PREFIX}: invalid SVG attribute name '${name}'`);
|
|
17
|
+
};
|
|
18
|
+
const serializeSvgNode = (node) => {
|
|
19
|
+
assertValidElementName(node.name);
|
|
20
|
+
const attrs = Object.entries(node.attrs).map(([key, value]) => {
|
|
21
|
+
assertValidAttrName(key);
|
|
22
|
+
return ` ${key}="${escapeAttr(value)}"`;
|
|
23
|
+
}).join("");
|
|
24
|
+
const children = node.children?.map(serializeSvgNode).join("") ?? "";
|
|
25
|
+
const text = node.text === void 0 ? "" : escapeAttr(node.text);
|
|
26
|
+
return `<${node.name}${attrs}>${children}${text}</${node.name}>`;
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { serializeSvgNode };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DEFAULT_CUBE_COLORS, HexColor } from "./scramble-image/src/color.mjs";
|
|
2
|
+
import { ScrambleImageOptions, ScrambleImageView, renderScrambleImage } from "./scramble-image/src/render.mjs";
|
|
3
|
+
import { renderClockState } from "./scramble-image/src/renderers/clock.mjs";
|
|
4
|
+
import { CubeIsometricColorScheme, renderCubeIsometric } from "./scramble-image/src/renderers/cube-isometric.mjs";
|
|
5
|
+
import { renderCubeNet } from "./scramble-image/src/renderers/cube-net.mjs";
|
|
6
|
+
import { MegaminxIsometricColorScheme, renderMegaminxIsometricState } from "./scramble-image/src/renderers/megaminx-isometric.mjs";
|
|
7
|
+
import { MegaminxColorScheme, renderMegaminxState } from "./scramble-image/src/renderers/megaminx.mjs";
|
|
8
|
+
import { PyraminxIsometricColorScheme, renderPyraminxIsometricState } from "./scramble-image/src/renderers/pyraminx-isometric.mjs";
|
|
9
|
+
import { PyraminxColorScheme, renderPyraminxState } from "./scramble-image/src/renderers/pyraminx.mjs";
|
|
10
|
+
import { SkewbIsometricColorScheme, renderSkewbIsometricState } from "./scramble-image/src/renderers/skewb-isometric.mjs";
|
|
11
|
+
import { SkewbColorScheme, renderSkewbState } from "./scramble-image/src/renderers/skewb.mjs";
|
|
12
|
+
import { SquareOneColorScheme, SquareOneFace, renderSquareOneState } from "./scramble-image/src/renderers/square1.mjs";
|
|
13
|
+
import { SvgNode, circle, group, path, rect, text } from "./scramble-image/src/svg/svg-elements.mjs";
|
|
14
|
+
import { createSvgDocument } from "./scramble-image/src/svg/svg-document.mjs";
|
|
15
|
+
export { type CubeIsometricColorScheme, DEFAULT_CUBE_COLORS, type HexColor, type MegaminxColorScheme, type MegaminxIsometricColorScheme, type PyraminxColorScheme, type PyraminxIsometricColorScheme, type ScrambleImageOptions, type ScrambleImageView, type SkewbColorScheme, type SkewbIsometricColorScheme, type SquareOneColorScheme, type SquareOneFace, type SvgNode, circle, createSvgDocument, group, path, rect, renderClockState, renderCubeIsometric, renderCubeNet, renderMegaminxIsometricState, renderMegaminxState, renderPyraminxIsometricState, renderPyraminxState, renderScrambleImage, renderSkewbIsometricState, renderSkewbState, renderSquareOneState, text };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DEFAULT_CUBE_COLORS } from "./scramble-image/src/color.mjs";
|
|
2
|
+
import { createSvgDocument } from "./scramble-image/src/svg/svg-document.mjs";
|
|
3
|
+
import { circle, group, path, rect, text } from "./scramble-image/src/svg/svg-elements.mjs";
|
|
4
|
+
import { renderClockState } from "./scramble-image/src/renderers/clock.mjs";
|
|
5
|
+
import { renderCubeIsometric } from "./scramble-image/src/renderers/cube-isometric.mjs";
|
|
6
|
+
import { renderCubeNet } from "./scramble-image/src/renderers/cube-net.mjs";
|
|
7
|
+
import { renderMegaminxIsometricState } from "./scramble-image/src/renderers/megaminx-isometric.mjs";
|
|
8
|
+
import { renderMegaminxState } from "./scramble-image/src/renderers/megaminx.mjs";
|
|
9
|
+
import { renderPyraminxIsometricState } from "./scramble-image/src/renderers/pyraminx-isometric.mjs";
|
|
10
|
+
import { renderPyraminxState } from "./scramble-image/src/renderers/pyraminx.mjs";
|
|
11
|
+
import { renderSkewbIsometricState } from "./scramble-image/src/renderers/skewb-isometric.mjs";
|
|
12
|
+
import { renderSkewbState } from "./scramble-image/src/renderers/skewb.mjs";
|
|
13
|
+
import { renderSquareOneState } from "./scramble-image/src/renderers/square1.mjs";
|
|
14
|
+
import { renderScrambleImage } from "./scramble-image/src/render.mjs";
|
|
15
|
+
export { DEFAULT_CUBE_COLORS, circle, createSvgDocument, group, path, rect, renderClockState, renderCubeIsometric, renderCubeNet, renderMegaminxIsometricState, renderMegaminxState, renderPyraminxIsometricState, renderPyraminxState, renderScrambleImage, renderSkewbIsometricState, renderSkewbState, renderSquareOneState, text };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PuzzleDefinition } from "./puzzle-definition.mjs";
|
|
2
|
+
|
|
3
|
+
//#region .build/vendor/scramble-puzzle/src/algorithm.d.ts
|
|
4
|
+
type AlgorithmApplier<State, Move> = Pick<PuzzleDefinition<State, Move>, 'applyMove' | 'parseAlgorithm'>;
|
|
5
|
+
declare const splitAlgorithm: (algorithm: string) => readonly string[];
|
|
6
|
+
declare const applyAlgorithm: <State, Move>(definition: AlgorithmApplier<State, Move>, state: State, algorithm: string) => State;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { applyAlgorithm, splitAlgorithm };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { InvalidScrambleError } from "./errors.mjs";
|
|
2
|
+
//#region ../scramble-puzzle/src/algorithm.ts
|
|
3
|
+
const splitAlgorithm = (algorithm) => {
|
|
4
|
+
const trimmedAlgorithm = algorithm.trim();
|
|
5
|
+
if (trimmedAlgorithm.length === 0) return [];
|
|
6
|
+
return trimmedAlgorithm.split(/\s+/u);
|
|
7
|
+
};
|
|
8
|
+
const applyAlgorithm = (definition, state, algorithm) => {
|
|
9
|
+
try {
|
|
10
|
+
return definition.parseAlgorithm(algorithm).reduce((nextState, move) => definition.applyMove(nextState, move), state);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
throw new InvalidScrambleError(algorithm, err);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { applyAlgorithm, splitAlgorithm };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { InvalidScrambleError } from "./errors2.mjs";
|
|
2
|
+
//#region .build/vendor/scramble-puzzle/src/algorithm.ts
|
|
3
|
+
const splitAlgorithm = (algorithm) => {
|
|
4
|
+
const trimmedAlgorithm = algorithm.trim();
|
|
5
|
+
if (trimmedAlgorithm.length === 0) return [];
|
|
6
|
+
return trimmedAlgorithm.split(/\s+/u);
|
|
7
|
+
};
|
|
8
|
+
const applyAlgorithm = (definition, state, algorithm) => {
|
|
9
|
+
try {
|
|
10
|
+
return definition.parseAlgorithm(algorithm).reduce((nextState, move) => definition.applyMove(nextState, move), state);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
throw new InvalidScrambleError(algorithm, err);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { applyAlgorithm, splitAlgorithm };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PuzzleDefinition } from "../puzzle-definition.mjs";
|
|
2
|
+
import { ClockMove } from "./clock-parser.mjs";
|
|
3
|
+
import { ClockState } from "./clock-state2.mjs";
|
|
4
|
+
|
|
5
|
+
//#region .build/vendor/scramble-puzzle/src/clock/clock-definition.d.ts
|
|
6
|
+
declare const createClockDefinition: () => PuzzleDefinition<ClockState, ClockMove>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { createClockDefinition };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { applyAlgorithm } from "../algorithm.mjs";
|
|
2
|
+
import { parseClockAlgorithm } from "./clock-parser.mjs";
|
|
3
|
+
import { applyClockMove, areClockStatesEqual, createSolvedClockState } from "./clock-state.mjs";
|
|
4
|
+
//#region ../scramble-puzzle/src/clock/clock-definition.ts
|
|
5
|
+
const createClockDefinition = () => {
|
|
6
|
+
const definition = {
|
|
7
|
+
id: "clock",
|
|
8
|
+
eventIds: ["clock"],
|
|
9
|
+
createSolvedState: createSolvedClockState,
|
|
10
|
+
parseAlgorithm: parseClockAlgorithm,
|
|
11
|
+
applyMove: applyClockMove,
|
|
12
|
+
applyAlgorithm: (state, algorithm) => applyAlgorithm(definition, state, algorithm),
|
|
13
|
+
isSolved: (state) => areClockStatesEqual(state, createSolvedClockState())
|
|
14
|
+
};
|
|
15
|
+
return definition;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { createClockDefinition };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { applyAlgorithm } from "../algorithm2.mjs";
|
|
2
|
+
import { parseClockAlgorithm } from "./clock-parser2.mjs";
|
|
3
|
+
import { applyClockMove, areClockStatesEqual, createSolvedClockState } from "./clock-state2.mjs";
|
|
4
|
+
//#region .build/vendor/scramble-puzzle/src/clock/clock-definition.ts
|
|
5
|
+
const createClockDefinition = () => {
|
|
6
|
+
const definition = {
|
|
7
|
+
id: "clock",
|
|
8
|
+
eventIds: ["clock"],
|
|
9
|
+
createSolvedState: createSolvedClockState,
|
|
10
|
+
parseAlgorithm: parseClockAlgorithm,
|
|
11
|
+
applyMove: applyClockMove,
|
|
12
|
+
applyAlgorithm: (state, algorithm) => applyAlgorithm(definition, state, algorithm),
|
|
13
|
+
isSolved: (state) => areClockStatesEqual(state, createSolvedClockState())
|
|
14
|
+
};
|
|
15
|
+
return definition;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { createClockDefinition };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-puzzle/src/clock/clock-parser.d.ts
|
|
2
|
+
declare const CLOCK_TURN_NAMES: readonly ["UR", "DR", "DL", "UL", "U", "R", "D", "L", "ALL"];
|
|
3
|
+
type ClockTurnName = (typeof CLOCK_TURN_NAMES)[number];
|
|
4
|
+
type ClockDirection = '+' | '-';
|
|
5
|
+
interface ClockTurnMove {
|
|
6
|
+
readonly type: 'turn';
|
|
7
|
+
readonly name: ClockTurnName;
|
|
8
|
+
readonly amount: number;
|
|
9
|
+
readonly direction: ClockDirection;
|
|
10
|
+
}
|
|
11
|
+
interface ClockRotationMove {
|
|
12
|
+
readonly type: 'rotation';
|
|
13
|
+
}
|
|
14
|
+
type ClockMove = ClockTurnMove | ClockRotationMove;
|
|
15
|
+
declare const parseClockMove: (token: string) => ClockMove;
|
|
16
|
+
declare const parseClockAlgorithm: (algorithm: string) => readonly ClockMove[];
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ClockDirection, ClockMove, ClockRotationMove, ClockTurnMove, ClockTurnName, parseClockAlgorithm, parseClockMove };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InvalidMoveError } from "../errors.mjs";
|
|
2
|
+
import { splitAlgorithm } from "../algorithm.mjs";
|
|
3
|
+
//#region ../scramble-puzzle/src/clock/clock-parser.ts
|
|
4
|
+
const CLOCK_TURN_NAMES = [
|
|
5
|
+
"UR",
|
|
6
|
+
"DR",
|
|
7
|
+
"DL",
|
|
8
|
+
"UL",
|
|
9
|
+
"U",
|
|
10
|
+
"R",
|
|
11
|
+
"D",
|
|
12
|
+
"L",
|
|
13
|
+
"ALL"
|
|
14
|
+
];
|
|
15
|
+
const CLOCK_MOVE_PATTERN = /^(UR|DR|DL|UL|ALL|U|R|D|L)(\d)([+-])$/;
|
|
16
|
+
const CLOCK_TURN_NAME_SET = new Set(CLOCK_TURN_NAMES);
|
|
17
|
+
const isClockTurnName = (name) => CLOCK_TURN_NAME_SET.has(name);
|
|
18
|
+
const parseClockMove = (token) => {
|
|
19
|
+
if (token === "y2") return { type: "rotation" };
|
|
20
|
+
const match = token.match(CLOCK_MOVE_PATTERN);
|
|
21
|
+
if (!match) throw new InvalidMoveError(token, "clock");
|
|
22
|
+
const [, name, amountText, direction] = match;
|
|
23
|
+
if (!isClockTurnName(name) || direction !== "+" && direction !== "-") throw new InvalidMoveError(token, "clock");
|
|
24
|
+
const amount = Number(amountText);
|
|
25
|
+
if (!Number.isSafeInteger(amount) || amount < 0 || amount > 6 || direction === "-" && (amount === 0 || amount === 6)) throw new InvalidMoveError(token, "clock");
|
|
26
|
+
return {
|
|
27
|
+
type: "turn",
|
|
28
|
+
name,
|
|
29
|
+
amount,
|
|
30
|
+
direction
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const parseClockAlgorithm = (algorithm) => splitAlgorithm(algorithm).map(parseClockMove);
|
|
34
|
+
//#endregion
|
|
35
|
+
export { CLOCK_TURN_NAMES, parseClockAlgorithm, parseClockMove };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InvalidMoveError } from "../errors2.mjs";
|
|
2
|
+
import { splitAlgorithm } from "../algorithm2.mjs";
|
|
3
|
+
//#region .build/vendor/scramble-puzzle/src/clock/clock-parser.ts
|
|
4
|
+
const CLOCK_TURN_NAMES = [
|
|
5
|
+
"UR",
|
|
6
|
+
"DR",
|
|
7
|
+
"DL",
|
|
8
|
+
"UL",
|
|
9
|
+
"U",
|
|
10
|
+
"R",
|
|
11
|
+
"D",
|
|
12
|
+
"L",
|
|
13
|
+
"ALL"
|
|
14
|
+
];
|
|
15
|
+
const CLOCK_MOVE_PATTERN = /^(UR|DR|DL|UL|ALL|U|R|D|L)(\d)([+-])$/;
|
|
16
|
+
const CLOCK_TURN_NAME_SET = new Set(CLOCK_TURN_NAMES);
|
|
17
|
+
const isClockTurnName = (name) => CLOCK_TURN_NAME_SET.has(name);
|
|
18
|
+
const parseClockMove = (token) => {
|
|
19
|
+
if (token === "y2") return { type: "rotation" };
|
|
20
|
+
const match = token.match(CLOCK_MOVE_PATTERN);
|
|
21
|
+
if (!match) throw new InvalidMoveError(token, "clock");
|
|
22
|
+
const [, name, amountText, direction] = match;
|
|
23
|
+
if (!isClockTurnName(name) || direction !== "+" && direction !== "-") throw new InvalidMoveError(token, "clock");
|
|
24
|
+
const amount = Number(amountText);
|
|
25
|
+
if (!Number.isSafeInteger(amount) || amount < 0 || amount > 6 || direction === "-" && (amount === 0 || amount === 6)) throw new InvalidMoveError(token, "clock");
|
|
26
|
+
return {
|
|
27
|
+
type: "turn",
|
|
28
|
+
name,
|
|
29
|
+
amount,
|
|
30
|
+
direction
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const parseClockAlgorithm = (algorithm) => splitAlgorithm(algorithm).map(parseClockMove);
|
|
34
|
+
//#endregion
|
|
35
|
+
export { CLOCK_TURN_NAMES, parseClockAlgorithm, parseClockMove };
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { InvalidMoveError } from "../errors.mjs";
|
|
2
|
+
import { CLOCK_TURN_NAMES } from "./clock-parser.mjs";
|
|
3
|
+
//#region ../scramble-puzzle/src/clock/clock-state.ts
|
|
4
|
+
const MALFORMED_MOVE = "<malformed>";
|
|
5
|
+
const CLOCK_MOVE_DELTAS = new Map([
|
|
6
|
+
["UR", [
|
|
7
|
+
0,
|
|
8
|
+
1,
|
|
9
|
+
1,
|
|
10
|
+
0,
|
|
11
|
+
1,
|
|
12
|
+
1,
|
|
13
|
+
0,
|
|
14
|
+
0,
|
|
15
|
+
0,
|
|
16
|
+
-1,
|
|
17
|
+
0,
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
0,
|
|
21
|
+
0,
|
|
22
|
+
0,
|
|
23
|
+
0,
|
|
24
|
+
0
|
|
25
|
+
]],
|
|
26
|
+
["DR", [
|
|
27
|
+
0,
|
|
28
|
+
0,
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
1,
|
|
32
|
+
1,
|
|
33
|
+
0,
|
|
34
|
+
1,
|
|
35
|
+
1,
|
|
36
|
+
0,
|
|
37
|
+
0,
|
|
38
|
+
0,
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
0,
|
|
42
|
+
-1,
|
|
43
|
+
0,
|
|
44
|
+
0
|
|
45
|
+
]],
|
|
46
|
+
["DL", [
|
|
47
|
+
0,
|
|
48
|
+
0,
|
|
49
|
+
0,
|
|
50
|
+
1,
|
|
51
|
+
1,
|
|
52
|
+
0,
|
|
53
|
+
1,
|
|
54
|
+
1,
|
|
55
|
+
0,
|
|
56
|
+
0,
|
|
57
|
+
0,
|
|
58
|
+
0,
|
|
59
|
+
0,
|
|
60
|
+
0,
|
|
61
|
+
0,
|
|
62
|
+
0,
|
|
63
|
+
0,
|
|
64
|
+
-1
|
|
65
|
+
]],
|
|
66
|
+
["UL", [
|
|
67
|
+
1,
|
|
68
|
+
1,
|
|
69
|
+
0,
|
|
70
|
+
1,
|
|
71
|
+
1,
|
|
72
|
+
0,
|
|
73
|
+
0,
|
|
74
|
+
0,
|
|
75
|
+
0,
|
|
76
|
+
0,
|
|
77
|
+
0,
|
|
78
|
+
-1,
|
|
79
|
+
0,
|
|
80
|
+
0,
|
|
81
|
+
0,
|
|
82
|
+
0,
|
|
83
|
+
0,
|
|
84
|
+
0
|
|
85
|
+
]],
|
|
86
|
+
["U", [
|
|
87
|
+
1,
|
|
88
|
+
1,
|
|
89
|
+
1,
|
|
90
|
+
1,
|
|
91
|
+
1,
|
|
92
|
+
1,
|
|
93
|
+
0,
|
|
94
|
+
0,
|
|
95
|
+
0,
|
|
96
|
+
-1,
|
|
97
|
+
0,
|
|
98
|
+
-1,
|
|
99
|
+
0,
|
|
100
|
+
0,
|
|
101
|
+
0,
|
|
102
|
+
0,
|
|
103
|
+
0,
|
|
104
|
+
0
|
|
105
|
+
]],
|
|
106
|
+
["R", [
|
|
107
|
+
0,
|
|
108
|
+
1,
|
|
109
|
+
1,
|
|
110
|
+
0,
|
|
111
|
+
1,
|
|
112
|
+
1,
|
|
113
|
+
0,
|
|
114
|
+
1,
|
|
115
|
+
1,
|
|
116
|
+
-1,
|
|
117
|
+
0,
|
|
118
|
+
0,
|
|
119
|
+
0,
|
|
120
|
+
0,
|
|
121
|
+
0,
|
|
122
|
+
-1,
|
|
123
|
+
0,
|
|
124
|
+
0
|
|
125
|
+
]],
|
|
126
|
+
["D", [
|
|
127
|
+
0,
|
|
128
|
+
0,
|
|
129
|
+
0,
|
|
130
|
+
1,
|
|
131
|
+
1,
|
|
132
|
+
1,
|
|
133
|
+
1,
|
|
134
|
+
1,
|
|
135
|
+
1,
|
|
136
|
+
0,
|
|
137
|
+
0,
|
|
138
|
+
0,
|
|
139
|
+
0,
|
|
140
|
+
0,
|
|
141
|
+
0,
|
|
142
|
+
-1,
|
|
143
|
+
0,
|
|
144
|
+
-1
|
|
145
|
+
]],
|
|
146
|
+
["L", [
|
|
147
|
+
1,
|
|
148
|
+
1,
|
|
149
|
+
0,
|
|
150
|
+
1,
|
|
151
|
+
1,
|
|
152
|
+
0,
|
|
153
|
+
1,
|
|
154
|
+
1,
|
|
155
|
+
0,
|
|
156
|
+
0,
|
|
157
|
+
0,
|
|
158
|
+
-1,
|
|
159
|
+
0,
|
|
160
|
+
0,
|
|
161
|
+
0,
|
|
162
|
+
0,
|
|
163
|
+
0,
|
|
164
|
+
-1
|
|
165
|
+
]],
|
|
166
|
+
["ALL", [
|
|
167
|
+
1,
|
|
168
|
+
1,
|
|
169
|
+
1,
|
|
170
|
+
1,
|
|
171
|
+
1,
|
|
172
|
+
1,
|
|
173
|
+
1,
|
|
174
|
+
1,
|
|
175
|
+
1,
|
|
176
|
+
-1,
|
|
177
|
+
0,
|
|
178
|
+
-1,
|
|
179
|
+
0,
|
|
180
|
+
0,
|
|
181
|
+
0,
|
|
182
|
+
-1,
|
|
183
|
+
0,
|
|
184
|
+
-1
|
|
185
|
+
]]
|
|
186
|
+
]);
|
|
187
|
+
const createClockState = (positions, rightSideUp) => {
|
|
188
|
+
if (positions.length !== 18) throw new RangeError(`clock state must contain 18 dial positions: ${positions.length}`);
|
|
189
|
+
return Object.freeze({
|
|
190
|
+
positions: Object.freeze([...positions]),
|
|
191
|
+
rightSideUp
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
const validateMove = (move) => {
|
|
195
|
+
if (typeof move !== "object" || move === null) throw new InvalidMoveError(MALFORMED_MOVE, "clock");
|
|
196
|
+
if (move.type === "rotation") return move;
|
|
197
|
+
if (move.type !== "turn" || !CLOCK_TURN_NAMES.includes(move.name) || move.direction !== "+" && move.direction !== "-" || !Number.isSafeInteger(move.amount) || move.amount < 0 || move.amount > 6 || move.direction === "-" && (move.amount === 0 || move.amount === 6)) throw new InvalidMoveError(MALFORMED_MOVE, "clock");
|
|
198
|
+
return move;
|
|
199
|
+
};
|
|
200
|
+
const moduloClock = (position) => (position % 12 + 12) % 12;
|
|
201
|
+
const createSolvedClockState = () => createClockState(Array(18).fill(0), true);
|
|
202
|
+
const applyClockMove = (state, move) => {
|
|
203
|
+
const validMove = validateMove(move);
|
|
204
|
+
if (validMove.type === "rotation") return createClockState([...state.positions.slice(9), ...state.positions.slice(0, 9)], !state.rightSideUp);
|
|
205
|
+
const deltas = CLOCK_MOVE_DELTAS.get(validMove.name);
|
|
206
|
+
if (deltas === void 0) throw new InvalidMoveError(MALFORMED_MOVE, "clock");
|
|
207
|
+
const signedAmount = validMove.direction === "+" ? validMove.amount : -validMove.amount;
|
|
208
|
+
return createClockState(state.positions.map((position, index) => moduloClock(position + signedAmount * (deltas[index] ?? 0))), state.rightSideUp);
|
|
209
|
+
};
|
|
210
|
+
const areClockStatesEqual = (a, b) => a.rightSideUp === b.rightSideUp && a.positions.every((position, index) => position === b.positions[index]);
|
|
211
|
+
//#endregion
|
|
212
|
+
export { applyClockMove, areClockStatesEqual, createSolvedClockState };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ClockMove } from "./clock-parser.mjs";
|
|
2
|
+
|
|
3
|
+
//#region .build/vendor/scramble-puzzle/src/clock/clock-state.d.ts
|
|
4
|
+
type ClockPositions = readonly number[];
|
|
5
|
+
interface ClockState {
|
|
6
|
+
readonly positions: ClockPositions;
|
|
7
|
+
readonly rightSideUp: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const createSolvedClockState: () => ClockState;
|
|
10
|
+
declare const applyClockMove: (state: ClockState, move: ClockMove) => ClockState;
|
|
11
|
+
declare const areClockStatesEqual: (a: ClockState, b: ClockState) => boolean;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { ClockPositions, ClockState, applyClockMove, areClockStatesEqual, createSolvedClockState };
|