cube-state-engine 1.3.0 → 1.4.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.
@@ -0,0 +1,304 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="c7204f89-75f2-42e0-aed9-81b858994b5a" name="Changes" comment="refactor: CubeEngine initialization logic and comments.&#10;&#10;Removed redundant comments and streamlined the CubeEngine class code. This improves readability while keeping the logic intact, ensuring clarity and maintainability.">
8
+ <change beforePath="$PROJECT_DIR$/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/index.html" afterDir="false" />
9
+ <change beforePath="$PROJECT_DIR$/main.js" beforeDir="false" afterPath="$PROJECT_DIR$/main.js" afterDir="false" />
10
+ </list>
11
+ <option name="SHOW_DIALOG" value="false" />
12
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
13
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
14
+ <option name="LAST_RESOLUTION" value="IGNORE" />
15
+ </component>
16
+ <component name="Git.Settings">
17
+ <option name="RECENT_BRANCH_BY_REPOSITORY">
18
+ <map>
19
+ <entry key="$PROJECT_DIR$" value="main" />
20
+ </map>
21
+ </option>
22
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
23
+ </component>
24
+ <component name="GitHubPullRequestSearchHistory">{
25
+ &quot;lastFilter&quot;: {
26
+ &quot;state&quot;: &quot;OPEN&quot;,
27
+ &quot;assignee&quot;: &quot;bryanlundberg01&quot;
28
+ }
29
+ }</component>
30
+ <component name="GithubPullRequestsUISettings">{
31
+ &quot;selectedUrlAndAccountId&quot;: {
32
+ &quot;url&quot;: &quot;https://github.com/bryanlundberg/cube-state-engine.git&quot;,
33
+ &quot;accountId&quot;: &quot;85b47674-9e23-4732-99d6-79570b26716d&quot;
34
+ }
35
+ }</component>
36
+ <component name="ProjectColorInfo">{
37
+ &quot;associatedIndex&quot;: 3
38
+ }</component>
39
+ <component name="ProjectId" id="2sl2I2ViYNbfTkFbsmtRZjsyMhx" />
40
+ <component name="ProjectViewState">
41
+ <option name="hideEmptyMiddlePackages" value="true" />
42
+ <option name="showLibraryContents" value="true" />
43
+ </component>
44
+ <component name="PropertiesComponent"><![CDATA[{
45
+ "keyToString": {
46
+ "JavaScript Debug.index.html.executor": "Run",
47
+ "Jest.2x2 Cube Tests.executor": "Run",
48
+ "Jest.Dw equals y' U.executor": "Run",
49
+ "Jest.Dw' equals y U'.executor": "Run",
50
+ "Jest.Dw2 equals Dw Dw.executor": "Run",
51
+ "Jest.M equals Lw L'.executor": "Run",
52
+ "Jest.M' equals Lw' L.executor": "Run",
53
+ "Jest.ROTATE M then M' returns to solved.executor": "Run",
54
+ "Jest.ROTATE Rw then Rw' returns to solved.executor": "Run",
55
+ "Jest.ROTATE z'.executor": "Run",
56
+ "Jest.ROTATE z.executor": "Run",
57
+ "Jest.Rw equals x L.executor": "Run",
58
+ "Jest.Rw' equals x' L'.executor": "Run",
59
+ "Jest.applyMoves supports B and records when requested.executor": "Run",
60
+ "Jest.applyMoves supports M and M' and records when requested.executor": "Run",
61
+ "Jest.applyMoves supports Rw and Rw' and records when requested.executor": "Run",
62
+ "Jest.applyMoves with record: false does not record history.executor": "Run",
63
+ "Jest.constructor scramble supports M and does not record history.executor": "Run",
64
+ "Jest.cube-engine-2x2.test.js.executor": "Run",
65
+ "Jest.cube-engine.test.js.executor": "Run",
66
+ "Jest.initialize with scramble R U' F R2 D.executor": "Run",
67
+ "Jest.initialize with scramble by string: R U' F R2 D.executor": "Run",
68
+ "Jest.spawn a cube.executor": "Run",
69
+ "RunOnceActivity.ShowReadmeOnStart": "true",
70
+ "RunOnceActivity.git.unshallow": "true",
71
+ "git-widget-placeholder": "virtual-egine-2x2",
72
+ "ignore.virus.scanning.warn.message": "true",
73
+ "junie.onboarding.icon.badge.shown": "true",
74
+ "last_opened_file_path": "C:/Users/bryan/OneDrive/Documentos/workspace/NexusTimer",
75
+ "node.js.detected.package.eslint": "true",
76
+ "node.js.detected.package.tslint": "true",
77
+ "node.js.selected.package.eslint": "(autodetect)",
78
+ "node.js.selected.package.tslint": "(autodetect)",
79
+ "nodejs.jest.jest_package": "C:/Users/bryan/OneDrive/Documentos/workspace/cube-state-engine/node_modules/jest",
80
+ "nodejs_package_manager_path": "npm",
81
+ "npm.build.executor": "Run",
82
+ "npm.test.executor": "Run",
83
+ "settings.editor.selected.configurable": "preferences.pluginManager",
84
+ "to.speed.mode.migration.done": "true",
85
+ "ts.external.directory.path": "C:\\Users\\bryan\\OneDrive\\Documentos\\workspace\\cube-state-engine\\node_modules\\typescript\\lib",
86
+ "vue.rearranger.settings.migration": "true"
87
+ }
88
+ }]]></component>
89
+ <component name="RunManager" selected="Jest.cube-engine-2x2.test.js">
90
+ <configuration name="applyMoves supports B and records when requested" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
91
+ <node-interpreter value="project" />
92
+ <jest-package value="$PROJECT_DIR$/node_modules/jest" />
93
+ <working-dir value="$PROJECT_DIR$" />
94
+ <envs />
95
+ <scope-kind value="TEST" />
96
+ <test-file value="$PROJECT_DIR$/test/cube-engine.test.js" />
97
+ <test-names>
98
+ <test-name value="applyMoves supports B and records when requested" />
99
+ </test-names>
100
+ <method v="2" />
101
+ </configuration>
102
+ <configuration name="cube-engine-2x2.test.js" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
103
+ <node-interpreter value="project" />
104
+ <jest-package value="$PROJECT_DIR$/node_modules/jest" />
105
+ <working-dir value="$PROJECT_DIR$" />
106
+ <envs />
107
+ <scope-kind value="TEST_FILE" />
108
+ <test-file value="$PROJECT_DIR$/test/cube-engine-2x2.test.js" />
109
+ <method v="2" />
110
+ </configuration>
111
+ <configuration name="cube-engine.test.js" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
112
+ <node-interpreter value="project" />
113
+ <jest-package value="$PROJECT_DIR$/node_modules/jest" />
114
+ <working-dir value="$PROJECT_DIR$" />
115
+ <envs />
116
+ <scope-kind value="TEST_FILE" />
117
+ <test-file value="$PROJECT_DIR$/test/cube-engine.test.js" />
118
+ <method v="2" />
119
+ </configuration>
120
+ <configuration name="spawn a cube" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
121
+ <node-interpreter value="project" />
122
+ <jest-package value="$PROJECT_DIR$/node_modules/jest" />
123
+ <working-dir value="$PROJECT_DIR$" />
124
+ <envs />
125
+ <scope-kind value="TEST" />
126
+ <test-file value="$PROJECT_DIR$/test/cube-engine.test.js" />
127
+ <test-names>
128
+ <test-name value="spawn a cube" />
129
+ </test-names>
130
+ <method v="2" />
131
+ </configuration>
132
+ <configuration name="index.html" type="JavascriptDebugType" temporary="true" nameIsGenerated="true" uri="http://localhost:63342/cube-state-engine/index.html" useBuiltInWebServerPort="true">
133
+ <method v="2" />
134
+ </configuration>
135
+ <recent_temporary>
136
+ <list>
137
+ <item itemvalue="Jest.cube-engine-2x2.test.js" />
138
+ <item itemvalue="Jest.cube-engine.test.js" />
139
+ <item itemvalue="Jest.applyMoves supports B and records when requested" />
140
+ <item itemvalue="JavaScript Debug.index.html" />
141
+ <item itemvalue="Jest.spawn a cube" />
142
+ </list>
143
+ </recent_temporary>
144
+ </component>
145
+ <component name="SharedIndexes">
146
+ <attachedChunks>
147
+ <set>
148
+ <option value="bundled-js-predefined-d6986cc7102b-1632447f56bf-JavaScript-WS-243.26574.96" />
149
+ </set>
150
+ </attachedChunks>
151
+ </component>
152
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
153
+ <component name="TaskManager">
154
+ <task active="true" id="Default" summary="Default task">
155
+ <changelist id="c7204f89-75f2-42e0-aed9-81b858994b5a" name="Changes" comment="" />
156
+ <created>1739015757661</created>
157
+ <option name="number" value="Default" />
158
+ <option name="presentableId" value="Default" />
159
+ <updated>1739015757661</updated>
160
+ <workItem from="1739015758729" duration="179000" />
161
+ <workItem from="1741396985188" duration="669000" />
162
+ <workItem from="1741434773408" duration="14000" />
163
+ <workItem from="1757809578390" duration="6244000" />
164
+ <workItem from="1757816608819" duration="487000" />
165
+ <workItem from="1757817801762" duration="372000" />
166
+ <workItem from="1759836800222" duration="2277000" />
167
+ <workItem from="1759843281721" duration="2894000" />
168
+ </task>
169
+ <task id="LOCAL-00001" summary="feat: Add scramble initialization and move application support&#10;&#10;Introduce a constructor option to initialize the CubeEngine with a scramble string, resetting the move history. Implement `applyMoves` to apply sequences of moves with an option to skip move history recording. Accompany changes with relevant tests.">
170
+ <option name="closed" value="true" />
171
+ <created>1757813016634</created>
172
+ <option name="number" value="00001" />
173
+ <option name="presentableId" value="LOCAL-00001" />
174
+ <option name="project" value="LOCAL" />
175
+ <updated>1757813016634</updated>
176
+ </task>
177
+ <task id="LOCAL-00002" summary="feat: Add support for wide D (Dw) moves in CubeEngine &#10;&#10;Introduced `rotateDw` and `#rotateDw` methods to handle wide D layer rotations. Updated `applyMoves` to process &quot;Dw&quot; and added corresponding tests to ensure correctness, including scramble handling and move recording behavior.">
178
+ <option name="closed" value="true" />
179
+ <created>1757814527881</created>
180
+ <option name="number" value="00002" />
181
+ <option name="presentableId" value="LOCAL-00002" />
182
+ <option name="project" value="LOCAL" />
183
+ <updated>1757814527881</updated>
184
+ </task>
185
+ <task id="LOCAL-00003" summary="Add support for wide U (Uw) layer rotations&#10;&#10;Implemented new methods to handle wide U layer rotations, `rotateUw` and `#rotateUw`, along with logic to differentiate between regular and wide U moves. Updated command parsing to recognize and process wide U moves appropriately.">
186
+ <option name="closed" value="true" />
187
+ <created>1757814670104</created>
188
+ <option name="number" value="00003" />
189
+ <option name="presentableId" value="LOCAL-00003" />
190
+ <option name="project" value="LOCAL" />
191
+ <updated>1757814670104</updated>
192
+ </task>
193
+ <task id="LOCAL-00004" summary="Add support for Rw wide moves and related tests&#10;&#10;Implemented functionality to handle Rw and Rw' (wide right-layer) rotations, including integration with move sequencing and history recording. Updated tests to validate correct behavior for new moves, ensure consistency with equivalent rotations, and verify state preservation.">
194
+ <option name="closed" value="true" />
195
+ <created>1757814961897</created>
196
+ <option name="number" value="00004" />
197
+ <option name="presentableId" value="LOCAL-00004" />
198
+ <option name="project" value="LOCAL" />
199
+ <updated>1757814961897</updated>
200
+ </task>
201
+ <task id="LOCAL-00005" summary="Add support for 'Lw' wide move rotation&#10;&#10;Implemented functionality for rotating the wide 'Lw' (LEFT two layers) move, both clockwise and counterclockwise. Updated the `applyMoves` method to recognize and execute 'Lw' commands along with proper history tracking.">
202
+ <option name="closed" value="true" />
203
+ <created>1757815147915</created>
204
+ <option name="number" value="00005" />
205
+ <option name="presentableId" value="LOCAL-00005" />
206
+ <option name="project" value="LOCAL" />
207
+ <updated>1757815147915</updated>
208
+ </task>
209
+ <task id="LOCAL-00006" summary="Add support for M slice moves and corresponding tests&#10;&#10;Introduce functionality to handle M and M' slice moves, including their recording in move history. Update documentation and logic in `applyMoves` to recognize M moves and handle scrambling. Add corresponding unit tests to ensure correctness and behavior consistency.">
210
+ <option name="closed" value="true" />
211
+ <created>1757815394671</created>
212
+ <option name="number" value="00006" />
213
+ <option name="presentableId" value="LOCAL-00006" />
214
+ <option name="project" value="LOCAL" />
215
+ <updated>1757815394671</updated>
216
+ </task>
217
+ <task id="LOCAL-00007" summary="Add rotateZ functionality and tests for the Z-axis rotation&#10;&#10;Introduce the `rotateZ` method to handle clockwise and counterclockwise rotations along the Z-axis. Updated the README for documentation, extended move handling, and added comprehensive unit tests to verify the functionality.">
218
+ <option name="closed" value="true" />
219
+ <created>1757815728756</created>
220
+ <option name="number" value="00007" />
221
+ <option name="presentableId" value="LOCAL-00007" />
222
+ <option name="project" value="LOCAL" />
223
+ <updated>1757815728756</updated>
224
+ </task>
225
+ <task id="LOCAL-00008" summary="Update README with new CubeEngine methods and examples&#10;&#10;Added details for new methods like `applyMoves`, wide layer rotations, and the constructor with optional scramble. Improved usage examples, including initializing with a scramble and retrieving movement history.">
226
+ <option name="closed" value="true" />
227
+ <created>1757815931435</created>
228
+ <option name="number" value="00008" />
229
+ <option name="presentableId" value="LOCAL-00008" />
230
+ <option name="project" value="LOCAL" />
231
+ <updated>1757815931435</updated>
232
+ </task>
233
+ <task id="LOCAL-00009" summary="feat: Add reset method to CubeEngine with corresponding test&#10;&#10;Implemented a reset method to revert the cube to its solved state and clear the move history. Added a unit test to ensure the method functions correctly by resetting both the cube's state and move history.">
234
+ <option name="closed" value="true" />
235
+ <created>1757816840133</created>
236
+ <option name="number" value="00009" />
237
+ <option name="presentableId" value="LOCAL-00009" />
238
+ <option name="project" value="LOCAL" />
239
+ <updated>1757816840133</updated>
240
+ </task>
241
+ <task id="LOCAL-00010" summary="feat: Add `reset` method and improve `CubeEngine` documentation&#10;&#10;The `reset` method allows resetting the cube to its solved state and clears the move history. Updated the `CubeEngine` constructor to accept an optional initial scramble, and revised the documentation for better clarity and completeness.">
242
+ <option name="closed" value="true" />
243
+ <created>1757817044103</created>
244
+ <option name="number" value="00010" />
245
+ <option name="presentableId" value="LOCAL-00010" />
246
+ <option name="project" value="LOCAL" />
247
+ <updated>1757817044103</updated>
248
+ </task>
249
+ <task id="LOCAL-00011" summary="feat: Add support for rotating the Back (B) layer of the cube&#10;&#10;Implemented `rotateB` function to handle Back layer rotations clockwise and counterclockwise. Updated related documentation, input bindings, and `applyMoves` method to include support for the B move. Added tests to ensure functionality and alignment with expected behavior.">
250
+ <option name="closed" value="true" />
251
+ <created>1757818136642</created>
252
+ <option name="number" value="00011" />
253
+ <option name="presentableId" value="LOCAL-00011" />
254
+ <option name="project" value="LOCAL" />
255
+ <updated>1757818136642</updated>
256
+ </task>
257
+ <task id="LOCAL-00012" summary="test: Add unit tests for 2x2 CubeEngine functionality&#10;&#10;Introduce tests for basic 2x2 cube operations, including initialization, move validations (M, wide moves), and algorithm execution. These tests ensure the expected behavior and edge case handling of the 2x2 cube simulation.">
258
+ <option name="closed" value="true" />
259
+ <created>1759844862946</created>
260
+ <option name="number" value="00012" />
261
+ <option name="presentableId" value="LOCAL-00012" />
262
+ <option name="project" value="LOCAL" />
263
+ <updated>1759844862946</updated>
264
+ </task>
265
+ <task id="LOCAL-00013" summary="feat: Add support for 2x2 cube size and refactor state initialization&#10;&#10;Introduced support for 2x2 cubes by updating methods to adapt to cube size. Refactored state initialization with dynamic matrix generation to reduce repetitive code. Updated cube rotation logic and validation to handle variable sizes more efficiently.">
266
+ <option name="closed" value="true" />
267
+ <created>1759845076135</created>
268
+ <option name="number" value="00013" />
269
+ <option name="presentableId" value="LOCAL-00013" />
270
+ <option name="project" value="LOCAL" />
271
+ <updated>1759845076135</updated>
272
+ </task>
273
+ <task id="LOCAL-00014" summary="refactor: CubeEngine initialization logic and comments.&#10;&#10;Removed redundant comments and streamlined the CubeEngine class code. This improves readability while keeping the logic intact, ensuring clarity and maintainability.">
274
+ <option name="closed" value="true" />
275
+ <created>1759845463330</created>
276
+ <option name="number" value="00014" />
277
+ <option name="presentableId" value="LOCAL-00014" />
278
+ <option name="project" value="LOCAL" />
279
+ <updated>1759845463330</updated>
280
+ </task>
281
+ <option name="localTasksCounter" value="15" />
282
+ <servers />
283
+ </component>
284
+ <component name="TypeScriptGeneratedFilesManager">
285
+ <option name="version" value="3" />
286
+ </component>
287
+ <component name="VcsManagerConfiguration">
288
+ <MESSAGE value="feat: Add scramble initialization and move application support&#10;&#10;Introduce a constructor option to initialize the CubeEngine with a scramble string, resetting the move history. Implement `applyMoves` to apply sequences of moves with an option to skip move history recording. Accompany changes with relevant tests." />
289
+ <MESSAGE value="feat: Add support for wide D (Dw) moves in CubeEngine &#10;&#10;Introduced `rotateDw` and `#rotateDw` methods to handle wide D layer rotations. Updated `applyMoves` to process &quot;Dw&quot; and added corresponding tests to ensure correctness, including scramble handling and move recording behavior." />
290
+ <MESSAGE value="Add support for wide U (Uw) layer rotations&#10;&#10;Implemented new methods to handle wide U layer rotations, `rotateUw` and `#rotateUw`, along with logic to differentiate between regular and wide U moves. Updated command parsing to recognize and process wide U moves appropriately." />
291
+ <MESSAGE value="Add support for Rw wide moves and related tests&#10;&#10;Implemented functionality to handle Rw and Rw' (wide right-layer) rotations, including integration with move sequencing and history recording. Updated tests to validate correct behavior for new moves, ensure consistency with equivalent rotations, and verify state preservation." />
292
+ <MESSAGE value="Add support for 'Lw' wide move rotation&#10;&#10;Implemented functionality for rotating the wide 'Lw' (LEFT two layers) move, both clockwise and counterclockwise. Updated the `applyMoves` method to recognize and execute 'Lw' commands along with proper history tracking." />
293
+ <MESSAGE value="Add support for M slice moves and corresponding tests&#10;&#10;Introduce functionality to handle M and M' slice moves, including their recording in move history. Update documentation and logic in `applyMoves` to recognize M moves and handle scrambling. Add corresponding unit tests to ensure correctness and behavior consistency." />
294
+ <MESSAGE value="Add rotateZ functionality and tests for the Z-axis rotation&#10;&#10;Introduce the `rotateZ` method to handle clockwise and counterclockwise rotations along the Z-axis. Updated the README for documentation, extended move handling, and added comprehensive unit tests to verify the functionality." />
295
+ <MESSAGE value="Update README with new CubeEngine methods and examples&#10;&#10;Added details for new methods like `applyMoves`, wide layer rotations, and the constructor with optional scramble. Improved usage examples, including initializing with a scramble and retrieving movement history." />
296
+ <MESSAGE value="feat: Add reset method to CubeEngine with corresponding test&#10;&#10;Implemented a reset method to revert the cube to its solved state and clear the move history. Added a unit test to ensure the method functions correctly by resetting both the cube's state and move history." />
297
+ <MESSAGE value="feat: Add `reset` method and improve `CubeEngine` documentation&#10;&#10;The `reset` method allows resetting the cube to its solved state and clears the move history. Updated the `CubeEngine` constructor to accept an optional initial scramble, and revised the documentation for better clarity and completeness." />
298
+ <MESSAGE value="feat: Add support for rotating the Back (B) layer of the cube&#10;&#10;Implemented `rotateB` function to handle Back layer rotations clockwise and counterclockwise. Updated related documentation, input bindings, and `applyMoves` method to include support for the B move. Added tests to ensure functionality and alignment with expected behavior." />
299
+ <MESSAGE value="test: Add unit tests for 2x2 CubeEngine functionality&#10;&#10;Introduce tests for basic 2x2 cube operations, including initialization, move validations (M, wide moves), and algorithm execution. These tests ensure the expected behavior and edge case handling of the 2x2 cube simulation." />
300
+ <MESSAGE value="feat: Add support for 2x2 cube size and refactor state initialization&#10;&#10;Introduced support for 2x2 cubes by updating methods to adapt to cube size. Refactored state initialization with dynamic matrix generation to reduce repetitive code. Updated cube rotation logic and validation to handle variable sizes more efficiently." />
301
+ <MESSAGE value="refactor: CubeEngine initialization logic and comments.&#10;&#10;Removed redundant comments and streamlined the CubeEngine class code. This improves readability while keeping the logic intact, ensuring clarity and maintainability." />
302
+ <option name="LAST_COMMIT_MESSAGE" value="refactor: CubeEngine initialization logic and comments.&#10;&#10;Removed redundant comments and streamlined the CubeEngine class code. This improves readability while keeping the logic intact, ensuring clarity and maintainability." />
303
+ </component>
304
+ </project>
package/dist/index.d.mts CHANGED
@@ -1,54 +1,43 @@
1
1
  class CubeEngine {
2
2
  MOVES = [];
3
+ size = 3;
4
+
5
+ constructor(initialScramble = "", options = { size: 3 }) {
6
+ const allowedSizes = [2, 3];
7
+ this.size = allowedSizes.includes(options.size) ? options.size : 3;
8
+
9
+ this.#initializeState();
3
10
 
4
- constructor(initialScramble = "") {
5
11
  // If an initial scramble string is provided, apply it without recording moves
6
12
  if (typeof initialScramble === "string" && initialScramble.trim().length > 0) {
7
13
  this.#applyMovesFromString(initialScramble, false);
8
- // Ensure history is empty for initial position
9
14
  this.MOVES = [];
10
15
  }
11
16
  }
12
17
 
13
- // States object for the rotation
14
- STATES = {
15
- UPPER: [
16
- // (White)
17
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
18
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
19
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]],
20
- ],
21
- LEFT: [
22
- // (Orange)
23
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
24
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
25
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]],
26
- ],
27
- FRONT: [
28
- // (Green)
29
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
30
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
31
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]],
32
- ],
33
- RIGHT: [
34
- // (Red)
35
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
36
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
37
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]],
38
- ],
39
- BACK: [
40
- // (Blue)
41
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
42
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
43
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]],
44
- ],
45
- DOWN: [
46
- // (Yellow)
47
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
48
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
49
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]],
50
- ],
51
- };
18
+ #initializeState() {
19
+ this.STATES = {
20
+ UPPER: this.#createFace("W"),
21
+ LEFT: this.#createFace("O"),
22
+ FRONT: this.#createFace("G"),
23
+ RIGHT: this.#createFace("R"),
24
+ BACK: this.#createFace("B"),
25
+ DOWN: this.#createFace("Y"),
26
+ };
27
+ }
28
+
29
+ // Create a face matrix based on cube size
30
+ #createFace(color) {
31
+ const face = [];
32
+ for (let i = 0; i < this.size; i++) {
33
+ const row = [];
34
+ for (let j = 0; j < this.size; j++) {
35
+ row.push(color);
36
+ }
37
+ face.push(row);
38
+ }
39
+ return face;
40
+ }
52
41
 
