programextensions/scene/demos/voxels-rubik.xtl
Voxels, 8: a Rubik's cube. 26 dark cubies with their colored stickers, drawn as voxels; the cube itself is arrays (Rubik.xtl): its 54 stickers, each where it is and which way it faces, and each of the twelve quarter turns a permutation of them, computed from the cube's geometry. This demo checks the turns -- each a permutation, four of one solved, a turn and its undoing solved, R U R' U' of order 6, R U of order 105, and U and R turning the right way -- and shows the solved cube, turning slowly; keys turn its faces. Run: just demo scene voxels-rubik u d r l f b turn a face clockwise (as you look at it), Shift with the letter counterclockwise, z undo (back to solved), Space a scramble (25 random turns), 0 reset, drag to look around, q quit
The turns, checked
The cube, drawn
k : Int
k ← w ˢᶜc̲amera! 0.6 0.45 7.5 0.3
ᵘd̲raw : Int -> Int
the stickers, one object of quads for each color
ᵘd̲raw ← { c → sent ← '{ ((f̲loat w) c̲at (10.0 + f̲loat ⍵) c̲at (⍵ + 1) s̲elect ʳᵇrgb) ˢᶜq̲uads! ⍵ ʳᵇc̲olorSquares c } m̲ap (r̲ange 6) − 1 c }
Turning it
ᵘt̲ell : (Any a, Any b) => a -> b -> b
m u:t_ell st: m printed, the state unchanged
ᵘt̲ell ← { m st → said ← p̲rint! m st }
ᵘs̲ay : Int -> Int
the turns made, by name (and whether the cube is solved)
ᵘs̲ay ← { st → h ← 54 d̲rop st 0 = t̲ally h ? "solved, no turns" ᵘt̲ell st names ← (n̲ot ʳᵇnames = f̲irst " ") p̲artition ʳᵇnames said ← p̲rint! "turns: " c̲at d̲isclose '{ e̲nclose (d̲isclose ⍺) c̲at " " c̲at d̲isclose ⍵ } r̲/ h s̲elect names ((54 t̲ake st) m̲atch ʳᵇsolved) ? "solved" ᵘt̲ell st st }
ᵘt̲urnBy : Int -> Int -> Int
i u:t_urnBy st: turn i made and remembered, the cube redrawn
ᵘt̲urnBy ← { i st → c ← i ʳᵇt̲urn 54 t̲ake st shown ← ᵘd̲raw c c c̲at (54 d̲rop st) c̲at i }
ᵘu̲ndoLast : Int -> Int
the last turn undone and forgotten
ᵘu̲ndoLast ← { st → 54 = t̲ally st ? st i ← f̲irst -1 t̲ake st c ← (ʳᵇu̲ndo i) ʳᵇt̲urn 54 t̲ake st shown ← ᵘd̲raw c c c̲at 54 d̲rop -1 d̲rop st }
ᵘo̲ne : Int -> Int
25 random turns, never the same face twice in a row (so none undoes or repeats the one before), remembered (so undo can walk back to solved)
ᵘo̲ne ← { st → i ← r̲oll! 12 prev ← (55 ≤ t̲ally st) × f̲irst -1 t̲ake st ((i + 1) d̲iv 2) = (prev + 1) d̲iv 2 ? ᵘo̲ne st c ← i ʳᵇt̲urn 54 t̲ake st c c̲at (54 d̲rop st) c̲at i }
ᵘs̲cramble : Int -> Int
ᵘs̲cramble ← { st → st ← 25 'ᵘo̲ne p̲ower st shown ← ᵘd̲raw 54 t̲ake st st }
ᵘr̲eset : Any a => a -> Int
back to solved, no history
ᵘr̲eset ← { st → shown ← ᵘd̲raw ʳᵇsolved ʳᵇsolved }
ᵘf̲rame : Int -> Int
one frame: an event, and what it asks for
ᵘf̲rame ← { st → 0 = t̲ally st ? st v ← ˢᶜn̲ext! w ((v m̲atch "close") + v m̲atch "key q") > 0 ? ᵘq̲uit st (v m̲atch "key z") ? ᵘs̲ay ᵘu̲ndoLast st (v m̲atch "key Space") ? ᵘs̲ay ᵘs̲cramble st (v m̲atch "key 0") ? ᵘs̲ay ᵘr̲eset st ch ← -1 t̲ake v i ← letters i̲ndexOf f̲irst ch ((5 = t̲ally v) × i ≤ 12) ? ᵘs̲ay i ᵘt̲urnBy st st }