@houstonp/rubiks-cube 2.1.0 → 3.0.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/README.md +304 -77
- package/package.json +18 -8
- package/src/{core.js → core/index.js} +72 -41
- package/src/rubiksCube/index.js +3 -0
- package/src/rubiksCube/rubiksCubeController.js +111 -0
- package/src/{three → rubiksCube3D}/centerPiece.js +37 -2
- package/src/{three → rubiksCube3D}/cornerPiece.js +56 -2
- package/src/rubiksCube3D/cubeConfig.js +87 -0
- package/src/rubiksCube3D/cubeSettings.js +30 -0
- package/src/{three → rubiksCube3D}/edgePiece.js +2 -1
- package/src/rubiksCube3D/index.js +3 -0
- package/src/rubiksCube3D/rubiksCube3D.js +383 -0
- package/src/{three → rubiksCube3D}/sticker.js +5 -4
- package/src/state/index.js +4 -0
- package/src/state/rubiksCubeState.js +471 -0
- package/src/state/slice.js +236 -0
- package/src/state/stickerState.js +185 -0
- package/src/{camera → webComponent}/cameraState.js +17 -25
- package/src/webComponent/constants.js +67 -0
- package/src/webComponent/index.js +7 -0
- package/src/webComponent/rubiksCubeElement.js +379 -0
- package/src/{settings.js → webComponent/settings.js} +36 -23
- package/tests/common.js +3 -20
- package/tests/core.test.js +56 -0
- package/tests/rubiksCube.solves.test.js +41 -0
- package/tests/rubiksCube3D.solves.test.js +185 -0
- package/tests/rubiksCubeState.solves.test.js +35 -0
- package/tests/testScrambles.js +194 -0
- package/types/{core.d.ts → core/index.d.ts} +45 -48
- package/types/rubiksCube/index.d.ts +3 -0
- package/types/rubiksCube/rubiksCubeController.d.ts +62 -0
- package/types/rubiksCube3D/centerPiece.d.ts +27 -0
- package/types/rubiksCube3D/cornerPiece.d.ts +38 -0
- package/types/rubiksCube3D/cubeConfig.d.ts +32 -0
- package/types/rubiksCube3D/cubeSettings.d.ts +33 -0
- package/types/{three → rubiksCube3D}/edgePiece.d.ts +5 -3
- package/types/rubiksCube3D/index.d.ts +3 -0
- package/types/rubiksCube3D/rubiksCube3D.d.ts +120 -0
- package/types/rubiksCube3D/sticker.d.ts +18 -0
- package/types/state/index.d.ts +5 -0
- package/types/state/rubiksCubeState.d.ts +108 -0
- package/types/state/slice.d.ts +46 -0
- package/types/state/stickerState.d.ts +34 -0
- package/types/webComponent/cameraState.d.ts +22 -0
- package/types/webComponent/constants.d.ts +57 -0
- package/types/webComponent/index.d.ts +6 -0
- package/types/webComponent/rubiksCubeElement.d.ts +89 -0
- package/types/{settings.d.ts → webComponent/settings.d.ts} +5 -8
- package/src/cube/animationSlice.js +0 -205
- package/src/cube/animationState.js +0 -96
- package/src/cube/cubeSettings.js +0 -19
- package/src/cube/cubeState.js +0 -337
- package/src/cube/stickerState.js +0 -188
- package/src/index.js +0 -621
- package/src/three/cube.js +0 -492
- package/tests/cube.five.test.js +0 -126
- package/tests/cube.four.test.js +0 -126
- package/tests/cube.seven.test.js +0 -126
- package/tests/cube.six.test.js +0 -126
- package/tests/cube.three.test.js +0 -151
- package/tests/cube.two.test.js +0 -125
- package/types/camera/cameraState.d.ts +0 -19
- package/types/cube/animationSlice.d.ts +0 -26
- package/types/cube/animationState.d.ts +0 -41
- package/types/cube/cubeSettings.d.ts +0 -17
- package/types/cube/cubeState.d.ts +0 -47
- package/types/cube/stickerState.d.ts +0 -21
- package/types/index.d.ts +0 -87
- package/types/three/centerPiece.d.ts +0 -15
- package/types/three/cornerPiece.d.ts +0 -24
- package/types/three/cube.d.ts +0 -130
- package/types/three/sticker.d.ts +0 -15
- /package/src/{debouncer.js → webComponent/debouncer.js} +0 -0
- /package/src/{globals.ts → webComponent/globals.ts} +0 -0
- /package/types/{debouncer.d.ts → webComponent/debouncer.d.ts} +0 -0
- /package/types/{globals.d.ts → webComponent/globals.d.ts} +0 -0
package/src/cube/cubeState.js
DELETED
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {{x: number,y: number,z: number}} vector
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { CubeTypes, Faces } from '../core';
|
|
7
|
-
import { defaultStickerState } from './stickerState';
|
|
8
|
-
|
|
9
|
-
/** @typedef {{cubeType: import('../core').CubeType, layers: number[], pieceSize: number, coreSize: number,initialStickerState: import('./stickerState').StickerState, outerLayerMultiplier: number, corners: state[], edges: state[], centers: state[]}} CubeInfo */
|
|
10
|
-
/**
|
|
11
|
-
* @param {import("../core").CubeType} cubeType
|
|
12
|
-
* @return {CubeInfo}
|
|
13
|
-
*/
|
|
14
|
-
export function getCubeInfo(cubeType) {
|
|
15
|
-
return {
|
|
16
|
-
cubeType: cubeType,
|
|
17
|
-
layers: getMiddleLayers(cubeType),
|
|
18
|
-
pieceSize: pieceSize(cubeType),
|
|
19
|
-
coreSize: coreSize(cubeType),
|
|
20
|
-
initialStickerState: defaultStickerState(cubeType),
|
|
21
|
-
outerLayerMultiplier: outlerLayerMultiplier(cubeType),
|
|
22
|
-
corners: corners,
|
|
23
|
-
edges: edges(getMiddleLayers(cubeType)),
|
|
24
|
-
centers: centers(getMiddleLayers(cubeType)),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const FaceColors = {
|
|
29
|
-
[Faces.B]: 'blue',
|
|
30
|
-
[Faces.D]: 'yellow',
|
|
31
|
-
[Faces.F]: '#2cbf13',
|
|
32
|
-
[Faces.L]: '#fc9a05',
|
|
33
|
-
[Faces.R]: 'red',
|
|
34
|
-
[Faces.U]: 'white',
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {import('three').ColorRepresentation} color
|
|
39
|
-
* @return {import('../core').Face}
|
|
40
|
-
* */
|
|
41
|
-
export const ColorToFace = (color) => {
|
|
42
|
-
const face = Object.values(Faces).find((face) => FaceColors[face] === color);
|
|
43
|
-
if (!face) {
|
|
44
|
-
throw new Error(`Invalid color: ${color}`);
|
|
45
|
-
}
|
|
46
|
-
return face;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @param {import("../core").CubeType} cubeType
|
|
51
|
-
* @return {number} core size
|
|
52
|
-
*/
|
|
53
|
-
export const outlerLayerMultiplier = (cubeType) => {
|
|
54
|
-
switch (cubeType) {
|
|
55
|
-
case CubeTypes.Two:
|
|
56
|
-
return 1;
|
|
57
|
-
case CubeTypes.Three:
|
|
58
|
-
return 1;
|
|
59
|
-
case CubeTypes.Four:
|
|
60
|
-
return 1.1;
|
|
61
|
-
case CubeTypes.Five:
|
|
62
|
-
return 1.2;
|
|
63
|
-
case CubeTypes.Six:
|
|
64
|
-
return 1.3;
|
|
65
|
-
case CubeTypes.Seven:
|
|
66
|
-
return 1.35;
|
|
67
|
-
default:
|
|
68
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @param {import("../core").CubeType} cubeType
|
|
74
|
-
* @return {number} core size
|
|
75
|
-
*/
|
|
76
|
-
export const coreSize = (cubeType) => {
|
|
77
|
-
switch (cubeType) {
|
|
78
|
-
case CubeTypes.Two:
|
|
79
|
-
return 2;
|
|
80
|
-
case CubeTypes.Three:
|
|
81
|
-
return 1.53;
|
|
82
|
-
case CubeTypes.Four:
|
|
83
|
-
return 1.36;
|
|
84
|
-
case CubeTypes.Five:
|
|
85
|
-
return 1.3;
|
|
86
|
-
case CubeTypes.Six:
|
|
87
|
-
return 1.22;
|
|
88
|
-
case CubeTypes.Seven:
|
|
89
|
-
return 1.21;
|
|
90
|
-
default:
|
|
91
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @param {import("../core").CubeType} cubeType
|
|
97
|
-
*/
|
|
98
|
-
export const getMiddleLayers = (cubeType) => {
|
|
99
|
-
switch (cubeType) {
|
|
100
|
-
case CubeTypes.Two:
|
|
101
|
-
return [];
|
|
102
|
-
case CubeTypes.Three:
|
|
103
|
-
return [0];
|
|
104
|
-
case CubeTypes.Four:
|
|
105
|
-
return [-1 / 3, 1 / 3];
|
|
106
|
-
case CubeTypes.Five:
|
|
107
|
-
return [-1 / 2, 0, 1 / 2];
|
|
108
|
-
case CubeTypes.Six:
|
|
109
|
-
return [-3 / 5, -1 / 5, 1 / 5, 3 / 5];
|
|
110
|
-
case CubeTypes.Seven:
|
|
111
|
-
return [-2 / 3, -1 / 3, 0, 1 / 3, 2 / 3];
|
|
112
|
-
default:
|
|
113
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @param {import("../core").CubeType} cubeType
|
|
119
|
-
*/
|
|
120
|
-
export const getAllLayers = (cubeType) => {
|
|
121
|
-
return [-1, ...getMiddleLayers(cubeType), 1];
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* @param {import("../core").CubeType} cubeType
|
|
126
|
-
* @return {number} piece size
|
|
127
|
-
*/
|
|
128
|
-
export const pieceSize = (cubeType) => {
|
|
129
|
-
switch (cubeType) {
|
|
130
|
-
case CubeTypes.Two:
|
|
131
|
-
return 2;
|
|
132
|
-
case CubeTypes.Three:
|
|
133
|
-
return 1;
|
|
134
|
-
case CubeTypes.Four:
|
|
135
|
-
return 2 / 3;
|
|
136
|
-
case CubeTypes.Five:
|
|
137
|
-
return 1 / 2;
|
|
138
|
-
case CubeTypes.Six:
|
|
139
|
-
return 2 / 5;
|
|
140
|
-
case CubeTypes.Seven:
|
|
141
|
-
return 1 / 3;
|
|
142
|
-
default:
|
|
143
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* @typedef {{position: vector, rotation: vector}} state
|
|
149
|
-
*/
|
|
150
|
-
|
|
151
|
-
/** @type {state[]} */
|
|
152
|
-
export const corners = [
|
|
153
|
-
{
|
|
154
|
-
position: { x: 1, y: 1, z: 1 },
|
|
155
|
-
rotation: { x: 0, y: 0, z: 0 },
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
position: { x: 1, y: 1, z: -1 },
|
|
159
|
-
rotation: { x: 0, y: Math.PI / 2, z: 0 },
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
position: { x: 1, y: -1, z: 1 },
|
|
163
|
-
rotation: { x: 0, y: Math.PI / 2, z: Math.PI },
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
position: { x: 1, y: -1, z: -1 },
|
|
167
|
-
rotation: { x: 0, y: Math.PI, z: Math.PI },
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
position: { x: -1, y: 1, z: 1 },
|
|
171
|
-
rotation: { x: 0, y: -Math.PI / 2, z: 0 },
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
position: { x: -1, y: 1, z: -1 },
|
|
175
|
-
rotation: { x: 0, y: Math.PI, z: 0 },
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
position: { x: -1, y: -1, z: 1 },
|
|
179
|
-
rotation: { x: 0, y: 0, z: Math.PI },
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
position: { x: -1, y: -1, z: -1 },
|
|
183
|
-
rotation: { x: 0, y: -Math.PI / 2, z: Math.PI },
|
|
184
|
-
},
|
|
185
|
-
];
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* @param {number[]} layers
|
|
189
|
-
* @return {state[]}
|
|
190
|
-
*/
|
|
191
|
-
export const centers = (layers) => [
|
|
192
|
-
//right
|
|
193
|
-
...layers.flatMap((layer1) =>
|
|
194
|
-
layers.map((layer2) => {
|
|
195
|
-
return {
|
|
196
|
-
position: { x: 1, y: layer1, z: layer2 },
|
|
197
|
-
rotation: { x: 0, y: Math.PI / 2, z: 0 },
|
|
198
|
-
};
|
|
199
|
-
}),
|
|
200
|
-
),
|
|
201
|
-
//up
|
|
202
|
-
...layers.flatMap((layer1) =>
|
|
203
|
-
layers.map((layer2) => {
|
|
204
|
-
return {
|
|
205
|
-
position: { x: layer1, y: 1, z: layer2 },
|
|
206
|
-
rotation: { x: -Math.PI / 2, y: 0, z: 0 },
|
|
207
|
-
};
|
|
208
|
-
}),
|
|
209
|
-
),
|
|
210
|
-
//front
|
|
211
|
-
...layers.flatMap((layer1) =>
|
|
212
|
-
layers.map((layer2) => {
|
|
213
|
-
return {
|
|
214
|
-
position: { x: layer1, y: layer2, z: 1 },
|
|
215
|
-
rotation: { x: 0, y: 0, z: 0 },
|
|
216
|
-
};
|
|
217
|
-
}),
|
|
218
|
-
),
|
|
219
|
-
//back
|
|
220
|
-
...layers.flatMap((layer1) =>
|
|
221
|
-
layers.map((layer2) => {
|
|
222
|
-
return {
|
|
223
|
-
position: { x: layer1, y: layer2, z: -1 },
|
|
224
|
-
rotation: { x: 0, y: Math.PI, z: 0 },
|
|
225
|
-
};
|
|
226
|
-
}),
|
|
227
|
-
),
|
|
228
|
-
//down
|
|
229
|
-
...layers.flatMap((layer1) =>
|
|
230
|
-
layers.map((layer2) => {
|
|
231
|
-
return {
|
|
232
|
-
position: { x: layer1, y: -1, z: layer2 },
|
|
233
|
-
rotation: { x: Math.PI / 2, y: 0, z: 0 },
|
|
234
|
-
};
|
|
235
|
-
}),
|
|
236
|
-
),
|
|
237
|
-
//left
|
|
238
|
-
...layers.flatMap((layer1) =>
|
|
239
|
-
layers.map((layer2) => {
|
|
240
|
-
return {
|
|
241
|
-
position: { x: -1, y: layer1, z: layer2 },
|
|
242
|
-
rotation: { x: 0, y: -Math.PI / 2, z: 0 },
|
|
243
|
-
};
|
|
244
|
-
}),
|
|
245
|
-
),
|
|
246
|
-
];
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* @param {number[]} layers
|
|
250
|
-
* @return {state[]}
|
|
251
|
-
*/
|
|
252
|
-
export const edges = (layers) => [
|
|
253
|
-
// RU
|
|
254
|
-
...layers.map((layer) => {
|
|
255
|
-
return {
|
|
256
|
-
position: { x: 1, y: 1, z: layer },
|
|
257
|
-
rotation: { x: 0, y: Math.PI / 2, z: 0 },
|
|
258
|
-
};
|
|
259
|
-
}),
|
|
260
|
-
// RF
|
|
261
|
-
...layers.map((layer) => {
|
|
262
|
-
return {
|
|
263
|
-
position: { x: 1, y: layer, z: 1 },
|
|
264
|
-
rotation: { x: 0, y: 0, z: -Math.PI / 2 },
|
|
265
|
-
};
|
|
266
|
-
}),
|
|
267
|
-
// RB
|
|
268
|
-
...layers.map((layer) => {
|
|
269
|
-
return {
|
|
270
|
-
position: { x: 1, y: layer, z: -1 },
|
|
271
|
-
rotation: { x: 0, y: Math.PI / 2, z: -Math.PI / 2 },
|
|
272
|
-
};
|
|
273
|
-
}),
|
|
274
|
-
// RD
|
|
275
|
-
...layers.map((layer) => {
|
|
276
|
-
return {
|
|
277
|
-
position: { x: 1, y: -1, z: layer },
|
|
278
|
-
rotation: { x: Math.PI, y: Math.PI / 2, z: 0 },
|
|
279
|
-
};
|
|
280
|
-
}),
|
|
281
|
-
// UF
|
|
282
|
-
...layers.map((layer) => {
|
|
283
|
-
return {
|
|
284
|
-
position: { x: layer, y: 1, z: 1 },
|
|
285
|
-
rotation: { x: 0, y: 0, z: 0 },
|
|
286
|
-
};
|
|
287
|
-
}),
|
|
288
|
-
// UB
|
|
289
|
-
...layers.map((layer) => {
|
|
290
|
-
return {
|
|
291
|
-
position: { x: layer, y: 1, z: -1 },
|
|
292
|
-
rotation: { x: -Math.PI / 2, y: 0, z: 0 },
|
|
293
|
-
};
|
|
294
|
-
}),
|
|
295
|
-
// DF
|
|
296
|
-
...layers.map((layer) => {
|
|
297
|
-
return {
|
|
298
|
-
position: { x: layer, y: -1, z: 1 },
|
|
299
|
-
rotation: { x: Math.PI / 2, y: 0, z: 0 },
|
|
300
|
-
};
|
|
301
|
-
}),
|
|
302
|
-
// DB
|
|
303
|
-
...layers.map((layer) => {
|
|
304
|
-
return {
|
|
305
|
-
position: { x: layer, y: -1, z: -1 },
|
|
306
|
-
rotation: { x: Math.PI, y: 0, z: 0 },
|
|
307
|
-
};
|
|
308
|
-
}),
|
|
309
|
-
// LU
|
|
310
|
-
...layers.map((layer) => {
|
|
311
|
-
return {
|
|
312
|
-
position: { x: -1, y: 1, z: layer },
|
|
313
|
-
rotation: { x: 0, y: -Math.PI / 2, z: 0 },
|
|
314
|
-
};
|
|
315
|
-
}),
|
|
316
|
-
// LF
|
|
317
|
-
...layers.map((layer) => {
|
|
318
|
-
return {
|
|
319
|
-
position: { x: -1, y: layer, z: 1 },
|
|
320
|
-
rotation: { x: 0, y: 0, z: Math.PI / 2 },
|
|
321
|
-
};
|
|
322
|
-
}),
|
|
323
|
-
// LB
|
|
324
|
-
...layers.map((layer) => {
|
|
325
|
-
return {
|
|
326
|
-
position: { x: -1, y: layer, z: -1 },
|
|
327
|
-
rotation: { x: 0, y: -Math.PI / 2, z: Math.PI / 2 },
|
|
328
|
-
};
|
|
329
|
-
}),
|
|
330
|
-
// LD
|
|
331
|
-
...layers.map((layer) => {
|
|
332
|
-
return {
|
|
333
|
-
position: { x: -1, y: -1, z: layer },
|
|
334
|
-
rotation: { x: 0, y: -Math.PI / 2, z: Math.PI },
|
|
335
|
-
};
|
|
336
|
-
}),
|
|
337
|
-
];
|
package/src/cube/stickerState.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/** @typedef {{ up: import('../core').Face[][], down: import('../core').Face[][], front: import('../core').Face[][], back: import('../core').Face[][], left: import('../core').Face[][], right: import('../core').Face[][] }} StickerState*/
|
|
3
|
-
|
|
4
|
-
import { CubeTypes, Faces } from '../core';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @param {import('../core').CubeType} cubeType
|
|
9
|
-
* @return {StickerState}
|
|
10
|
-
*/
|
|
11
|
-
export const defaultStickerState = (cubeType) => {
|
|
12
|
-
const length = 0;
|
|
13
|
-
switch (cubeType) {
|
|
14
|
-
case CubeTypes.Two:
|
|
15
|
-
return initialStickerState(2);
|
|
16
|
-
case CubeTypes.Three:
|
|
17
|
-
return initialStickerState(3);
|
|
18
|
-
case CubeTypes.Four:
|
|
19
|
-
return initialStickerState(4);
|
|
20
|
-
case CubeTypes.Five:
|
|
21
|
-
return initialStickerState(5);
|
|
22
|
-
case CubeTypes.Six:
|
|
23
|
-
return initialStickerState(6);
|
|
24
|
-
case CubeTypes.Seven:
|
|
25
|
-
return initialStickerState(7);
|
|
26
|
-
default:
|
|
27
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
* @param {number} layerCount
|
|
34
|
-
* @returns {StickerState}
|
|
35
|
-
*/
|
|
36
|
-
const initialStickerState = (layerCount) => {
|
|
37
|
-
const state = {
|
|
38
|
-
right: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.R)),
|
|
39
|
-
up: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.U)),
|
|
40
|
-
front: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.F)),
|
|
41
|
-
back: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.B)),
|
|
42
|
-
down: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.D)),
|
|
43
|
-
left: Array.from({ length: layerCount }, () => Array.from({ length: layerCount }, () => Faces.L)),
|
|
44
|
-
};
|
|
45
|
-
return state;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* @param {import('../core').CubeType} cubeType
|
|
51
|
-
* @return {StickerState}
|
|
52
|
-
*/
|
|
53
|
-
export const getEmptyStickerState = (cubeType) => {
|
|
54
|
-
const length = 0;
|
|
55
|
-
switch (cubeType) {
|
|
56
|
-
case CubeTypes.Two:
|
|
57
|
-
return emptyStickerState(2);
|
|
58
|
-
case CubeTypes.Three:
|
|
59
|
-
return emptyStickerState(3);
|
|
60
|
-
case CubeTypes.Four:
|
|
61
|
-
return emptyStickerState(4);
|
|
62
|
-
case CubeTypes.Five:
|
|
63
|
-
return emptyStickerState(5);
|
|
64
|
-
case CubeTypes.Six:
|
|
65
|
-
return emptyStickerState(6);
|
|
66
|
-
case CubeTypes.Seven:
|
|
67
|
-
return emptyStickerState(7);
|
|
68
|
-
default:
|
|
69
|
-
throw new Error(`Unsupported cube type: ${cubeType}`);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* @param {number} layerCount
|
|
75
|
-
* @returns {StickerState}
|
|
76
|
-
*/
|
|
77
|
-
const emptyStickerState = (layerCount) => {
|
|
78
|
-
const state = {
|
|
79
|
-
right: Array.from({ length: layerCount }, () => []),
|
|
80
|
-
up: Array.from({ length: layerCount }, () => []),
|
|
81
|
-
front: Array.from({ length: layerCount }, () => []),
|
|
82
|
-
back: Array.from({ length: layerCount }, () => []),
|
|
83
|
-
down: Array.from({ length: layerCount }, () => []),
|
|
84
|
-
left: Array.from({ length: layerCount }, () => []),
|
|
85
|
-
};
|
|
86
|
-
return state;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @param {StickerState} stickerState
|
|
91
|
-
* @returns {string}
|
|
92
|
-
*/
|
|
93
|
-
export function toKociemba(stickerState) {
|
|
94
|
-
return `${stickerState.up.flat().join('')}${stickerState.right.flat().join('')}${stickerState.front.flat().join('')}${stickerState.down.flat().join('')}${stickerState.left.flat().join('')}${stickerState.back.flat().join('')}`;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @param {string} kociembaString
|
|
99
|
-
* @param {import('../core').CubeType} cubeType
|
|
100
|
-
* @returns {StickerState | undefined} stickerState
|
|
101
|
-
*/
|
|
102
|
-
export function fromKociemba(kociembaString, cubeType) {
|
|
103
|
-
const length = kociembaString.length;
|
|
104
|
-
switch (cubeType) {
|
|
105
|
-
case CubeTypes.Two:
|
|
106
|
-
if (length != 6 * 2 ** 2) {
|
|
107
|
-
console.error('Invalid state string length. Length must be 24 for 2x2 cubes.');
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
return fromKociembaWithLayerCount(kociembaString, 2);
|
|
111
|
-
case CubeTypes.Three:
|
|
112
|
-
if (length != 6 * 3 ** 2) {
|
|
113
|
-
console.error('Invalid state string length. Length must be 54 for 3x3 cubes.');
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
return fromKociembaWithLayerCount(kociembaString, 3);
|
|
117
|
-
case CubeTypes.Four:
|
|
118
|
-
if (length != 6 * 4 ** 2) {
|
|
119
|
-
console.error('Invalid state string length. Length must be 96 for 4x4 cubes.');
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
return fromKociembaWithLayerCount(kociembaString, 4);
|
|
123
|
-
case CubeTypes.Five:
|
|
124
|
-
if (length != 6 * 5 ** 2) {
|
|
125
|
-
console.error('Invalid state string length. Length must be 150 for 5x5 cubes.');
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
return fromKociembaWithLayerCount(kociembaString, 5);
|
|
129
|
-
case CubeTypes.Six:
|
|
130
|
-
if (length != 6 * 6 ** 2) {
|
|
131
|
-
console.error('Invalid state string length. Length must be 216 for 6x6 cubes.');
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
return fromKociembaWithLayerCount(kociembaString, 6);
|
|
135
|
-
case CubeTypes.Seven:
|
|
136
|
-
if (length != 6 * 7 ** 2) {
|
|
137
|
-
console.error('Invalid state string length. Length must be 294 for 7x7 cubes.');
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
return fromKociembaWithLayerCount(kociembaString, 7);
|
|
141
|
-
default:
|
|
142
|
-
undefined;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* @param {string} kociembaString
|
|
148
|
-
* @param {number} layerCount
|
|
149
|
-
* @returns {StickerState | undefined } stickerState
|
|
150
|
-
*/
|
|
151
|
-
function fromKociembaWithLayerCount(kociembaString, layerCount) {
|
|
152
|
-
let stickerState = emptyStickerState(layerCount);
|
|
153
|
-
for (let i = 0; i < 6; i++) {
|
|
154
|
-
const faceString = kociembaString.slice(i * layerCount ** 2, (i + 1) * layerCount ** 2);
|
|
155
|
-
for (let j = 0; j < layerCount; j++) {
|
|
156
|
-
const rowString = faceString.slice(j * layerCount, (j + 1) * layerCount);
|
|
157
|
-
for (let k = 0; k < layerCount; k++) {
|
|
158
|
-
const face = Object.values(Faces).find((face) => rowString[k] === face);
|
|
159
|
-
if (!face) {
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
switch (i) {
|
|
163
|
-
case 0:
|
|
164
|
-
stickerState.up[j][k] = face;
|
|
165
|
-
break;
|
|
166
|
-
case 1:
|
|
167
|
-
stickerState.right[j][k] = face;
|
|
168
|
-
break;
|
|
169
|
-
case 2:
|
|
170
|
-
stickerState.front[j][k] = face;
|
|
171
|
-
break;
|
|
172
|
-
case 3:
|
|
173
|
-
stickerState.down[j][k] = face;
|
|
174
|
-
break;
|
|
175
|
-
case 4:
|
|
176
|
-
stickerState.left[j][k] = face;
|
|
177
|
-
break;
|
|
178
|
-
case 5:
|
|
179
|
-
stickerState.back[j][k] = face;
|
|
180
|
-
break;
|
|
181
|
-
default:
|
|
182
|
-
throw new Error(`Invalid value for i - [${i}]. i should be between [0,5] inclusive.`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return stickerState;
|
|
188
|
-
}
|