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:

  1. Start from a solved cube.
  2. Emit scrambler.base_twists random face turns — 18 by default.
  3. Emit between 0 and scrambler.extra_twists_max further turns — up to 6 more — so the length varies between 18 and 24.
  4. Never place a move on the same face as the previous move (forbid_same_face_repeat): no R after R', because the two would partially cancel and the scramble would be shorter than it looks.
  5. Never place A B A on parallel faces (forbid_parallel_sandwich): no R L R, because L commutes with R and 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.

The naive approach is to apply the case's inverse algorithm and call it done, but that produces the same cube every single time, and you end up training on a fixed position rather than on the case. So the generator does this instead:

  1. Start from the case's stored setup_moves — the sequence that takes a solved cube into the case.
  2. Prefix a random AUF (U, U', U2 or nothing), so the last layer arrives at a different angle each rep.
  3. Where it does not destroy recognition, prefix a random cube rotation (y, y', y2), so you have to find the case rather than expect it in a fixed place.

Whether a rotation is safe depends on the case. For OLL, any y rotation is fine — orientation is rotation-independent. For PLL, a y changes which permutation you are looking at relative to the front face, so the generator adds the rotation and then adjusts. For F2L, the slot matters, so the rotation is what selects which of the four slot angles you get — which is exactly why the 41 F2L cases cover all four angles rather than being 164 separate cases.

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 (RR', 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.

Source: docs/user/scrambling.md