I am making my own android application that can help solve rubiks cube. I bought Xiaomi's Giiker Cube and have looked into the Herbert Kociemba's Two phase Algorithm.
So the problem starts here. For Giiker Cube I looked into below api. But this api gives the state of the cube which is 20 bytes of data. https://github.com/Vexu/SuperCube-API
I also looked into below React library of the same and its dependent libraries from here to look into conversion of that state to cube faces and moves. But that library's decode logic is not working for me.
Also I am not using react native. https://www.npmjs.com/package/react-native-giiker
I need help in translation of cube state of 20 bytes to cube faces for Herbert Kociemba's algo and moves
I have the new Giiker cube i3s which have encrypted state. This was not the case with Giiker cube i3.
The logic to decode the encrypted state can be found here.
https://github.com/kabelbinder/giiker/blob/50db5d58e0417749fe5815e72856b90a1afa43b1/index.js#L326
Below is the logic for decryption and parsing as well.
const turns = {
0: 1,
1: 2,
2: -1,
8: -2,
};
const faces = ['B', 'D', 'L', 'U', 'R', 'F'];
_parseCubeValue (value) {
const state = {
cornerPositions: [],
cornerOrientations: [],
edgePositions: [],
edgeOrientations: []
};
const moves = [];
if (value.getUint8(18) == 0xa7) { // decrypt
var key = [176, 81, 104, 224, 86, 137, 237, 119, 38, 26, 193, 161, 210, 126, 150, 81, 93, 13, 236, 249, 89, 235, 88, 24, 113, 81, 214, 131, 130, 199, 2, 169, 39, 165, 171, 41];
var k = value.getUint8(19);
var k1 = k >> 4 & 0xf;
var k2 = k & 0xf;
for (let i = 0; i < value.byteLength; i++) {
const move = (value.getUint8(i) + key[i + k1] + key[i + k2]) & 0xff;
const highNibble = move >> 4;
const lowNibble = move & 0b1111;
if (i < 4) {
state.cornerPositions.push(highNibble, lowNibble);
} else if (i < 8) {
state.cornerOrientations.push(highNibble, lowNibble);
} else if (i < 14) {
state.edgePositions.push(highNibble, lowNibble);
} else if (i < 16) {
state.edgeOrientations.push(!!(move & 0b10000000));
state.edgeOrientations.push(!!(move & 0b01000000));
state.edgeOrientations.push(!!(move & 0b00100000));
state.edgeOrientations.push(!!(move & 0b00010000));
if (i === 14) {
state.edgeOrientations.push(!!(move & 0b00001000));
state.edgeOrientations.push(!!(move & 0b00000100));
state.edgeOrientations.push(!!(move & 0b00000010));
state.edgeOrientations.push(!!(move & 0b00000001));
}
} else {
moves.push(this._parseMove(highNibble, lowNibble));
}
}
}
else { // not encrypted
for (let i = 0; i < value.byteLength; i++) {
const move = value.getUint8(i)
const highNibble = move >> 4;
const lowNibble = move & 0b1111;
if (i < 4) {
state.cornerPositions.push(highNibble, lowNibble);
} else if (i < 8) {
state.cornerOrientations.push(highNibble, lowNibble);
} else if (i < 14) {
state.edgePositions.push(highNibble, lowNibble);
} else if (i < 16) {
state.edgeOrientations.push(!!(move & 0b10000000));
state.edgeOrientations.push(!!(move & 0b01000000));
state.edgeOrientations.push(!!(move & 0b00100000));
state.edgeOrientations.push(!!(move & 0b00010000));
if (i === 14) {
state.edgeOrientations.push(!!(move & 0b00001000));
state.edgeOrientations.push(!!(move & 0b00000100));
state.edgeOrientations.push(!!(move & 0b00000010));
state.edgeOrientations.push(!!(move & 0b00000001));
}
} else {
moves.push(this._parseMove(highNibble, lowNibble));
}
}
}
return {state, moves};
}
_parseMove (faceIndex, turnIndex) {
const face = faces[faceIndex - 1];
const amount = turns[turnIndex - 1];
let notation = face;
switch (amount) {
case 2: notation = `${face}2`; break;
case -1: notation = `${face}'`; break;
case -2: notation = `${face}2'`; break;
}
return {face, amount, notation};
}