Scrambling#
Two different things in this app are called a scramble, and they are generated differently.
- Full scramble
- Randomises the whole cube, for the timer. Any state, no structure.
- Case scramble
- Puts the cube into one specific case, for a drill. The rest of the cube is solved (or, for F2L, solved apart from the target slot).
Full scrambles#
The generator is the straightforward random-move one described in the project brief, with the standard anti-cancellation rules:
- Start from a solved cube.
- Emit
scrambler.base_twistsrandom face turns — 18 by default. - Emit between 0 and
scrambler.extra_twists_maxfurther turns — up to 6 more — so the length varies between 18 and 24. - Never place a move on the same face as the previous move
(
forbid_same_face_repeat): noRafterR', because the two would partially cancel and the scramble would be shorter than it looks. - Never place
A B Aon parallel faces (forbid_parallel_sandwich): noR L R, becauseLcommutes withRand the sequence reduces to two moves.
Each move gets a random modifier: clockwise, counter-clockwise (') or a half
turn (2).
Only the six face turns U D L R F B appear. No wide moves, no slices, no
rotations — that is what every scrambler does and what every timer expects.
Random-move, not random-state
A WCA competition scrambler generates a random state and then finds a short sequence that reaches it, which gives a uniform distribution over all 43 quintillion positions in about 20 moves. This app uses random moves, which is what the brief specified and what almost every practice timer does by default. The practical difference at 18–24 moves is small enough not to matter for training, and the generator carries no solver dependency.
csTimer compatibility#
Scrambles are emitted in the notation csTimer reads: single-space separated,
uppercase faces, ' for counter-clockwise and 2 for half turns.
D2 F' L2 B U R2 F' D B2 R L' U2 F R2 D' B' U L2 F2 D
Copy any scramble with the copy button, paste it into csTimer under scramble → enter your own, and you get the same state. This works both ways: a scramble from csTimer or from a competition pastes into this app's viewer.
Determinism#
Every generator in the app takes an optional seed. Given the same seed you get the same scramble, which is what makes the test suite meaningful and what lets a drill session be reproduced exactly. Sessions store the scramble they gave you, so you never depend on the seed to get your history back.
Case scrambles#
A drill on OLL 21 needs a cube that is OLL 21 — not a random cube.
A case scramble is the case's stored setup_moves — the sequence that takes a
solved cube into the case — and nothing else. The same case always scrambles
the same way, on the case page, in a drill and in a plan, and the string you
are shown is the one in the database.
That is deliberate. The generator can append a random AUF (U, U', U2)
to vary the angle the last layer arrives at, and a random y rotation to
vary which side you meet it from, but both are off. Turning either on makes the
scramble differ from the case's setup moves for a reason nothing on the page
explains, and it puts the cube in a state the case's own algorithm does not
solve from — so the scramble and the 3D aid stop agreeing.
If you want to practise recognising a case from another angle, turn the top layer yourself before you start. That is the same drill, under your control.
The API still exposes both as query parameters —
?auf=1 and ?rotation=1 on the case-scramble endpoint — for anyone building
something that wants them.
Verifying a case scramble#
Case setups are validated, not trusted. At import time the app applies
setup_moves and then the primary algorithm to a solved cube, and checks that
the result is the phase's target state:
| Phase | Target state after setup + algorithm |
|---|---|
| OLL | Fully solved |
| PLL | Fully solved |
| F2L | The target slot solved, the last layer untouched |
A case that fails is treated as a bug in the data file. See Contributing.
Quick return#
Every case page and every drill rep offers quick return: the inverse of the algorithm you just performed, so you can undo the case on a physical cube and be back at the case's starting position without re-scrambling.
The inverse is computed, not stored — the sequence is reversed and every move
is negated (R ↔ R', R2 stays R2). For a 3-second alg that saves you the
25 seconds of re-scrambling, which over a 15-rep session is most of the
session.
Configuring the scrambler#
Everything above is driven by four keys in config.yml:
scrambler:
base_twists: 18
extra_twists_max: 6
forbid_same_face_repeat: true
forbid_parallel_sandwich: true
See Configuration for the full table.