53
42
  /**
54
43
  * Rotates the (UPPER) layer clockwise or counterclockwise.
@@ -230,6 +219,7 @@ class CubeEngine {
230
219
  * Rotates the wide (DOWN two layers) clockwise or counterclockwise.
231
220
  */
232
221
  rotateDw(clockwise = true) {
222
+ if (this.size === 2) return;
233
223
  if (clockwise) {
234
224
  this.#rotateDw(true);
235
225
  this.MOVES.push("Dw");
@@ -253,6 +243,7 @@ class CubeEngine {
253
243
  * Rotates the wide (UPPER two layers) clockwise or counterclockwise.
254
244
  */
255
245
  rotateUw(clockwise = true) {
246
+ if (this.size === 2) return;
256
247
  if (clockwise) {
257
248
  this.#rotateUw(true);
258
249
  this.MOVES.push("Uw");
@@ -276,6 +267,7 @@ class CubeEngine {
276
267
  * Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
277
268
  */
278
269
  rotateRw(clockwise = true) {
270
+ if (this.size === 2) return;
279
271
  if (clockwise) {
280
272
  this.#rotateRw(true);
281
273
  this.MOVES.push("Rw");
@@ -299,6 +291,7 @@ class CubeEngine {
299
291
  * Rotates the wide (LEFT two layers) clockwise or counterclockwise.
300
292
  */
301
293
  rotateLw(clockwise = true) {
294
+ if (this.size === 2) return;
302
295
  if (clockwise) {
303
296
  this.#rotateLw(true);
304
297
  this.MOVES.push("Lw");
@@ -323,6 +316,7 @@ class CubeEngine {
323
316
  * Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
324
317
  */
325
318
  rotateM(clockwise = true) {
319
+ if (this.size === 2) return;
326
320
  if (clockwise) {
327
321
  this.#rotateM(true);
328
322
  this.MOVES.push("M");
@@ -474,21 +468,42 @@ class CubeEngine {
474
468
  */
475
469
  #switchMatrix(matrix, clockwise = true) {
476
470
  const clone = structuredClone(matrix);
471
+ const size = this.size;
477
472
 
478
- const tempMatrix = [...clone[0], ...clone[1], ...clone[2]];
473
+ // Flatten the matrix
474
+ let tempMatrix = [];
475
+ for (let i = 0; i < size; i++) {
476
+ tempMatrix = [...tempMatrix, ...clone[i]];
477
+ }
479
478
 
480
- if (clockwise) {
481
- return [
482
- [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
483
- [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
484
- [tempMatrix[8], tempMatrix[5], tempMatrix[2]],
485
- ];
479
+ if (size === 2) {
480
+ // For 2x2 cubes
481
+ if (clockwise) {
482
+ return [
483
+ [tempMatrix[2], tempMatrix[0]],
484
+ [tempMatrix[3], tempMatrix[1]]
485
+ ];
486
+ } else {
487
+ return [
488
+ [tempMatrix[1], tempMatrix[3]],
489
+ [tempMatrix[0], tempMatrix[2]]
490
+ ];
491
+ }
486
492
  } else {
487
- return [
488
- [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
489
- [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
490
- [tempMatrix[0], tempMatrix[3], tempMatrix[6]],
491
- ];
493
+ // For 3x3 cubes (original logic)
494
+ if (clockwise) {
495
+ return [
496
+ [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
497
+ [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
498
+ [tempMatrix[8], tempMatrix[5], tempMatrix[2]],
499
+ ];
500
+ } else {
501
+ return [
502
+ [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
503
+ [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
504
+ [tempMatrix[0], tempMatrix[3], tempMatrix[6]],
505
+ ];
506
+ }
492
507
  }
493
508
  }
494
509
 
@@ -516,13 +531,15 @@ class CubeEngine {
516
531
  };
517
532
 
518
533
  const layersSolved = Object.keys(temp).map((layer) => {
519
- const mixedMatrix = [
520
- ...temp[layer][0],
521
- ...temp[layer][1],
522
- ...temp[layer][2],
523
- ];
524
534
 
525
- const centerColor = mixedMatrix[4];
535
+ let mixedMatrix = [];
536
+ for (let i = 0; i < this.size; i++) {
537
+ mixedMatrix = [...mixedMatrix, ...temp[layer][i]];
538
+ }
539
+
540
+ // For a 2x2 cube, there is no center; we use the first color as reference
541
+ // For a 3x3 cube, we use the color of the center (position 4)
542
+ const centerColor = this.size === 2 ? mixedMatrix[0] : mixedMatrix[4];
526
543
 
527
544
  return mixedMatrix.every((currentColor) => currentColor === centerColor);
528
545
  });
@@ -544,38 +561,7 @@ class CubeEngine {
544
561
  * Resets the cube to the solved state and clears the move history.
545
562
  */
546
563
  reset() {
547
- this.STATES = {
548
- UPPER: [
549
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
550
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
551
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]],
552
- ],
553
- LEFT: [
554
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
555
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
556
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]],
557
- ],
558
- FRONT: [
559
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
560
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
561
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]],
562
- ],
563
- RIGHT: [
564
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
565
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
566
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]],
567
- ],
568
- BACK: [
569
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
570
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
571
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]],
572
- ],
573
- DOWN: [
574
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
575
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
576
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]],
577
- ],
578
- };
564
+ this.#initializeState();
579
565
  this.MOVES = [];
580
566
  }
581
567
 
@@ -606,7 +592,6 @@ class CubeEngine {
606
592
 
607
593
  const exec = (fnClockwise, fnCounter) => {
608
594
  if (isDouble) {
609
- // Double turns ignore prime; do two clockwise quarter-turns
610
595
  fnClockwise();
611
596
  fnClockwise();
612
597
  } else {
package/dist/index.d.ts CHANGED
@@ -1,54 +1,43 @@
1
1
  class CubeEngine {
2
2
  MOVES = [];
3
+ size = 3;
4
+
5
+ constructor(initialScramble = "", options = { size: 3 }) {
6
+ const allowedSizes = [2, 3];
7
+ this.size = allowedSizes.includes(options.size) ? options.size : 3;
8
+
9
+ this.#initializeState();
3
10
 
4
- constructor(initialScramble = "") {
5
11
  // If an initial scramble string is provided, apply it without recording moves
6
12
  if (typeof initialScramble === "string" && initialScramble.trim().length > 0) {
7
13
  this.#applyMovesFromString(initialScramble, false);
8
- // Ensure history is empty for initial position
9
14
  this.MOVES = [];
10
15
  }
11
16
  }
12
17
 
13
- // States object for the rotation
14
- STATES = {
15
- UPPER: [
16
- // (White)
17
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
18
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
19
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]],
20
- ],
21
- LEFT: [
22
- // (Orange)
23
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
24
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
25
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]],
26
- ],
27
- FRONT: [
28
- // (Green)
29
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
30
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
31
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]],
32
- ],
33
- RIGHT: [
34
- // (Red)
35
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
36
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
37
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]],
38
- ],
39
- BACK: [
40
- // (Blue)
41
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
42
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
43
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]],
44
- ],
45
- DOWN: [
46
- // (Yellow)
47
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
48
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
49
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]],
50
- ],
51
- };
18
+ #initializeState() {
19
+ this.STATES = {
20
+ UPPER: this.#createFace("W"),
21
+ LEFT: this.#createFace("O"),
22
+ FRONT: this.#createFace("G"),
23
+ RIGHT: this.#createFace("R"),
24
+ BACK: this.#createFace("B"),
25
+ DOWN: this.#createFace("Y"),
26
+ };
27
+ }
28
+
29
+ // Create a face matrix based on cube size
30
+ #createFace(color) {
31
+ const face = [];
32
+ for (let i = 0; i < this.size; i++) {
33
+ const row = [];
34
+ for (let j = 0; j < this.size; j++) {
35
+ row.push(color);
36
+ }
37
+ face.push(row);
38
+ }
39
+ return face;
40
+ }
52
41
 
53
42
  /**
54
43
  * Rotates the (UPPER) layer clockwise or counterclockwise.
@@ -230,6 +219,7 @@ class CubeEngine {
230
219
  * Rotates the wide (DOWN two layers) clockwise or counterclockwise.
231
220
  */
232
221
  rotateDw(clockwise = true) {
222
+ if (this.size === 2) return;
233
223
  if (clockwise) {
234
224
  this.#rotateDw(true);
235
225
  this.MOVES.push("Dw");
@@ -253,6 +243,7 @@ class CubeEngine {
253
243
  * Rotates the wide (UPPER two layers) clockwise or counterclockwise.
254
244
  */
255
245
  rotateUw(clockwise = true) {
246
+ if (this.size === 2) return;
256
247
  if (clockwise) {
257
248
  this.#rotateUw(true);
258
249
  this.MOVES.push("Uw");
@@ -276,6 +267,7 @@ class CubeEngine {
276
267
  * Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
277
268
  */
278
269
  rotateRw(clockwise = true) {
270
+ if (this.size === 2) return;
279
271
  if (clockwise) {
280
272
  this.#rotateRw(true);
281
273
  this.MOVES.push("Rw");
@@ -299,6 +291,7 @@ class CubeEngine {
299
291
  * Rotates the wide (LEFT two layers) clockwise or counterclockwise.
300
292
  */
301
293
  rotateLw(clockwise = true) {
294
+ if (this.size === 2) return;
302
295
  if (clockwise) {
303
296
  this.#rotateLw(true);
304
297
  this.MOVES.push("Lw");
@@ -323,6 +316,7 @@ class CubeEngine {
323
316
  * Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
324
317
  */
325
318
  rotateM(clockwise = true) {
319
+ if (this.size === 2) return;
326
320
  if (clockwise) {
327
321
  this.#rotateM(true);
328
322
  this.MOVES.push("M");
@@ -474,21 +468,42 @@ class CubeEngine {
474
468
  */
475
469
  #switchMatrix(matrix, clockwise = true) {
476
470
  const clone = structuredClone(matrix);
471
+ const size = this.size;
477
472
 
478
- const tempMatrix = [...clone[0], ...clone[1], ...clone[2]];
473
+ // Flatten the matrix
474
+ let tempMatrix = [];
475
+ for (let i = 0; i < size; i++) {
476
+ tempMatrix = [...tempMatrix, ...clone[i]];
477
+ }
479
478
 
480
- if (clockwise) {
481
- return [
482
- [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
483
- [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
484
- [tempMatrix[8], tempMatrix[5], tempMatrix[2]],
485
- ];
479
+ if (size === 2) {
480
+ // For 2x2 cubes
481
+ if (clockwise) {
482
+ return [
483
+ [tempMatrix[2], tempMatrix[0]],
484
+ [tempMatrix[3], tempMatrix[1]]
485
+ ];
486
+ } else {
487
+ return [
488
+ [tempMatrix[1], tempMatrix[3]],
489
+ [tempMatrix[0], tempMatrix[2]]
490
+ ];
491
+ }
486
492
  } else {
487
- return [
488
- [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
489
- [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
490
- [tempMatrix[0], tempMatrix[3], tempMatrix[6]],
491
- ];
493
+ // For 3x3 cubes (original logic)
494
+ if (clockwise) {
495
+ return [
496
+ [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
497
+ [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
498
+ [tempMatrix[8], tempMatrix[5], tempMatrix[2]],
499
+ ];
500
+ } else {
501
+ return [
502
+ [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
503
+ [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
504
+ [tempMatrix[0], tempMatrix[3], tempMatrix[6]],
505
+ ];
506
+ }
492
507
  }
493
508
  }
494
509
 
@@ -516,13 +531,15 @@ class CubeEngine {
516
531
  };
517
532
 
518
533
  const layersSolved = Object.keys(temp).map((layer) => {
519
- const mixedMatrix = [
520
- ...temp[layer][0],
521
- ...temp[layer][1],
522
- ...temp[layer][2],
523
- ];
524
534
 
525
- const centerColor = mixedMatrix[4];
535
+ let mixedMatrix = [];
536
+ for (let i = 0; i < this.size; i++) {
537
+ mixedMatrix = [...mixedMatrix, ...temp[layer][i]];
538
+ }
539
+
540
+ // For a 2x2 cube, there is no center; we use the first color as reference
541
+ // For a 3x3 cube, we use the color of the center (position 4)
542
+ const centerColor = this.size === 2 ? mixedMatrix[0] : mixedMatrix[4];
526
543
 
527
544
  return mixedMatrix.every((currentColor) => currentColor === centerColor);
528
545
  });
@@ -544,38 +561,7 @@ class CubeEngine {
544
561
  * Resets the cube to the solved state and clears the move history.
545
562
  */
546
563
  reset() {
547
- this.STATES = {
548
- UPPER: [
549
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
550
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
551
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]],
552
- ],
553
- LEFT: [
554
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
555
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
556
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]],
557
- ],
558
- FRONT: [
559
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
560
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
561
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]],
562
- ],
563
- RIGHT: [
564
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
565
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
566
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]],
567
- ],
568
- BACK: [
569
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
570
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
571
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]],
572
- ],
573
- DOWN: [
574
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
575
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
576
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]],
577
- ],
578
- };
564
+ this.#initializeState();
579
565
  this.MOVES = [];
580
566
  }
581
567
 
@@ -606,7 +592,6 @@ class CubeEngine {
606
592
 
607
593
  const exec = (fnClockwise, fnCounter) => {
608
594
  if (isDouble) {
609
- // Double turns ignore prime; do two clockwise quarter-turns
610
595
  fnClockwise();
611
596
  fnClockwise();
612
597
  } else {
package/dist/index.js CHANGED
@@ -45,50 +45,15 @@ __export(src_exports, {
45
45
  CubeEngine: () => CubeEngine
46
46
  });
47
47
  module.exports = __toCommonJS(src_exports);
48
- var _CubeEngine_instances, rotateU_fn, rotateF_fn, rotateB_fn, rotateR_fn, rotateL_fn, rotateD_fn, rotateDw_fn, rotateUw_fn, rotateRw_fn, rotateLw_fn, rotateM_fn, rotateX_fn, rotateZ_fn, rotateY_fn, switchMatrix_fn, specialFlip_fn, applyMovesFromString_fn;
48
+ var _CubeEngine_instances, initializeState_fn, createFace_fn, rotateU_fn, rotateF_fn, rotateB_fn, rotateR_fn, rotateL_fn, rotateD_fn, rotateDw_fn, rotateUw_fn, rotateRw_fn, rotateLw_fn, rotateM_fn, rotateX_fn, rotateZ_fn, rotateY_fn, switchMatrix_fn, specialFlip_fn, applyMovesFromString_fn;
49
49
  var CubeEngine = class {
50
- constructor(initialScramble = "") {
50
+ constructor(initialScramble = "", options = { size: 3 }) {
51
51
  __privateAdd(this, _CubeEngine_instances);
52
52
  __publicField(this, "MOVES", []);
53
- // States object for the rotation
54
- __publicField(this, "STATES", {
55
- UPPER: [
56
- // (White)
57
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
58
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
59
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]]
60
- ],
61
- LEFT: [
62
- // (Orange)
63
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
64
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
65
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]]
66
- ],
67
- FRONT: [
68
- // (Green)
69
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
70
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
71
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]]
72
- ],
73
- RIGHT: [
74
- // (Red)
75
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
76
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
77
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]]
78
- ],
79
- BACK: [
80
- // (Blue)
81
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
82
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
83
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]]
84
- ],
85
- DOWN: [
86
- // (Yellow)
87
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
88
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
89
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
90
- ]
91
- });
53
+ __publicField(this, "size", 3);
54
+ const allowedSizes = [2, 3];
55
+ this.size = allowedSizes.includes(options.size) ? options.size : 3;
56
+ __privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
92
57
  if (typeof initialScramble === "string" && initialScramble.trim().length > 0) {
93
58
  __privateMethod(this, _CubeEngine_instances, applyMovesFromString_fn).call(this, initialScramble, false);
94
59
  this.MOVES = [];
@@ -170,6 +135,7 @@ var CubeEngine = class {
170
135
  * Rotates the wide (DOWN two layers) clockwise or counterclockwise.
171
136
  */
172
137
  rotateDw(clockwise = true) {
138
+ if (this.size === 2) return;
173
139
  if (clockwise) {
174
140
  __privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, true);
175
141
  this.MOVES.push("Dw");
@@ -182,6 +148,7 @@ var CubeEngine = class {
182
148
  * Rotates the wide (UPPER two layers) clockwise or counterclockwise.
183
149
  */
184
150
  rotateUw(clockwise = true) {
151
+ if (this.size === 2) return;
185
152
  if (clockwise) {
186
153
  __privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, true);
187
154
  this.MOVES.push("Uw");
@@ -194,6 +161,7 @@ var CubeEngine = class {
194
161
  * Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
195
162
  */
196
163
  rotateRw(clockwise = true) {
164
+ if (this.size === 2) return;
197
165
  if (clockwise) {
198
166
  __privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, true);
199
167
  this.MOVES.push("Rw");
@@ -206,6 +174,7 @@ var CubeEngine = class {
206
174
  * Rotates the wide (LEFT two layers) clockwise or counterclockwise.
207
175
  */
208
176
  rotateLw(clockwise = true) {
177
+ if (this.size === 2) return;
209
178
  if (clockwise) {
210
179
  __privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, true);
211
180
  this.MOVES.push("Lw");
@@ -218,6 +187,7 @@ var CubeEngine = class {
218
187
  * Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
219
188
  */
220
189
  rotateM(clockwise = true) {
190
+ if (this.size === 2) return;
221
191
  if (clockwise) {
222
192
  __privateMethod(this, _CubeEngine_instances, rotateM_fn).call(this, true);
223
193
  this.MOVES.push("M");
@@ -274,12 +244,11 @@ var CubeEngine = class {
274
244
  isSolved() {
275
245
  const temp = __spreadValues({}, this.STATES);
276
246
  const layersSolved = Object.keys(temp).map((layer) => {
277
- const mixedMatrix = [
278
- ...temp[layer][0],
279
- ...temp[layer][1],
280
- ...temp[layer][2]
281
- ];
282
- const centerColor = mixedMatrix[4];
247
+ let mixedMatrix = [];
248
+ for (let i = 0; i < this.size; i++) {
249
+ mixedMatrix = [...mixedMatrix, ...temp[layer][i]];
250
+ }
251
+ const centerColor = this.size === 2 ? mixedMatrix[0] : mixedMatrix[4];
283
252
  return mixedMatrix.every((currentColor) => currentColor === centerColor);
284
253
  });
285
254
  return layersSolved.every((isLayerSolved) => isLayerSolved);
@@ -297,38 +266,7 @@ var CubeEngine = class {
297
266
  * Resets the cube to the solved state and clears the move history.
298
267
  */
299
268
  reset() {
300
- this.STATES = {
301
- UPPER: [
302
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
303
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
304
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]]
305
- ],
306
- LEFT: [
307
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
308
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
309
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]]
310
- ],
311
- FRONT: [
312
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
313
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
314
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]]
315
- ],
316
- RIGHT: [
317
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
318
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
319
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]]
320
- ],
321
- BACK: [
322
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
323
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
324
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]]
325
- ],
326
- DOWN: [
327
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
328
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
329
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
330
- ]
331
- };
269
+ __privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
332
270
  this.MOVES = [];
333
271
  }
334
272
  /**
@@ -343,6 +281,28 @@ var CubeEngine = class {
343
281
  }
344
282
  };
345
283
  _CubeEngine_instances = new WeakSet();
284
+ initializeState_fn = function() {
285
+ this.STATES = {
286
+ UPPER: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "W"),
287
+ LEFT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "O"),
288
+ FRONT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "G"),
289
+ RIGHT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "R"),
290
+ BACK: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "B"),
291
+ DOWN: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "Y")
292
+ };
293
+ };
294
+ // Create a face matrix based on cube size
295
+ createFace_fn = function(color) {
296
+ const face = [];
297
+ for (let i = 0; i < this.size; i++) {
298
+ const row = [];
299
+ for (let j = 0; j < this.size; j++) {
300
+ row.push(color);
301
+ }
302
+ face.push(row);
303
+ }
304
+ return face;
305
+ };
346
306
  rotateU_fn = function(clockwise = true) {
347
307
  if (clockwise) {
348
308
  this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, true);
@@ -546,19 +506,37 @@ rotateY_fn = function(clockwise = true) {
546
506
  */
547
507
  switchMatrix_fn = function(matrix, clockwise = true) {
548
508
  const clone = structuredClone(matrix);
549
- const tempMatrix = [...clone[0], ...clone[1], ...clone[2]];
550
- if (clockwise) {
551
- return [
552
- [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
553
- [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
554
- [tempMatrix[8], tempMatrix[5], tempMatrix[2]]
555
- ];
509
+ const size = this.size;
510
+ let tempMatrix = [];
511
+ for (let i = 0; i < size; i++) {
512
+ tempMatrix = [...tempMatrix, ...clone[i]];
513
+ }
514
+ if (size === 2) {
515
+ if (clockwise) {
516
+ return [
517
+ [tempMatrix[2], tempMatrix[0]],
518
+ [tempMatrix[3], tempMatrix[1]]
519
+ ];
520
+ } else {
521
+ return [
522
+ [tempMatrix[1], tempMatrix[3]],
523
+ [tempMatrix[0], tempMatrix[2]]
524
+ ];
525
+ }
556
526
  } else {
557
- return [
558
- [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
559
- [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
560
- [tempMatrix[0], tempMatrix[3], tempMatrix[6]]
561
- ];
527
+ if (clockwise) {
528
+ return [
529
+ [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
530
+ [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
531
+ [tempMatrix[8], tempMatrix[5], tempMatrix[2]]
532
+ ];
533
+ } else {
534
+ return [
535
+ [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
536
+ [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
537
+ [tempMatrix[0], tempMatrix[3], tempMatrix[6]]
538
+ ];
539
+ }
562
540
  }
563
541
  };
564
542
  specialFlip_fn = function(matrix) {
@@ -573,7 +551,6 @@ applyMovesFromString_fn = function(sequence, record = true) {
573
551
  const rest = token.slice(1);
574
552
  const isDouble = rest.includes("2");
575
553
  const isPrime = rest.includes("'");
576
- const times = isDouble ? 2 : 1;
577
554
  const exec = (fnClockwise, fnCounter) => {
578
555
  if (isDouble) {
579
556
  fnClockwise();
package/dist/index.mjs CHANGED
@@ -23,50 +23,15 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
23
23
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
24
24
 
25
25
  // src/index.js
26
- var _CubeEngine_instances, rotateU_fn, rotateF_fn, rotateB_fn, rotateR_fn, rotateL_fn, rotateD_fn, rotateDw_fn, rotateUw_fn, rotateRw_fn, rotateLw_fn, rotateM_fn, rotateX_fn, rotateZ_fn, rotateY_fn, switchMatrix_fn, specialFlip_fn, applyMovesFromString_fn;
26
+ var _CubeEngine_instances, initializeState_fn, createFace_fn, rotateU_fn, rotateF_fn, rotateB_fn, rotateR_fn, rotateL_fn, rotateD_fn, rotateDw_fn, rotateUw_fn, rotateRw_fn, rotateLw_fn, rotateM_fn, rotateX_fn, rotateZ_fn, rotateY_fn, switchMatrix_fn, specialFlip_fn, applyMovesFromString_fn;
27
27
  var CubeEngine = class {
28
- constructor(initialScramble = "") {
28
+ constructor(initialScramble = "", options = { size: 3 }) {
29
29
  __privateAdd(this, _CubeEngine_instances);
30
30
  __publicField(this, "MOVES", []);
31
- // States object for the rotation
32
- __publicField(this, "STATES", {
33
- UPPER: [
34
- // (White)
35
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
36
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
37
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]]
38
- ],
39
- LEFT: [
40
- // (Orange)
41
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
42
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
43
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]]
44
- ],
45
- FRONT: [
46
- // (Green)
47
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
48
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
49
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]]
50
- ],
51
- RIGHT: [
52
- // (Red)
53
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
54
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
55
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]]
56
- ],
57
- BACK: [
58
- // (Blue)
59
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
60
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
61
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]]
62
- ],
63
- DOWN: [
64
- // (Yellow)
65
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
66
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
67
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
68
- ]
69
- });
31
+ __publicField(this, "size", 3);
32
+ const allowedSizes = [2, 3];
33
+ this.size = allowedSizes.includes(options.size) ? options.size : 3;
34
+ __privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
70
35
  if (typeof initialScramble === "string" && initialScramble.trim().length > 0) {
71
36
  __privateMethod(this, _CubeEngine_instances, applyMovesFromString_fn).call(this, initialScramble, false);
72
37
  this.MOVES = [];
@@ -148,6 +113,7 @@ var CubeEngine = class {
148
113
  * Rotates the wide (DOWN two layers) clockwise or counterclockwise.
149
114
  */
150
115
  rotateDw(clockwise = true) {
116
+ if (this.size === 2) return;
151
117
  if (clockwise) {
152
118
  __privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, true);
153
119
  this.MOVES.push("Dw");
@@ -160,6 +126,7 @@ var CubeEngine = class {
160
126
  * Rotates the wide (UPPER two layers) clockwise or counterclockwise.
161
127
  */
162
128
  rotateUw(clockwise = true) {
129
+ if (this.size === 2) return;
163
130
  if (clockwise) {
164
131
  __privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, true);
165
132
  this.MOVES.push("Uw");
@@ -172,6 +139,7 @@ var CubeEngine = class {
172
139
  * Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
173
140
  */
174
141
  rotateRw(clockwise = true) {
142
+ if (this.size === 2) return;
175
143
  if (clockwise) {
176
144
  __privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, true);
177
145
  this.MOVES.push("Rw");
@@ -184,6 +152,7 @@ var CubeEngine = class {
184
152
  * Rotates the wide (LEFT two layers) clockwise or counterclockwise.
185
153
  */
186
154
  rotateLw(clockwise = true) {
155
+ if (this.size === 2) return;
187
156
  if (clockwise) {
188
157
  __privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, true);
189
158
  this.MOVES.push("Lw");
@@ -196,6 +165,7 @@ var CubeEngine = class {
196
165
  * Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
197
166
  */
198
167
  rotateM(clockwise = true) {
168
+ if (this.size === 2) return;
199
169
  if (clockwise) {
200
170
  __privateMethod(this, _CubeEngine_instances, rotateM_fn).call(this, true);
201
171
  this.MOVES.push("M");
@@ -252,12 +222,11 @@ var CubeEngine = class {
252
222
  isSolved() {
253
223
  const temp = __spreadValues({}, this.STATES);
254
224
  const layersSolved = Object.keys(temp).map((layer) => {
255
- const mixedMatrix = [
256
- ...temp[layer][0],
257
- ...temp[layer][1],
258
- ...temp[layer][2]
259
- ];
260
- const centerColor = mixedMatrix[4];
225
+ let mixedMatrix = [];
226
+ for (let i = 0; i < this.size; i++) {
227
+ mixedMatrix = [...mixedMatrix, ...temp[layer][i]];
228
+ }
229
+ const centerColor = this.size === 2 ? mixedMatrix[0] : mixedMatrix[4];
261
230
  return mixedMatrix.every((currentColor) => currentColor === centerColor);
262
231
  });
263
232
  return layersSolved.every((isLayerSolved) => isLayerSolved);
@@ -275,38 +244,7 @@ var CubeEngine = class {
275
244
  * Resets the cube to the solved state and clears the move history.
276
245
  */
277
246
  reset() {
278
- this.STATES = {
279
- UPPER: [
280
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
281
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
282
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]]
283
- ],
284
- LEFT: [
285
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
286
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
287
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]]
288
- ],
289
- FRONT: [
290
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
291
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
292
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]]
293
- ],
294
- RIGHT: [
295
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
296
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
297
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]]
298
- ],
299
- BACK: [
300
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
301
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
302
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]]
303
- ],
304
- DOWN: [
305
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
306
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
307
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
308
- ]
309
- };
247
+ __privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
310
248
  this.MOVES = [];
311
249
  }
312
250
  /**
@@ -321,6 +259,28 @@ var CubeEngine = class {
321
259
  }
322
260
  };
323
261
  _CubeEngine_instances = new WeakSet();
262
+ initializeState_fn = function() {
263
+ this.STATES = {
264
+ UPPER: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "W"),
265
+ LEFT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "O"),
266
+ FRONT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "G"),
267
+ RIGHT: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "R"),
268
+ BACK: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "B"),
269
+ DOWN: __privateMethod(this, _CubeEngine_instances, createFace_fn).call(this, "Y")
270
+ };
271
+ };
272
+ // Create a face matrix based on cube size
273
+ createFace_fn = function(color) {
274
+ const face = [];
275
+ for (let i = 0; i < this.size; i++) {
276
+ const row = [];
277
+ for (let j = 0; j < this.size; j++) {
278
+ row.push(color);
279
+ }
280
+ face.push(row);
281
+ }
282
+ return face;
283
+ };
324
284
  rotateU_fn = function(clockwise = true) {
325
285
  if (clockwise) {
326
286
  this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, true);
@@ -524,19 +484,37 @@ rotateY_fn = function(clockwise = true) {
524
484
  */
525
485
  switchMatrix_fn = function(matrix, clockwise = true) {
526
486
  const clone = structuredClone(matrix);
527
- const tempMatrix = [...clone[0], ...clone[1], ...clone[2]];
528
- if (clockwise) {
529
- return [
530
- [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
531
- [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
532
- [tempMatrix[8], tempMatrix[5], tempMatrix[2]]
533
- ];
487
+ const size = this.size;
488
+ let tempMatrix = [];
489
+ for (let i = 0; i < size; i++) {
490
+ tempMatrix = [...tempMatrix, ...clone[i]];
491
+ }
492
+ if (size === 2) {
493
+ if (clockwise) {
494
+ return [
495
+ [tempMatrix[2], tempMatrix[0]],
496
+ [tempMatrix[3], tempMatrix[1]]
497
+ ];
498
+ } else {
499
+ return [
500
+ [tempMatrix[1], tempMatrix[3]],
501
+ [tempMatrix[0], tempMatrix[2]]
502
+ ];
503
+ }
534
504
  } else {
535
- return [
536
- [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
537
- [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
538
- [tempMatrix[0], tempMatrix[3], tempMatrix[6]]
539
- ];
505
+ if (clockwise) {
506
+ return [
507
+ [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
508
+ [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
509
+ [tempMatrix[8], tempMatrix[5], tempMatrix[2]]
510
+ ];
511
+ } else {
512
+ return [
513
+ [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
514
+ [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
515
+ [tempMatrix[0], tempMatrix[3], tempMatrix[6]]
516
+ ];
517
+ }
540
518
  }
541
519
  };
542
520
  specialFlip_fn = function(matrix) {
@@ -551,7 +529,6 @@ applyMovesFromString_fn = function(sequence, record = true) {
551
529
  const rest = token.slice(1);
552
530
  const isDouble = rest.includes("2");
553
531
  const isPrime = rest.includes("'");
554
- const times = isDouble ? 2 : 1;
555
532
  const exec = (fnClockwise, fnCounter) => {
556
533
  if (isDouble) {
557
534
  fnClockwise();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cube-state-engine",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "An efficient representation in memory for tracking the Rubik's cube state on each movement.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1,12 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
- <excludeFolder url="file://$MODULE_DIR$/temp" />
7
- <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
- </content>
9
- <orderEntry type="inheritedJdk" />
10
- <orderEntry type="sourceFolder" forTests="false" />
11
- </component>
12
- </module>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/cube-state-engine.iml" filepath="$PROJECT_DIR$/.idea/cube-state-engine.iml" />
6
- </modules>
7
- </component>
8
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>