π Problem Statement
CubeIt generates WCA-compliant scrambles to animate the 3D cube visualizer. WCA regulations (Article 4b) require that scrambles be randomly generated but also non-trivial β specifically:
- No two consecutive moves on the same face (e.g.,
R R is redundant β equivalent to R2)
- No two consecutive moves on opposite faces in the same axis that could merge (e.g.,
R L R is reducible)
- Scrambles must be effectively 20 moves of genuine state change
A naive random generator using Math.random() to pick from ['R', 'L', 'U', 'D', 'F', 'B'] + modifiers ['', "'", '2'] can produce:
R R' U2 U D D' F ...
Here R R' cancels to identity, U2 U reduces to U', D D' cancels β producing a scramble that's far shorter than 20 moves of actual state change. The 3D visualizer would then show incorrect scramble states.
π‘ Proposed Fix
Add same-face and opposite-face filtering to the scramble generator:
// src/utils/scrambleGenerator.js
const FACES = ['U', 'D', 'R', 'L', 'F', 'B'];
const MODIFIERS = ['', "'", '2'];
const OPPOSITE_FACES = { U: 'D', D: 'U', R: 'L', L: 'R', F: 'B', B: 'F' };
export function generateScramble(length = 20) {
const moves = [];
let lastFace = null;
let secondLastFace = null;
while (moves.length < length) {
// Filter: exclude same face and opposite face (if second-last was also on that axis)
const availableFaces = FACES.filter(face => {
if (face === lastFace) return false; // No same-face repeat
// Avoid reducible three-move sequences: if last two were on same axis, skip opposite
if (
lastFace &&
secondLastFace &&
OPPOSITE_FACES[face] === lastFace &&
OPPOSITE_FACES[face] === secondLastFace
) return false;
return true;
});
const face = availableFaces[Math.floor(Math.random() * availableFaces.length)];
const modifier = MODIFIERS[Math.floor(Math.random() * MODIFIERS.length)];
moves.push(face + modifier);
secondLastFace = lastFace;
lastFace = face;
}
return moves.join(' ');
}
Add a unit test suite for the scramble generator:
// src/utils/scrambleGenerator.test.js
test('no consecutive same-face moves', () => {
for (let i = 0; i < 1000; i++) {
const scramble = generateScramble(20);
const moves = scramble.split(' ');
for (let j = 1; j < moves.length; j++) {
const prevFace = moves[j - 1][0];
const currFace = moves[j][0];
expect(currFace).not.toBe(prevFace);
}
}
});
π Files to Modify
| File |
Change |
src/utils/scrambleGenerator.js |
Add face-filtering logic to generator |
src/utils/scrambleGenerator.test.js |
New β unit tests for scramble validity |
package.json |
Ensure Jest or Vitest test runner is configured |
Suggested labels: bug, scramble-generator, wca-compliance
I would like to work on this. Could you please assign it to me?
π Problem Statement
CubeIt generates WCA-compliant scrambles to animate the 3D cube visualizer. WCA regulations (Article 4b) require that scrambles be randomly generated but also non-trivial β specifically:
R Ris redundant β equivalent toR2)R L Ris reducible)A naive random generator using
Math.random()to pick from['R', 'L', 'U', 'D', 'F', 'B']+ modifiers['', "'", '2']can produce:R R' U2 U D D' F ...
Here
R R'cancels to identity,U2 Ureduces toU',D D'cancels β producing a scramble that's far shorter than 20 moves of actual state change. The 3D visualizer would then show incorrect scramble states.π‘ Proposed Fix
Add same-face and opposite-face filtering to the scramble generator:
Add a unit test suite for the scramble generator:
π Files to Modify
src/utils/scrambleGenerator.jssrc/utils/scrambleGenerator.test.jspackage.jsonSuggested labels:
bug,scramble-generator,wca-complianceI would like to work on this. Could you please assign it to me?