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,214 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-core/src/solvers/sq12phase/shape.ts
|
|
2
|
+
const N_SHAPES = 3678;
|
|
3
|
+
const N_SHAPE_STATES = N_SHAPES * 2;
|
|
4
|
+
const FACE_TURN_METRIC = 0;
|
|
5
|
+
const WCA_TURN_METRIC = 1;
|
|
6
|
+
const SEARCH_METRIC = WCA_TURN_METRIC;
|
|
7
|
+
const HALF_LAYER = [
|
|
8
|
+
0,
|
|
9
|
+
3,
|
|
10
|
+
6,
|
|
11
|
+
12,
|
|
12
|
+
15,
|
|
13
|
+
24,
|
|
14
|
+
27,
|
|
15
|
+
30,
|
|
16
|
+
48,
|
|
17
|
+
51,
|
|
18
|
+
54,
|
|
19
|
+
60,
|
|
20
|
+
63
|
|
21
|
+
];
|
|
22
|
+
const SOLVED_SHAPE_WITH_PARITY = 7191990;
|
|
23
|
+
let cachedTables;
|
|
24
|
+
var ShapeCoordinate = class {
|
|
25
|
+
top = 0;
|
|
26
|
+
bottom = 0;
|
|
27
|
+
parity = 0;
|
|
28
|
+
constructor(shapeIdx) {
|
|
29
|
+
this.shapeIdx = shapeIdx;
|
|
30
|
+
}
|
|
31
|
+
getIdx() {
|
|
32
|
+
return getShape2IdxFrom(this.shapeIdx, this.parity << 24 | this.top << 12 | this.bottom);
|
|
33
|
+
}
|
|
34
|
+
setIdx(index) {
|
|
35
|
+
this.parity = index & 1;
|
|
36
|
+
this.top = this.shapeIdx[index >> 1];
|
|
37
|
+
this.bottom = this.top & 4095;
|
|
38
|
+
this.top >>= 12;
|
|
39
|
+
}
|
|
40
|
+
topMove() {
|
|
41
|
+
let move = 0;
|
|
42
|
+
let moveParity = 0;
|
|
43
|
+
do {
|
|
44
|
+
if ((this.top & 2048) === 0) {
|
|
45
|
+
move += 1;
|
|
46
|
+
this.top <<= 1;
|
|
47
|
+
} else {
|
|
48
|
+
move += 2;
|
|
49
|
+
this.top = this.top << 2 ^ 12291;
|
|
50
|
+
}
|
|
51
|
+
moveParity = 1 - moveParity;
|
|
52
|
+
} while ((popCount(this.top & 63) & 1) !== 0);
|
|
53
|
+
if ((popCount(this.top) & 2) === 0) this.parity ^= moveParity;
|
|
54
|
+
return move;
|
|
55
|
+
}
|
|
56
|
+
bottomMove() {
|
|
57
|
+
let move = 0;
|
|
58
|
+
let moveParity = 0;
|
|
59
|
+
do {
|
|
60
|
+
if ((this.bottom & 2048) === 0) {
|
|
61
|
+
move += 1;
|
|
62
|
+
this.bottom <<= 1;
|
|
63
|
+
} else {
|
|
64
|
+
move += 2;
|
|
65
|
+
this.bottom = this.bottom << 2 ^ 12291;
|
|
66
|
+
}
|
|
67
|
+
moveParity = 1 - moveParity;
|
|
68
|
+
} while ((popCount(this.bottom & 63) & 1) !== 0);
|
|
69
|
+
if ((popCount(this.bottom) & 2) === 0) this.parity ^= moveParity;
|
|
70
|
+
return move;
|
|
71
|
+
}
|
|
72
|
+
twistMove() {
|
|
73
|
+
const topSlice = this.top & 63;
|
|
74
|
+
const topSliceCorners = popCount(topSlice);
|
|
75
|
+
const bottomSliceCorners = popCount(this.bottom & 4032);
|
|
76
|
+
this.parity ^= 1 & (topSliceCorners & bottomSliceCorners) >> 1;
|
|
77
|
+
this.top = this.top & 4032 | this.bottom >> 6 & 63;
|
|
78
|
+
this.bottom = this.bottom & 63 | topSlice << 6;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const getShape2Idx = (shapeWithParity) => getShape2IdxFrom(getShapeTables().shapeIdx, shapeWithParity);
|
|
82
|
+
const getShapeTables = () => {
|
|
83
|
+
cachedTables ??= createShapeTables();
|
|
84
|
+
return cachedTables;
|
|
85
|
+
};
|
|
86
|
+
const createShapeTables = () => {
|
|
87
|
+
const shapeIdx = createShapeIndex();
|
|
88
|
+
const topMove = new Int32Array(N_SHAPE_STATES);
|
|
89
|
+
const bottomMove = new Int32Array(N_SHAPE_STATES);
|
|
90
|
+
const twistMove = new Int32Array(N_SHAPE_STATES);
|
|
91
|
+
const shape = new ShapeCoordinate(shapeIdx);
|
|
92
|
+
for (let index = 0; index < N_SHAPE_STATES; index += 1) {
|
|
93
|
+
shape.setIdx(index);
|
|
94
|
+
topMove[index] = shape.topMove() | shape.getIdx() << 4;
|
|
95
|
+
shape.setIdx(index);
|
|
96
|
+
bottomMove[index] = shape.bottomMove() | shape.getIdx() << 4;
|
|
97
|
+
shape.setIdx(index);
|
|
98
|
+
shape.twistMove();
|
|
99
|
+
twistMove[index] = shape.getIdx();
|
|
100
|
+
}
|
|
101
|
+
const shapePrun = new Int8Array(N_SHAPE_STATES);
|
|
102
|
+
const shapePrunOpt = new Int8Array(N_SHAPE_STATES);
|
|
103
|
+
shapePrun.fill(-1);
|
|
104
|
+
shapePrunOpt.fill(-1);
|
|
105
|
+
shapePrun[getShape2IdxFrom(shapeIdx, 14378715)] = 0;
|
|
106
|
+
shapePrun[getShape2IdxFrom(shapeIdx, 31157686)] = 0;
|
|
107
|
+
shapePrun[getShape2IdxFrom(shapeIdx, 23967451)] = 0;
|
|
108
|
+
shapePrun[getShape2IdxFrom(shapeIdx, 7191990)] = 0;
|
|
109
|
+
shapePrunOpt[getShape2IdxFrom(shapeIdx, SOLVED_SHAPE_WITH_PARITY)] = 0;
|
|
110
|
+
const tables = {
|
|
111
|
+
shapeIdx,
|
|
112
|
+
shapePrun,
|
|
113
|
+
shapePrunOpt,
|
|
114
|
+
topMove,
|
|
115
|
+
bottomMove,
|
|
116
|
+
twistMove
|
|
117
|
+
};
|
|
118
|
+
initPruning(tables, shapePrun, 4, FACE_TURN_METRIC);
|
|
119
|
+
initPruning(tables, shapePrunOpt, 1, SEARCH_METRIC);
|
|
120
|
+
return tables;
|
|
121
|
+
};
|
|
122
|
+
const createShapeIndex = () => {
|
|
123
|
+
const shapeIdx = new Int32Array(N_SHAPES);
|
|
124
|
+
let count = 0;
|
|
125
|
+
for (let index = 0; index < 2197 * 13; index += 1) {
|
|
126
|
+
const dr = HALF_LAYER[index % 13];
|
|
127
|
+
const dl = HALF_LAYER[Math.floor(index / 13) % 13];
|
|
128
|
+
const ur = HALF_LAYER[Math.floor(index / 13 / 13) % 13];
|
|
129
|
+
const value = HALF_LAYER[Math.floor(index / 13 / 13 / 13)] << 18 | ur << 12 | dl << 6 | dr;
|
|
130
|
+
if (popCount(value) === 16) {
|
|
131
|
+
shapeIdx[count] = value;
|
|
132
|
+
count += 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return shapeIdx;
|
|
136
|
+
};
|
|
137
|
+
const initPruning = (tables, pruning, doneStart, metric) => {
|
|
138
|
+
let done = doneStart;
|
|
139
|
+
let previousDone = 0;
|
|
140
|
+
let depth = -1;
|
|
141
|
+
while (done !== previousDone) {
|
|
142
|
+
previousDone = done;
|
|
143
|
+
depth += 1;
|
|
144
|
+
for (let index = 0; index < N_SHAPE_STATES; index += 1) {
|
|
145
|
+
if (pruning[index] !== depth) continue;
|
|
146
|
+
const twisted = tables.twistMove[index];
|
|
147
|
+
if (pruning[twisted] === -1) {
|
|
148
|
+
done += 1;
|
|
149
|
+
pruning[twisted] = depth + 1;
|
|
150
|
+
}
|
|
151
|
+
if (metric === FACE_TURN_METRIC) {
|
|
152
|
+
for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
|
|
153
|
+
const moved = tables.topMove[next];
|
|
154
|
+
increment = moved & 15;
|
|
155
|
+
next = moved >> 4;
|
|
156
|
+
if (pruning[next] === -1) {
|
|
157
|
+
done += 1;
|
|
158
|
+
pruning[next] = depth + 1;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
|
|
162
|
+
const moved = tables.bottomMove[next];
|
|
163
|
+
increment = moved & 15;
|
|
164
|
+
next = moved >> 4;
|
|
165
|
+
if (pruning[next] === -1) {
|
|
166
|
+
done += 1;
|
|
167
|
+
pruning[next] = depth + 1;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
} else if (metric === WCA_TURN_METRIC) for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
|
|
171
|
+
const movedTop = tables.topMove[next];
|
|
172
|
+
increment = movedTop & 15;
|
|
173
|
+
next = movedTop >> 4;
|
|
174
|
+
for (let bottomMove = 0, bottomIncrement = 0, bottomNext = next; bottomMove !== 12; bottomMove += bottomIncrement) {
|
|
175
|
+
const movedBottom = tables.bottomMove[bottomNext];
|
|
176
|
+
bottomIncrement = movedBottom & 15;
|
|
177
|
+
bottomNext = movedBottom >> 4;
|
|
178
|
+
if (pruning[bottomNext] === -1) {
|
|
179
|
+
done += 1;
|
|
180
|
+
pruning[bottomNext] = depth + 1;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const getShape2IdxFrom = (shapeIdx, shapeWithParity) => {
|
|
188
|
+
const index = binarySearch(shapeIdx, shapeWithParity & 16777215);
|
|
189
|
+
if (index < 0) throw new RangeError("@cubegin/scramble-core: invalid Square-1 shape coordinate");
|
|
190
|
+
return index << 1 | shapeWithParity >> 24 & 1;
|
|
191
|
+
};
|
|
192
|
+
const binarySearch = (values, target) => {
|
|
193
|
+
let low = 0;
|
|
194
|
+
let high = values.length - 1;
|
|
195
|
+
while (low <= high) {
|
|
196
|
+
const middle = low + high >> 1;
|
|
197
|
+
const value = values[middle];
|
|
198
|
+
if (value < target) low = middle + 1;
|
|
199
|
+
else if (value > target) high = middle - 1;
|
|
200
|
+
else return middle;
|
|
201
|
+
}
|
|
202
|
+
return -1;
|
|
203
|
+
};
|
|
204
|
+
const popCount = (value) => {
|
|
205
|
+
let remaining = value >>> 0;
|
|
206
|
+
let count = 0;
|
|
207
|
+
while (remaining !== 0) {
|
|
208
|
+
remaining &= remaining - 1;
|
|
209
|
+
count += 1;
|
|
210
|
+
}
|
|
211
|
+
return count;
|
|
212
|
+
};
|
|
213
|
+
//#endregion
|
|
214
|
+
export { getShape2Idx, getShapeTables, popCount };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
//#region .build/vendor/scramble-core/src/solvers/sq12phase/square.ts
|
|
2
|
+
const N_PERMUTATIONS = 40320;
|
|
3
|
+
const N_MIDDLE_LAYER_STATES = N_PERMUTATIONS * 2;
|
|
4
|
+
const FACTORIAL = [
|
|
5
|
+
1,
|
|
6
|
+
1,
|
|
7
|
+
2,
|
|
8
|
+
6,
|
|
9
|
+
24,
|
|
10
|
+
120,
|
|
11
|
+
720,
|
|
12
|
+
5040
|
|
13
|
+
];
|
|
14
|
+
let cachedTables;
|
|
15
|
+
const createSquareCoordinate = () => ({
|
|
16
|
+
edgePerm: 0,
|
|
17
|
+
cornPerm: 0,
|
|
18
|
+
topEdgeFirst: false,
|
|
19
|
+
botEdgeFirst: false,
|
|
20
|
+
ml: 0
|
|
21
|
+
});
|
|
22
|
+
const set8Perm = (pieces, permutation) => {
|
|
23
|
+
let remaining = permutation;
|
|
24
|
+
let value = 1985229328;
|
|
25
|
+
for (let index = 0; index < 7; index += 1) {
|
|
26
|
+
const factorial = FACTORIAL[7 - index];
|
|
27
|
+
let piece = Math.floor(remaining / factorial);
|
|
28
|
+
remaining -= piece * factorial;
|
|
29
|
+
piece <<= 2;
|
|
30
|
+
pieces[index] = value >> piece & 7;
|
|
31
|
+
const mask = (1 << piece) - 1;
|
|
32
|
+
value = (value & mask) + (value >> 4 & ~mask);
|
|
33
|
+
}
|
|
34
|
+
pieces[7] = value;
|
|
35
|
+
};
|
|
36
|
+
const get8Perm = (pieces) => {
|
|
37
|
+
let permutation = 0;
|
|
38
|
+
let value = 1985229328;
|
|
39
|
+
for (let index = 0; index < 7; index += 1) {
|
|
40
|
+
const piece = pieces[index] << 2;
|
|
41
|
+
permutation = (8 - index) * permutation + (value >> piece & 7);
|
|
42
|
+
value -= 286331152 << piece;
|
|
43
|
+
}
|
|
44
|
+
return permutation;
|
|
45
|
+
};
|
|
46
|
+
const createMoveTables = () => {
|
|
47
|
+
const twistMove = new Uint16Array(N_PERMUTATIONS);
|
|
48
|
+
const topMove = new Uint16Array(N_PERMUTATIONS);
|
|
49
|
+
const bottomMove = new Uint16Array(N_PERMUTATIONS);
|
|
50
|
+
const pieces = Array.from({ length: 8 }, () => 0);
|
|
51
|
+
for (let permutation = 0; permutation < N_PERMUTATIONS; permutation += 1) {
|
|
52
|
+
set8Perm(pieces, permutation);
|
|
53
|
+
swap(pieces, 2, 4);
|
|
54
|
+
swap(pieces, 3, 5);
|
|
55
|
+
twistMove[permutation] = get8Perm(pieces);
|
|
56
|
+
set8Perm(pieces, permutation);
|
|
57
|
+
const topPiece = pieces[0];
|
|
58
|
+
pieces[0] = pieces[1];
|
|
59
|
+
pieces[1] = pieces[2];
|
|
60
|
+
pieces[2] = pieces[3];
|
|
61
|
+
pieces[3] = topPiece;
|
|
62
|
+
topMove[permutation] = get8Perm(pieces);
|
|
63
|
+
set8Perm(pieces, permutation);
|
|
64
|
+
const bottomPiece = pieces[4];
|
|
65
|
+
pieces[4] = pieces[5];
|
|
66
|
+
pieces[5] = pieces[6];
|
|
67
|
+
pieces[6] = pieces[7];
|
|
68
|
+
pieces[7] = bottomPiece;
|
|
69
|
+
bottomMove[permutation] = get8Perm(pieces);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
twistMove,
|
|
73
|
+
topMove,
|
|
74
|
+
bottomMove
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
const createPruningTable = ({ twistMove, topMove, bottomMove }) => {
|
|
78
|
+
const squarePrun = new Int8Array(N_MIDDLE_LAYER_STATES);
|
|
79
|
+
squarePrun.fill(-1);
|
|
80
|
+
squarePrun[0] = 0;
|
|
81
|
+
let depth = 0;
|
|
82
|
+
let done = 1;
|
|
83
|
+
while (done < N_MIDDLE_LAYER_STATES) {
|
|
84
|
+
const inverseFill = depth >= 11;
|
|
85
|
+
const findValue = inverseFill ? -1 : depth;
|
|
86
|
+
const checkValue = inverseFill ? depth : -1;
|
|
87
|
+
depth += 1;
|
|
88
|
+
for (let index = 0; index < N_MIDDLE_LAYER_STATES; index += 1) {
|
|
89
|
+
if (squarePrun[index] !== findValue) continue;
|
|
90
|
+
const ml = index & 1;
|
|
91
|
+
let permutation = index >> 1;
|
|
92
|
+
const twisted = twistMove[permutation] << 1 | 1 - ml;
|
|
93
|
+
if (squarePrun[twisted] === checkValue) {
|
|
94
|
+
done += 1;
|
|
95
|
+
squarePrun[inverseFill ? index : twisted] = depth;
|
|
96
|
+
if (inverseFill) continue;
|
|
97
|
+
}
|
|
98
|
+
for (let move = 0; move < 4; move += 1) {
|
|
99
|
+
permutation = topMove[permutation];
|
|
100
|
+
const moved = permutation << 1 | ml;
|
|
101
|
+
if (squarePrun[moved] !== checkValue) continue;
|
|
102
|
+
done += 1;
|
|
103
|
+
squarePrun[inverseFill ? index : moved] = depth;
|
|
104
|
+
if (inverseFill) break;
|
|
105
|
+
}
|
|
106
|
+
if (inverseFill && squarePrun[index] !== findValue) continue;
|
|
107
|
+
for (let move = 0; move < 4; move += 1) {
|
|
108
|
+
permutation = bottomMove[permutation];
|
|
109
|
+
const moved = permutation << 1 | ml;
|
|
110
|
+
if (squarePrun[moved] !== checkValue) continue;
|
|
111
|
+
done += 1;
|
|
112
|
+
squarePrun[inverseFill ? index : moved] = depth;
|
|
113
|
+
if (inverseFill) break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return squarePrun;
|
|
118
|
+
};
|
|
119
|
+
const getSquareTables = () => {
|
|
120
|
+
cachedTables ??= (() => {
|
|
121
|
+
const moveTables = createMoveTables();
|
|
122
|
+
return {
|
|
123
|
+
...moveTables,
|
|
124
|
+
squarePrun: createPruningTable(moveTables)
|
|
125
|
+
};
|
|
126
|
+
})();
|
|
127
|
+
return cachedTables;
|
|
128
|
+
};
|
|
129
|
+
const swap = (pieces, first, second) => {
|
|
130
|
+
const piece = pieces[first];
|
|
131
|
+
pieces[first] = pieces[second];
|
|
132
|
+
pieces[second] = piece;
|
|
133
|
+
};
|
|
134
|
+
//#endregion
|
|
135
|
+
export { createSquareCoordinate, get8Perm, getSquareTables };
|