cube-state-engine 1.2.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/README.md CHANGED
@@ -19,12 +19,13 @@ A core state manager designed to integrate with custom 3D cube models. This engi
19
19
  | `state()` | Returns the current state of the cube as an object representing each face. | `object` |
20
20
  | `getMoves(asString?: boolean)` | Returns the history of all movements; as string if `true` (default), or as array if `false`. | `string / string[]` |
21
21
  | `reset()` | Resets the cube to the solved state and clears the move history. | `void` |
22
- | `applyMoves(sequence: string, options?: {record?: boolean})` | Applies a sequence of moves (supports U, D, L, R, F, x, y, z, M, Dw, Uw, Rw, Lw with ', 2). | `void` |
22
+ | `applyMoves(sequence: string, options?: {record?: boolean})` | Applies a sequence of moves (supports U, D, L, R, F, B, x, y, z, M, Dw, Uw, Rw, Lw with ', 2). | `void` |
23
23
  | `rotateU(clockwise?: boolean)` | Rotates the **Upper** layer clockwise or counterclockwise. | `void` |
24
24
  | `rotateD(clockwise?: boolean)` | Rotates the **Down** layer clockwise or counterclockwise. | `void` |
25
25
  | `rotateL(clockwise?: boolean)` | Rotates the **Left** layer clockwise or counterclockwise. | `void` |
26
26
  | `rotateR(clockwise?: boolean)` | Rotates the **Right** layer clockwise or counterclockwise. | `void` |
27
27
  | `rotateF(clockwise?: boolean)` | Rotates the **Front** layer clockwise or counterclockwise. | `void` |
28
+ | `rotateB(clockwise?: boolean)` | Rotates the **Back** layer clockwise or counterclockwise. | `void` |
28
29
  | `rotateX(clockwise?: boolean)` | Rotates the cube along the **X-axis** clockwise or counterclockwise. | `void` |
29
30
  | `rotateY(clockwise?: boolean)` | Rotates the cube along the **Y-axis** clockwise or counterclockwise. | `void` |
30
31
  | `rotateZ(clockwise?: boolean)` | Rotates the cube along the **Z-axis** clockwise or counterclockwise. | `void` |
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.
@@ -116,6 +105,33 @@ class CubeEngine {
116
105
  }
117
106
  }
118
107
 
108
+ /**
109
+ * Rotates the (BACK) layer clockwise or counterclockwise.
110
+ */
111
+ rotateB(clockwise = true) {
112
+ if (clockwise) {
113
+ this.#rotateB(true);
114
+ this.MOVES.push("B");
115
+ } else {
116
+ this.#rotateB(false);
117
+ this.MOVES.push("B'");
118
+ }
119
+ }
120
+
121
+ #rotateB(clockwise = true) {
122
+ // Implement B as y2 F y2
123
+ // Clockwise/counterclockwise direction is preserved through y2 conjugation
124
+ this.#rotateY(true);
125
+ this.#rotateY(true);
126
+ if (clockwise) {
127
+ this.#rotateF(true);
128
+ } else {
129
+ this.#rotateF(false);
130
+ }
131
+ this.#rotateY(false);
132
+ this.#rotateY(false);
133
+ }
134
+
119
135
  /**
120
136
  * Rotates the (RIGHT) layer clockwise or counterclockwise.
121
137
  */
