programextensions/scene/demos/voxels-rubik-buttons.xtl
Voxels, 12: the Rubik's cube with buttons. Six buttons under the cube turn its top, right and front layers a quarter turn either way -- U and U' the top, R and R' the right, F and F' the front (a letter alone clockwise as you look at that face, with ' counterclockwise), which between them reach every position of the cube. Each press is animated, a quarter turn in 8 frames; presses made while a turn is under way wait their turn, so the cube answers at once and never drops one. The turns made are shown above the cube. Run: just demo scene voxels-rubik-buttons click a button, or the keys u r f (Shift for '), z undo the last turn, 0 solved again, drag to look around, q quit
k : Int
k ← w ˢᶜc̲amera! 0.6 0.45 7.5 0.25
The buttons
names : Char
the six buttons, their turns (in the order of rb:names) and the keys that press them
names ← "U U' R R' F F'"
o : Int
o ← w ˢᶜo̲verlay! (w, names, top, 640.0, 100, ʳᵖbw) ʳᵖd̲rawRow 0
ᵘl̲ight : (Any a, Any b, Any c, Any d, Any e) => (a, b, c, Int, d) -> e -> (a, b, c, Int, d)
ᵘl̲ight ← { st z → (_, _, _, i, _) ← st o ← w ˢᶜo̲verlay! (w, names, top, 640.0, 100, ʳᵖbw) ʳᵖd̲rawRow turns i̲ndexOf a̲bs i st }
ᵘl̲ightIf : (Truthy a, Any b, Any c, Any d, Any e) => a -> (b, c, d, Int, e) -> (b, c, d, Int, e)
ᵘl̲ightIf ← { yes st → yes ? st ᵘl̲ight 0 st }
ᵘu̲nder : (Any a, Any b, Any c, Any d, Any e) => (a, b, c, d, e) -> d
ᵘu̲nder ← { (_, _, _, i, _) → i }
Playing
ᵘs̲ay : (Any a, Any b, Any c, Any d, Any e) => (a, Int, b, c, d) -> e -> (a, Int, b, c, d)
ᵘs̲ay ← { st z → (_, h, _, _, _) ← st said ← ((f̲loat w) c̲at 2.0 100.0 20.0 14.0 1.0 1.0 0.6) ˢᶜl̲abel! ʳᵖn̲ames (0 − 12 m̲in t̲ally h) t̲ake h st }
ᵘp̲ressed : Char -> Int
ᵘp̲ressed ← { v → b ← (v, 6, top, 640.0, ʳᵖbw) ʳᵖh̲it 0 b > 0 ? b s̲elect turns i ← keys i̲ndexOf f̲irst -1 t̲ake v ((5 = t̲ally v) × i ≤ 6) ? i s̲elect turns 0 }
ᵘp̲ush : (Num a, Any b, Any c, Any d, Any e) => a -> (b, c, a, d, e) -> (b, c, a, d, e)
ᵘp̲ush ← { t st → t = 0 ? st t ʳᵖq̲ueue st }
ᵘu̲ndoIf : (Truthy a, Any b, Num c, Any d) => a -> (b, Int, Int, c, d) -> (b, Int, Int, c, d)
ᵘu̲ndoIf ← { yes st → yes ? (ʳᵖu̲ndo st) ᵘs̲ay 0 st }
ᵘs̲ayIf : (Truthy a, Any b, Any c, Any d, Any e) => a -> (b, Int, c, d, e) -> (b, Int, c, d, e)
ᵘs̲ayIf ← { yes st → yes ? st ᵘs̲ay 0 st }
ᵘm̲ade : (Any a, Any c, Any d, Any e) => (a, b, c, d, e) -> Int
ᵘm̲ade ← { (_, h, _, _, _) → t̲ally h }
ᵘf̲rame : Num a => ((Int, Int, Int, Int, Int), a) -> ((Int, Int, Int, Int, Int), a)
one frame: an event (a button, a key, undo, solved again, quit), then a frame of turning
ᵘf̲rame ← { (st, on) → 0 = on ? (st, on) v ← ˢᶜn̲ext! w ((v m̲atch "close") + v m̲atch "key q") > 0 ? (st, 0) (v m̲atch "key 0") ? (ʳᵖstart ᵘs̲ay 0, on) ᵘr̲edraw 0 st ← (v m̲atch "key z") ᵘu̲ndoIf st st ← (ᵘp̲ressed v) ᵘp̲ush st n ← ᵘm̲ade st was ← ᵘu̲nder st st ← (w, 8) ʳᵖa̲dvance st st ← (was ≠ ᵘu̲nder st) ᵘl̲ightIf st ((n ≠ ᵘm̲ade st) ᵘs̲ayIf st, on) }
ᵘr̲edraw : (Num a, Num b) => ((Int, Int, Int, Int, Int), a) -> b -> ((Int, Int, Int, Int, Int), a)
ᵘr̲edraw ← { sto z → (st, on) ← sto (c, _, _, _, _) ← st d ← (c, 0, 0.0) ʳᵇd̲raw w sto }
ᵘc̲olorsOf : (Any a, Any b, Any c, Any d, Any e, Any f) => ((a, b, c, d, e), f) -> a
ᵘc̲olorsOf ← { ((c, _, _, _, _), _) → c }
ᵘt̲urnsOf : (Any a, Any b, Any c, Any d, Any e, Any f) => ((a, b, c, d, e), f) -> b
ᵘt̲urnsOf ← { ((_, h, _, _, _), _) → h }
c : Int
c ← ᵘc̲olorsOf last