UNPKG

rubik-cipher

Version:

Simple rubik cube cipher

263 lines 9.65 kB
"use strict"; const Cube = require('bedard-cube'); const rubikHelpers_1 = require("./helpers/rubikHelpers"); var FillAlpabet; (function (FillAlpabet) { FillAlpabet["default"] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; FillAlpabet["czech"] = "a\u00E1bc\u010Dd\u010Fe\u00E9\u011Bfghi\u00EDjklmn\u0148o\u00F3pqr\u0159s\u0161t\u0165u\u00FA\u016Fvwxy\u00FDz\u017EA\u00C1BC\u010CD\u010EE\u00C9\u011AFGHI\u00CDJKLMN\u0147O\u00D3PQR\u0158S\u0160T\u0164U\u00DA\u016EVWXY\u00DDZ\u017D0123456789"; })(FillAlpabet || (FillAlpabet = {})); class RubikCipher { constructor(text, config) { this.text = ''; this.cube = undefined; this.currentScramble = []; this.size = 2; this.groupSize = 1; this.fillRest = true; this.fillWithRandom = false; this.fillAlphabet = FillAlpabet.default; if (text === '') { throw new Error('Text cannot be empty'); } this.text = text; if (config) { if (typeof config === 'string') { this.setupFromKey(config); } else { if (typeof config.cubeSize !== 'undefined') { if (config.cubeSize < 2) { throw new Error('Cube size must be larger than 2'); } if (!rubikHelpers_1.canFitInCube(this.text, config.cubeSize)) { throw new Error(`Text of length ${this.text.length} cant fit in cube with size ${config.cubeSize}`); } this.size = config.cubeSize; } else { this.size = rubikHelpers_1.minimalSizeByText(text); } if (typeof config.groupSize !== 'undefined') { if (config.groupSize < 1) { throw new Error('Group size must be larger than 0'); } this.groupSize = config.groupSize; } else { this.groupSize = 1; } if (typeof config.fillRest !== 'undefined') { this.fillRest = config.fillRest; } else { this.fillRest = true; } if (typeof config.fillWithRandom !== 'undefined') { this.fillWithRandom = config.fillWithRandom; } else { this.fillWithRandom = false; } this.reset(); } } else { this.size = rubikHelpers_1.minimalSizeByText(text); this.reset(); } } setupFromKey(key) { const { combinationText, config } = this.getKeyParts(key); this.size = config.cubeSize; this.groupSize = config.groupSize; this.fillRest = config.fillRest; this.fillWithRandom = config.fillWithRandom; this.reset(); this.applyReverseCombination(this.combinationTextToObject(combinationText)); } isValidKey(key) { if (!(/^[^+](\+{0,1}[- a-zA-Z0-9]+)+[^+]$/.test(key))) { return false; } const keyParts = key.split('+'); if (keyParts.length !== 5) { return false; } const cubeSize = Number(keyParts[0]); const groupSize = Number(keyParts[1]); if (cubeSize < 2) { return false; } if (groupSize < 1) { return false; } if (!rubikHelpers_1.canFitInCube(this.text, cubeSize)) { return false; } return true; } getKeyParts(key) { if (this.isValidKey(key)) { const keyParts = key.split('+'); return { config: { cubeSize: Number(keyParts[0]), groupSize: Number(keyParts[1]), fillRest: (keyParts[2] === '1'), fillWithRandom: (keyParts[3] === '1'), }, combinationText: keyParts[4], }; } throw new Error('Key is invalid'); } combinationTextToObject(combination) { return combination.split(' ').map(rubikHelpers_1.decodeScramble); } applyReverseCombination(combination) { this.turn(rubikHelpers_1.getInverseCombination(combination)); } /** * Function for cube scrambling * @param {number} count How many times you want to scramble */ scramble(count = 0) { this.reset(); const newScramble = this.cube.generateScramble(count); this.currentScramble = newScramble; this.cube.turn(this.currentScramble); } /** * Function for additional cube scrambling * @param {number} count How many times you want to scramble */ addScramble(count = 0) { const newScramble = this.cube.generateScramble(count); this.currentScramble = this.currentScramble.concat(newScramble); this.cube.turn(this.currentScramble); } /** * Function to manually turn the cube * @param {string | Array<ScrambleObject>} turnKey selected sequence of turns */ turn(turnKey) { const newScramble = []; if (typeof turnKey === 'string') { const turnKeys = turnKey.split(' ').map(rubikHelpers_1.decodeScramble); newScramble.push(...turnKeys); } else { newScramble.push(...turnKey); } this.currentScramble = this.currentScramble.concat(newScramble); this.cube.turn(newScramble); } /** * Reset the cube or create new one when cube is undefined */ reset() { if (typeof this.cube !== 'undefined') { this.cube.reset(); } else { this.cube = new Cube(this.size, { useObjects: true }); } } /** * Getter for current cube Combination string * @returns {string} */ get Combination() { return this.currentScramble.map(rubikHelpers_1.encodeScramble).join(' '); } get InverseCombination() { if (this.currentScramble.length > 0) { return rubikHelpers_1.getInverseCombination(this.currentScramble); } return []; } /** * Getter for current text from cube stickers * @returns {string} */ get Text() { const cubeIndexes = rubikHelpers_1.getAllIndexes(this.cube, this.size); const textSplit = this.text.split(''); const alphabetSplit = this.fillAlphabet.split(''); let returnString = ''; if (this.groupSize > 1) { const groups = rubikHelpers_1.chunkString(this.text, this.groupSize); if (groups[groups.length - 1].length < this.groupSize) { while (groups[groups.length - 1].length < this.groupSize) { if (this.fillRest) { if (this.fillWithRandom) { groups[groups.length - 1] += alphabetSplit[Math.floor(Math.random() * alphabetSplit.length)]; } else { groups[groups.length - 1] += 'x'; } } else { break; } } } while (groups.length < this.CubeTileCount) { let textGroup = ''; for (let i = 0; i < this.groupSize; i++) { if (this.fillRest) { if (this.fillWithRandom) { textGroup += alphabetSplit[Math.floor(Math.random() * alphabetSplit.length)]; } else { textGroup += 'x'; } } else { continue; } } groups.push(textGroup); } const mappedString = cubeIndexes.map(i => groups[i]); returnString = mappedString.join(''); } else { const mappedString = cubeIndexes.map((i) => { if (textSplit[i] !== undefined) { return textSplit[i]; } if (this.fillRest) { if (this.fillWithRandom) { return alphabetSplit[Math.floor(Math.random() * alphabetSplit.length)]; } return 'x'; } return ''; }); returnString = mappedString.join(''); } return returnString; } get Indexes() { return rubikHelpers_1.getAllIndexes(this.cube, this.size); } /** * Gets current cube key in format size+groupSize+fillRest(0 or 1)+fillRandom(0 or 1)+combination * @returns {string} key */ get Key() { return [ this.size, this.groupSize, (this.fillRest ? 1 : 0), (this.fillWithRandom ? 1 : 0), this.Combination, ].join('+'); } get CubeTileCount() { return 6 * (this.size ** 2); } } module.exports = RubikCipher; //# sourceMappingURL=RubikCipher.js.map