@@ -203,6 +219,7 @@ class CubeEngine {
203
219
  * Rotates the wide (DOWN two layers) clockwise or counterclockwise.
204
220
  */
205
221
  rotateDw(clockwise = true) {
222
+ if (this.size === 2) return;
206
223
  if (clockwise) {
207
224
  this.#rotateDw(true);
208
225
  this.MOVES.push("Dw");
@@ -226,6 +243,7 @@ class CubeEngine {
226
243
  * Rotates the wide (UPPER two layers) clockwise or counterclockwise.
227
244
  */
228
245
  rotateUw(clockwise = true) {
246
+ if (this.size === 2) return;
229
247
  if (clockwise) {
230
248
  this.#rotateUw(true);
231
249
  this.MOVES.push("Uw");
@@ -249,6 +267,7 @@ class CubeEngine {
249
267
  * Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
250
268
  */
251
269
  rotateRw(clockwise = true) {
270
+ if (this.size === 2) return;
252
271
  if (clockwise) {
253
272
  this.#rotateRw(true);
254
273
  this.MOVES.push("Rw");
@@ -272,6 +291,7 @@ class CubeEngine {
272
291
  * Rotates the wide (LEFT two layers) clockwise or counterclockwise.
273
292
  */
274
293
  rotateLw(clockwise = true) {
294
+ if (this.size === 2) return;
275
295
  if (clockwise) {
276
296
  this.#rotateLw(true);
277
297
  this.MOVES.push("Lw");
@@ -296,6 +316,7 @@ class CubeEngine {
296
316
  * Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
297
317
  */
298
318
  rotateM(clockwise = true) {
319
+ if (this.size === 2) return;
299
320
  if (clockwise) {
300
321
  this.#rotateM(true);
301
322
  this.MOVES.push("M");
@@ -447,21 +468,42 @@ class CubeEngine {
447
468
  */
448
469
  #switchMatrix(matrix, clockwise = true) {
449
470
  const clone = structuredClone(matrix);
471
+ const size = this.size;
450
472
 
451
- 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
+ }
452
478
 
453
- if (clockwise) {
454
- return [
455
- [tempMatrix[6], tempMatrix[3], tempMatrix[0]],
456
- [tempMatrix[7], tempMatrix[4], tempMatrix[1]],
457
- [tempMatrix[8], tempMatrix[5], tempMatrix[2]],
458
- ];
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
+ }
459
492
  } else {
460
- return [
461
- [tempMatrix[2], tempMatrix[5], tempMatrix[8]],
462
- [tempMatrix[1], tempMatrix[4], tempMatrix[7]],
463
- [tempMatrix[0], tempMatrix[3], tempMatrix[6]],
464
- ];
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
+ }
465
507
  }
466
508
  }
467
509
 
@@ -489,13 +531,15 @@ class CubeEngine {
489
531
  };
490
532
 
491
533
  const layersSolved = Object.keys(temp).map((layer) => {
492
- const mixedMatrix = [
493
- ...temp[layer][0],
494
- ...temp[layer][1],
495
- ...temp[layer][2],
496
- ];
497
534
 
498
- 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];
499
543
 
500
544
  return mixedMatrix.every((currentColor) => currentColor === centerColor);
501
545
  });
@@ -517,38 +561,7 @@ class CubeEngine {
517
561
  * Resets the cube to the solved state and clears the move history.
518
562
  */
519
563
  reset() {
520
- this.STATES = {
521
- UPPER: [
522
- [COLOR.W[0], COLOR.W[1], COLOR.W[2]],
523
- [COLOR.W[3], COLOR.W[4], COLOR.W[5]],
524
- [COLOR.W[6], COLOR.W[7], COLOR.W[8]],
525
- ],
526
- LEFT: [
527
- [COLOR.O[0], COLOR.O[1], COLOR.O[2]],
528
- [COLOR.O[3], COLOR.O[4], COLOR.O[5]],
529
- [COLOR.O[6], COLOR.O[7], COLOR.O[8]],
530
- ],
531
- FRONT: [
532
- [COLOR.G[0], COLOR.G[1], COLOR.G[2]],
533
- [COLOR.G[3], COLOR.G[4], COLOR.G[5]],
534
- [COLOR.G[6], COLOR.G[7], COLOR.G[8]],
535
- ],
536
- RIGHT: [
537
- [COLOR.R[0], COLOR.R[1], COLOR.R[2]],
538
- [COLOR.R[3], COLOR.R[4], COLOR.R[5]],
539
- [COLOR.R[6], COLOR.R[7], COLOR.R[8]],
540
- ],
541
- BACK: [
542
- [COLOR.B[0], COLOR.B[1], COLOR.B[2]],
543
- [COLOR.B[3], COLOR.B[4], COLOR.B[5]],
544
- [COLOR.B[6], COLOR.B[7], COLOR.B[8]],
545
- ],
546
- DOWN: [
547
- [COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
548
- [COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
549
- [COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]],
550
- ],
551
- };
564
+ this.#initializeState();
552
565
  this.MOVES = [];
553
566
  }
554
567
 
@@ -579,7 +592,6 @@ class CubeEngine {
579
592
 
580
593
  const exec = (fnClockwise, fnCounter) => {
581
594
  if (isDouble) {
582
- // Double turns ignore prime; do two clockwise quarter-turns
583
595
  fnClockwise();
584
596
  fnClockwise();
585
597
  } else {
@@ -662,6 +674,12 @@ class CubeEngine {
662
674
  () => (record ? this.rotateF(false) : this.#rotateF(false))
663
675
  );
664
676
  break;
677
+ case 'B':
678
+ exec(
679
+ () => (record ? this.rotateB(true) : this.#rotateB(true)),
680
+ () => (record ? this.rotateB(false) : this.#rotateB(false))
681
+ );
682
+ break;
665
683
  case 'x':
666
684
  exec(
667
685
  () => (record ? this.rotateX(true) : this.#rotateX(true)),