Giiker立方体api。从状态配置
Giiker cube api. Configuration from State
我正在制作自己的 android 应用程序,可以帮助解决魔方问题。
我买了小米的 Giiker Cube,研究了 Herbert Kociemba 的两相算法。
那么问题就从这里开始了。
对于 Giiker Cube,我在下面查看 api。但是这个 api 给出了立方体的状态,即 20 字节的数据。
https://github.com/Vexu/SuperCube-API
我还从此处查看了相同的 React 库及其依赖库,以研究该状态到立方体面和移动的转换。但是那个库的解码逻辑对我不起作用。
我也没有使用 React Native。
https://www.npmjs.com/package/react-native-giiker
我需要帮助将 20 字节的立方体状态转换为 Herbert Kociemba 的算法和移动的立方体面
我有新的 Giiker cube i3s,它有加密状态。 Giiker cube i3 不是这种情况。
可以在此处找到解码加密状态的逻辑。
https://github.com/kabelbinder/giiker/blob/50db5d58e0417749fe5815e72856b90a1afa43b1/index.js#L326
下面是解密和解析的逻辑
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};
}
我正在制作自己的 android 应用程序,可以帮助解决魔方问题。 我买了小米的 Giiker Cube,研究了 Herbert Kociemba 的两相算法。
那么问题就从这里开始了。 对于 Giiker Cube,我在下面查看 api。但是这个 api 给出了立方体的状态,即 20 字节的数据。 https://github.com/Vexu/SuperCube-API
我还从此处查看了相同的 React 库及其依赖库,以研究该状态到立方体面和移动的转换。但是那个库的解码逻辑对我不起作用。
我也没有使用 React Native。 https://www.npmjs.com/package/react-native-giiker
我需要帮助将 20 字节的立方体状态转换为 Herbert Kociemba 的算法和移动的立方体面
我有新的 Giiker cube i3s,它有加密状态。 Giiker cube i3 不是这种情况。
可以在此处找到解码加密状态的逻辑。
https://github.com/kabelbinder/giiker/blob/50db5d58e0417749fe5815e72856b90a1afa43b1/index.js#L326
下面是解密和解析的逻辑
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};
}