sourceextensions/scene/demos/voxels-rubik-buttons.xtl
1⍝# Voxels, 12: the Rubik's cube with buttons. Six buttons under the cube
2⍝# turn its top, right and front layers a quarter turn either way -- U
3⍝# and U' the top, R and R' the right, F and F' the front (a letter
4⍝# alone clockwise as you look at that face, with ' counterclockwise),
5⍝# which between them reach every position of the cube. Each press is
6⍝# animated, a quarter turn in 8 frames; presses made while a turn is
7⍝# under way wait their turn, so the cube answers at once and never
8⍝# drops one. The turns made are shown above the cube.
9⍝# Run: just demo scene voxels-rubik-buttons
10⍝# click a button, or the keys u r f (Shift for '), z undo the last
11⍝# turn, 0 solved again, drag to look around, q quit
12
13ʳᵇ⁼u̲se< "Rubik"
14ʳᵖ⁼u̲se< "RubikPlay"
15ˢᶜ⁼u̲se< "Scene"
16
17w ← "Voxels 12: Rubik's cube, buttons -- X_eTaL" ˢᶜo̲pen! 640 560
18k ← w ˢᶜc̲amera! 0.6 0.45 7.5 0.25
19z ← (ʳᵇsolved, 0, 0.0) ʳᵇd̲raw w
20
21⍝## The buttons
22
23⍝# the six buttons, their turns (in the order of rb:names) and the keys
24⍝# that press them
25names ← "U U' R R' F F'"
26turns ← 1 2 5 6 9 10
27keys ← "uUrRfF"
28top ← 500.0
29o ← w ˢᶜo̲verlay! (w, names, top, 640.0, 100, ʳᵖbw) ʳᵖd̲rawRow 0
30⍝ the buttons drawn again, the one whose turn is under way lit
31ᵘl̲ight ← { st z →
32 (_, _, _, i, _) ← st
33 o ← w ˢᶜo̲verlay! (w, names, top, 640.0, 100, ʳᵖbw) ʳᵖd̲rawRow turns i̲ndexOf a̲bs i
34 st
35}
36ᵘl̲ightIf ← { yes st →
37 yes ? st ᵘl̲ight 0
38 st
39}
40ᵘu̲nder ← { (_, _, _, i, _) → i }
41title ← ((f̲loat w) c̲at 1.0 20.0 20.0 14.0 1.0 1.0 1.0) ˢᶜl̲abel! "Turns:"
42
43"keys: u r f turn clockwise, Shift+letter counterclockwise, z undo, 0 solved, q quit; or click the buttons"
44
45⍝## Playing
46
47⍝# The state is a tuple: (the turning -- RubikPlay's colors, turns made,
48⍝# turns waiting, turn under way and its frame -- and whether it runs).
49
50⍝ st u:s_ay 0: the last 12 turns made, shown above the cube
51ᵘs̲ay ← { st z →
52 (_, h, _, _, _) ← st
53 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
54 st
55}
56
57⍝ the button or key of event v: its turn, else 0
58ᵘp̲ressed ← { v →
59 b ← (v, 6, top, 640.0, ʳᵖbw) ʳᵖh̲it 0
60 b > 0 ? b s̲elect turns
61 i ← keys i̲ndexOf f̲irst -1 t̲ake v
62 ((5 = t̲ally v) × i ≤ 6) ? i s̲elect turns
63 0
64}
65
66ᵘp̲ush ← { t st →
67 t = 0 ? st
68 t ʳᵖq̲ueue st
69}
70ᵘu̲ndoIf ← { yes st →
71 yes ? (ʳᵖu̲ndo st) ᵘs̲ay 0
72 st
73}
74ᵘs̲ayIf ← { yes st →
75 yes ? st ᵘs̲ay 0
76 st
77}
78ᵘm̲ade ← { (_, h, _, _, _) → t̲ally h }
79
80⍝# one frame: an event (a button, a key, undo, solved again, quit), then
81⍝# a frame of turning
82ᵘf̲rame ← { (st, on) →
83 0 = on ? (st, on)
84 v ← ˢᶜn̲ext! w
85 ((v m̲atch "close") + v m̲atch "key q") > 0 ? (st, 0)
86 (v m̲atch "key 0") ? (ʳᵖstart ᵘs̲ay 0, on) ᵘr̲edraw 0
87 st ← (v m̲atch "key z") ᵘu̲ndoIf st
88 st ← (ᵘp̲ressed v) ᵘp̲ush st
89 n ← ᵘm̲ade st
90 was ← ᵘu̲nder st
91 st ← (w, 8) ʳᵖa̲dvance st
92 st ← (was ≠ ᵘu̲nder st) ᵘl̲ightIf st
93 ((n ≠ ᵘm̲ade st) ᵘs̲ayIf st, on)
94}
95⍝ the cube drawn again (after a reset)
96ᵘr̲edraw ← { sto z →
97 (st, on) ← sto
98 (c, _, _, _, _) ← st
99 d ← (c, 0, 0.0) ʳᵇd̲raw w
100 sto
101}
102
103last ← 100000 'ᵘf̲rame p̲ower (ʳᵖstart, 1)
104z ← ˢᶜc̲lose! w
105⍝ (an accessor, not a top-level tuple pattern: xetal doc would list a
106⍝ hidden %N value for one, ask E10)
107ᵘc̲olorsOf ← { ((c, _, _, _, _), _) → c }
108ᵘt̲urnsOf ← { ((_, h, _, _, _), _) → h }
109c ← ᵘc̲olorsOf last
110h ← ᵘt̲urnsOf last
111"the turns made:"
112ʳᵖn̲ames h
113"the cube is those turns made at once on a solved cube:"
114c m̲atch ʳᵖa̲pplied h
115"bye"