cube-state-engine
Version:
An efficient representation in memory for tracking the Rubik's cube state on each movement.
365 lines (363 loc) • 14.8 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
// src/index.js
var src_exports = {};
__export(src_exports, {
COLOR: () => COLOR,
CubeEngine: () => CubeEngine
});
module.exports = __toCommonJS(src_exports);
var _CubeEngine_instances, rotateU_fn, rotateF_fn, rotateR_fn, rotateL_fn, rotateD_fn, rotateX_fn, rotateY_fn, switchMatrix_fn, specialFlip_fn;
var CubeEngine = class {
constructor() {
__privateAdd(this, _CubeEngine_instances);
__publicField(this, "MOVES", []);
// States object for the rotation
__publicField(this, "STATES", {
UPPER: [
// (White)
[COLOR.W[0], COLOR.W[1], COLOR.W[2]],
[COLOR.W[3], COLOR.W[4], COLOR.W[5]],
[COLOR.W[6], COLOR.W[7], COLOR.W[8]]
],
LEFT: [
// (Orange)
[COLOR.O[0], COLOR.O[1], COLOR.O[2]],
[COLOR.O[3], COLOR.O[4], COLOR.O[5]],
[COLOR.O[6], COLOR.O[7], COLOR.O[8]]
],
FRONT: [
// (Green)
[COLOR.G[0], COLOR.G[1], COLOR.G[2]],
[COLOR.G[3], COLOR.G[4], COLOR.G[5]],
[COLOR.G[6], COLOR.G[7], COLOR.G[8]]
],
RIGHT: [
// (Red)
[COLOR.R[0], COLOR.R[1], COLOR.R[2]],
[COLOR.R[3], COLOR.R[4], COLOR.R[5]],
[COLOR.R[6], COLOR.R[7], COLOR.R[8]]
],
BACK: [
// (Blue)
[COLOR.B[0], COLOR.B[1], COLOR.B[2]],
[COLOR.B[3], COLOR.B[4], COLOR.B[5]],
[COLOR.B[6], COLOR.B[7], COLOR.B[8]]
],
DOWN: [
// (Yellow)
[COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
[COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
[COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
]
});
}
/**
* Rotates the (UPPER) layer clockwise or counterclockwise.
*/
rotateU(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
this.MOVES.push("U");
} else {
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
this.MOVES.push("U'");
}
}
/**
* Rotates the (FRONT) layer clockwise or counterclockwise.
*/
rotateF(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true);
this.MOVES.push("F");
} else {
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false);
this.MOVES.push("F'");
}
}
/**
* Rotates the (RIGHT) layer clockwise or counterclockwise.
*/
rotateR(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, true);
this.MOVES.push("R");
} else {
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, false);
this.MOVES.push("R'");
}
}
/**
* Rotates the (LEFT) layer clockwise or counterclockwise.
*/
rotateL(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, true);
this.MOVES.push("L");
} else {
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, false);
this.MOVES.push("L'");
}
}
/**
* Rotates the (DOWN) layer clockwise or counterclockwise.
*/
rotateD(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, true);
this.MOVES.push("D");
} else {
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, false);
this.MOVES.push("D'");
}
}
/**
* Rotates the (x) axis clockwise or counterclockwise.
*/
rotateX(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
this.MOVES.push("x");
} else {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
this.MOVES.push("x'");
}
}
/**
* Rotates the (y) axis clockwise or counterclockwise.
*/
rotateY(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
this.MOVES.push("y");
} else {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
this.MOVES.push("y'");
}
}
/**
* Logs the current state of the cube.
*/
state() {
return __spreadValues({}, this.STATES);
}
/**
* Indicates if the cube is solve or not in all layers.
*/
isSolved() {
const temp = __spreadValues({}, this.STATES);
const layersSolved = Object.keys(temp).map((layer) => {
const mixedMatrix = [
...temp[layer][0],
...temp[layer][1],
...temp[layer][2]
];
const centerColor = mixedMatrix[4];
return mixedMatrix.every((currentColor) => currentColor === centerColor);
});
return layersSolved.every((isLayerSolved) => isLayerSolved);
}
/**
* Returns the history of all movements made.
*
* @param {boolean} asString - If true, returns the history as a string; otherwise, returns it as an array.
* @returns {string|array} The history of movements as an array or string.
*/
getMoves(asString = true) {
return asString ? this.MOVES.join(" ") : this.MOVES;
}
};
_CubeEngine_instances = new WeakSet();
rotateU_fn = function(clockwise = true) {
if (clockwise) {
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, true);
const tempFront = [...this.STATES.FRONT[0]];
const tempRight = [...this.STATES.RIGHT[0]];
const tempLeft = [...this.STATES.LEFT[0]];
const tempBack = [...this.STATES.BACK[0]];
this.STATES.FRONT[0] = [...tempRight];
this.STATES.LEFT[0] = [...tempFront];
this.STATES.BACK[0] = [...tempLeft];
this.STATES.RIGHT[0] = [...tempBack];
} else {
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, false);
const tempFront = [...this.STATES.FRONT[0]];
const tempRight = [...this.STATES.RIGHT[0]];
const tempLeft = [...this.STATES.LEFT[0]];
const tempBack = [...this.STATES.BACK[0]];
this.STATES.FRONT[0] = [...tempLeft];
this.STATES.LEFT[0] = [...tempBack];
this.STATES.BACK[0] = [...tempRight];
this.STATES.RIGHT[0] = [...tempFront];
}
};
rotateF_fn = function(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
} else {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
}
};
rotateR_fn = function(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
} else {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
}
};
rotateL_fn = function(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
} else {
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
}
};
rotateD_fn = function(clockwise = true) {
if (clockwise) {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
} else {
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false);
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
}
};
rotateX_fn = function(clockwise = true) {
const tempFront = structuredClone(this.STATES.FRONT);
const tempDown = structuredClone(this.STATES.DOWN);
const tempUpper = structuredClone(this.STATES.UPPER);
const tempBack = structuredClone(this.STATES.BACK);
const tempLeft = structuredClone(this.STATES.LEFT);
const tempRight = structuredClone(this.STATES.RIGHT);
if (clockwise) {
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, false);
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, true);
this.STATES.FRONT = [...tempDown];
this.STATES.UPPER = [...tempFront];
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempUpper);
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempBack);
} else {
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, true);
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, false);
this.STATES.FRONT = [...tempUpper];
this.STATES.DOWN = [...tempFront];
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempDown);
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempBack);
}
};
rotateY_fn = function(clockwise = true) {
const tempFront = structuredClone(this.STATES.FRONT);
const tempRight = structuredClone(this.STATES.RIGHT);
const tempBack = structuredClone(this.STATES.BACK);
const tempLeft = structuredClone(this.STATES.LEFT);
if (clockwise) {
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, true);
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.DOWN, false);
this.STATES.FRONT = [...tempRight];
this.STATES.RIGHT = [...tempBack];
this.STATES.LEFT = [...tempFront];
this.STATES.BACK = [...tempLeft];
} else {
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, false);
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.DOWN, true);
this.STATES.FRONT = [...tempLeft];
this.STATES.RIGHT = [...tempFront];
this.STATES.LEFT = [...tempBack];
this.STATES.BACK = [...tempRight];
}
};
/**
* Rotate the entire face in the direction set
*/
switchMatrix_fn = function(matrix, clockwise = true) {
const clone = structuredClone(matrix);
const tempMatrix = [...clone[0], ...clone[1], ...clone[2]];
if (clockwise) {
return [
[tempMatrix[6], tempMatrix[3], tempMatrix[0]],
[tempMatrix[7], tempMatrix[4], tempMatrix[1]],
[tempMatrix[8], tempMatrix[5], tempMatrix[2]]
];
} else {
return [
[tempMatrix[2], tempMatrix[5], tempMatrix[8]],
[tempMatrix[1], tempMatrix[4], tempMatrix[7]],
[tempMatrix[0], tempMatrix[3], tempMatrix[6]]
];
}
};
specialFlip_fn = function(matrix) {
return structuredClone(matrix).reverse().map((row) => [...row].reverse());
};
var COLOR = {
W: ["W", "W", "W", "W", "W", "W", "W", "W", "W"],
G: ["G", "G", "G", "G", "G", "G", "G", "G", "G"],
R: ["R", "R", "R", "R", "R", "R", "R", "R", "R"],
B: ["B", "B", "B", "B", "B", "B", "B", "B", "B"],
O: ["O", "O", "O", "O", "O", "O", "O", "O", "O"],
Y: ["Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y"]
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
COLOR,
CubeEngine
});