sourceextensions/scene/demos/voxels-rubik.xtl

1⍝# Voxels, 8: a Rubik's cube. 26 dark cubies with their colored stickers, 2⍝# drawn as voxels; the cube itself is arrays (Rubik.xtl): its 54 3⍝# stickers, each where it is and which way it faces, and each of the 4⍝# twelve quarter turns a permutation of them, computed from the cube's 5⍝# geometry. This demo checks the turns -- each a permutation, four of 6⍝# one solved, a turn and its undoing solved, R U R' U' of order 6, R U 7⍝# of order 105, and U and R turning the right way -- and shows the 8⍝# solved cube, turning slowly; keys turn its faces. 9⍝# Run: just demo scene voxels-rubik 10⍝# u d r l f b turn a face clockwise (as you look at it), Shift with the 11⍝# letter counterclockwise, z undo (back to solved), Space a scramble 12⍝# (25 random turns), 0 reset, drag to look around, q quit 13 14ʳᵇ⁼u̲se< "Rubik" 15ˢᶜ⁼u̲se< "Scene" 16 17⍝## The turns, checked 18 19s ← ʳᵇsolved 20"each turn a permutation of the 54 stickers:" 21'{ (s̲ort ⍵ s̲elect ʳᵇmoves) m̲atch r̲ange 54 } e̲ach r̲ange 12 22ᵘf̲our ← { i → (i ʳᵇt̲urn i ʳᵇt̲urn i ʳᵇt̲urn i ʳᵇt̲urn s) m̲atch s } 23"four of each turn: solved" 24'ᵘf̲our e̲ach r̲ange 12 25ᵘb̲ack ← { i → ((ʳᵇu̲ndo i) ʳᵇt̲urn i ʳᵇt̲urn s) m̲atch s } 26"each turn then its undoing: solved" 27'ᵘb̲ack e̲ach r̲ange 12 28ᵘs̲exy ← { c → 6 ʳᵇt̲urn 2 ʳᵇt̲urn 5 ʳᵇt̲urn 1 ʳᵇt̲urn c } 29ᵘs̲exyN ← { n → (n 'ᵘs̲exy p̲ower s) m̲atch s } 30"R U R' U' solved after 6, not after 1 to 5:" 31(ᵘs̲exyN 6) c̲at 'ᵘs̲exyN e̲ach r̲ange 5 32ᵘr̲u ← { c → 1 ʳᵇt̲urn 5 ʳᵇt̲urn c } 33ᵘr̲uN ← { n → (n 'ᵘr̲u p̲ower s) m̲atch s } 34"R U solved after 105, and how many of 1 to 104:" 35(ᵘr̲uN 105) c̲at '+ r̲/ 'ᵘr̲uN e̲ach r̲ange 104 36m ← ʳᵇstickers 37top ← ((6 s̲elect₂ m) = 1) × (2 s̲elect₂ m) = 1 38"after U, the front's top row has the right face's color (2):" 39(top > 0) r̲eplicate 1 ʳᵇt̲urn s 40 41⍝## The cube, drawn 42 43w ← "Voxels 8: Rubik's cube -- X_eTaL" ˢᶜo̲pen! 560 560 44k ← w ˢᶜc̲amera! 0.6 0.45 7.5 0.3 45b ← ((f̲loat w) c̲at 1.0 0.1 0.1 0.11) ˢᶜq̲uads! ʳᵇbodies 46 47⍝# the stickers, one object of quads for each color 48ᵘd̲raw ← { c → 49 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 50 c 51} 52shown ← ᵘd̲raw s 53 54⍝## Turning it 55 56⍝# The state is one Int vector: the 54 colors, then the turns made so 57⍝# far (1 to 12, in the order of rb:names), the history undo walks back. 58⍝# Keys: u d r l f b turn that face clockwise (seen from outside it), 59⍝# with Shift counterclockwise; z undoes the last turn; Space scrambles 60⍝# (25 random turns, never the same face twice in a row); 0 resets. 61 62letters ← "uUdDrRlLfFbB" 63 64⍝# m u:t_ell st: m printed, the state unchanged 65ᵘt̲ell ← { m st → 66 said ← p̲rint! m 67 st 68} 69 70⍝# the turns made, by name (and whether the cube is solved) 71ᵘs̲ay ← { st → 72 h ← 54 d̲rop st 73 0 = t̲ally h ? "solved, no turns" ᵘt̲ell st 74 names ← (n̲ot ʳᵇnames = f̲irst " ") p̲artition ʳᵇnames 75 said ← p̲rint! "turns: " c̲at d̲isclose '{ e̲nclose (d̲isclose ⍺) c̲at " " c̲at d̲isclose ⍵ } r̲/ h s̲elect names 76 ((54 t̲ake st) m̲atch ʳᵇsolved) ? "solved" ᵘt̲ell st 77 st 78} 79 80⍝# i u:t_urnBy st: turn i made and remembered, the cube redrawn 81ᵘt̲urnBy ← { i st → 82 c ← i ʳᵇt̲urn 54 t̲ake st 83 shown ← ᵘd̲raw c 84 c c̲at (54 d̲rop st) c̲at i 85} 86 87⍝# the last turn undone and forgotten 88ᵘu̲ndoLast ← { st → 89 54 = t̲ally st ? st 90 i ← f̲irst -1 t̲ake st 91 c ← (ʳᵇu̲ndo i) ʳᵇt̲urn 54 t̲ake st 92 shown ← ᵘd̲raw c 93 c c̲at 54 d̲rop -1 d̲rop st 94} 95 96⍝# 25 random turns, never the same face twice in a row (so none undoes 97⍝# or repeats the one before), remembered (so undo can walk back to 98⍝# solved) 99ᵘo̲ne ← { st → 100 i ← r̲oll! 12 101 prev ← (55 ≤ t̲ally st) × f̲irst -1 t̲ake st 102 ((i + 1) d̲iv 2) = (prev + 1) d̲iv 2 ? ᵘo̲ne st 103 c ← i ʳᵇt̲urn 54 t̲ake st 104 c c̲at (54 d̲rop st) c̲at i 105} 106ᵘs̲cramble ← { st → 107 st ← 25 'ᵘo̲ne p̲ower st 108 shown ← ᵘd̲raw 54 t̲ake st 109 st 110} 111 112⍝# back to solved, no history 113ᵘr̲eset ← { st → 114 shown ← ᵘd̲raw ʳᵇsolved 115 ʳᵇsolved 116} 117 118ᵘq̲uit ← { st → 119 z ← ˢᶜc̲lose! w 120 0 r̲eshape 0 121} 122 123⍝# one frame: an event, and what it asks for 124ᵘf̲rame ← { st → 125 0 = t̲ally st ? st 126 v ← ˢᶜn̲ext! w 127 ((v m̲atch "close") + v m̲atch "key q") > 0 ? ᵘq̲uit st 128 (v m̲atch "key z") ? ᵘs̲ay ᵘu̲ndoLast st 129 (v m̲atch "key Space") ? ᵘs̲ay ᵘs̲cramble st 130 (v m̲atch "key 0") ? ᵘs̲ay ᵘr̲eset st 131 ch ← -1 t̲ake v 132 i ← letters i̲ndexOf f̲irst ch 133 ((5 = t̲ally v) × i ≤ 12) ? ᵘs̲ay i ᵘt̲urnBy st 134 st 135} 136"keys: u d r l f b turn a face clockwise, Shift+letter counterclockwise, z undo, Space scramble, 0 reset, q quit" 137last ← 100000 'ᵘf̲rame p̲ower ʳᵇsolved 138"bye"