programextensions/scene/demos/voxels-game.xtl
Voxels, 15: Gem Hunt. Ten gems are buried around the start, a few blocks under the surface; dig them out in three minutes. The first lies four blocks straight down from where you start; the others are scattered within a dozen blocks, deeper. Gems glow a little (12 where a lamp is 15), so a tunnel near one is lit -- and the corner of the screen says how far the nearest gem you have not found is. Everything from the voxel demos works: dig, place, lamps, water, night. G gives up and shows the score. The game is X_eTaL: the gems are edits, a find is a dig whose cell is a gem's, the clock is the frames (60 a second), the labels are scene's. Run: just demo scene voxels-game click (or X) dig, right-click (or E) place, 1 to 8 choose the block (8 a lamp), N night or day, W A S D walk, Space jump, F fly, drag or the arrows to look, G give up, H back to the start, q quit
The gems
s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))
s ← ᵉⁿl̲ighting ᵉⁿn̲ew w
ᵘm̲ore : Int -> Int
u:m_ore gs: one more gem, at a random column within 12 blocks of the start (not the start's own), 2 to 6 blocks under the ground's top, never above the world's bottom
ᵘm̲ore ← { gs → o ← (r̲oll! 25 25) − 13 xz ← (1 3 s̲elect x0) + o y ← 1 m̲ax (ᵘt̲op xz) − 1 + r̲oll! 5 gs c̲at 1 3 r̲eshape (1 s̲elect xz) c̲at y c̲at 2 s̲elect xz }
first : Int
the first gem four blocks down under the start (its fourth dig), then nine more
first ← 1 3 r̲eshape (1 s̲elect x0) c̲at ((ᵘt̲op 1 3 s̲elect x0) − 3) c̲at 3 s̲elect x0
s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))
s ← (gems, 9) ᵉⁿs̲etAll s
Playing
ᵘk̲ey : Num a => a -> a
ᵘk̲ey ← { q → (200000 × (64 × 100000 + 1 s̲elect₂ q) + 2 s̲elect₂ q) + 100000 + 3 s̲elect₂ q }
ᵘc̲lock : Int -> Char
ᵘc̲lock ← { frames → secs ← frames d̲iv 60 (f̲ormat secs d̲iv 60) c̲at ":" c̲at -2 t̲ake "0" c̲at f̲ormat secs m̲od 60 }
ᵘs̲how : (Any a, Any b, Any c, Any d, Any e, Any f, Any g, Any h, Num i, Any k, Any l) => (((Float, a, b, c, d, e), f, g, h), (i, j, Int, k, l)) -> (i, j, Int, k, l)
ᵘs̲how ← { (s, game) → (gs, found, left, over, _) ← game p ← ᵉⁿp̲osition s a ← ((f̲loat w) c̲at 1.0 16.0 14.0 14.0 1.0 1.0 1.0) ˢᶜl̲abel! "Gems " c̲at (f̲ormat found) c̲at " of " c̲at f̲ormat total b ← ((f̲loat w) c̲at 2.0 200.0 14.0 14.0 1.0 1.0 0.6) ˢᶜl̲abel! "Time " c̲at ᵘc̲lock left hint ← (0 < t̲ally gs) ᵘn̲ear (gs, p) c ← ((f̲loat w) c̲at 3.0 340.0 14.0 14.0 0.6 1.0 1.0) ˢᶜl̲abel! hint game }
ᵘn̲ear : (Num a, Truthy a, Num b) => a -> (b, Float) -> Char
ᵘn̲ear ← { yes gp → (gs, p) ← gp 0 = yes ? "" d ← ((f̲loat gs) + 0.5) − ((t̲ally gs) c̲at 3) r̲eshape p "Nearest gem " c̲at (f̲ormat f̲loor 0.5 + ('m̲in r̲/ '+ r̲/₂ d × d) ^ 0.5) c̲at " blocks" }
ᵘe̲nd : (Num c, Truthy c, Any d) => (a, b, Int, c, d) -> (a, b, Int, c, d)
ᵘe̲nd ← { game → (gs, found, left, over, seen) ← game over ? game m ← (0 = t̲ally gs) ᵘv̲erdict (found, left) said ← p̲rint! "game over: " c̲at m z ← ((f̲loat w) c̲at 4.0 c̲at (320.0 − 1.5 × f̲loat (6 × t̲ally m) − 1) c̲at 170.0 21.0 1.0 0.85 0.3) ˢᶜl̲abel! m (gs, found, left, 1, seen) }
ᵘv̲erdict : Truthy a => a -> (b, Int) -> Char
ᵘv̲erdict ← { all fl → (found, left) ← fl all ? "All " c̲at (f̲ormat total) c̲at " gems with " c̲at (ᵘc̲lock left) c̲at " to spare!" left = 0 ? (f̲ormat found) c̲at " of " c̲at (f̲ormat total) c̲at " gems -- time is up" (f̲ormat found) c̲at " of " c̲at (f̲ormat total) c̲at " gems -- stopped with " c̲at (ᵘc̲lock left) c̲at " left" }
ᵘf̲inds : (Any a, Any b, Any c, Any d, Any e, Num f, Any g, Any h, Any i, Any j, Any k, Num l, Truthy l, Any m, Any n) => ((a, (b, c, d, e, f, g, h, i), j, k), (f, l, m, n, Int)) -> (f, l, m, n, Int)
ᵘf̲inds ← { (s, game) → (gs, found, left, over, seen) ← game ed ← ᵉⁿe̲dits s n ← t̲ally ed new ← (n − seen) t̲ake ed dug ← (0 = 4 s̲elect₂ new) r̲eplicate 1 2 3 s̲elect₂ new hit ← (ᵘk̲ey gs) m̲ember? ᵘk̲ey dug k ← '+ r̲/ hit said ← (k > 0) ᵘt̲ell (hit r̲eplicate gs, found + k) ((0 = hit) r̲eplicate gs, found + k, left, over, n) }
ᵘt̲ell : (Num a, Truthy a, Num b, Num c, Truthy c) => a -> (b, c) -> Char
ᵘt̲ell ← { yes cf → (cells, found) ← cf 0 = yes ? "" p̲rint! "found a gem at " c̲at (f̲ormat r̲avel cells) c̲at " (" c̲at (f̲ormat found) c̲at " of " c̲at (f̲ormat total) c̲at ")" }
ᵘf̲rame : (Num a, Num b, Num c, Num d, Truthy d, Num e, Truthy e) => (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (a, Int, Int, Int), (Int, Int, Float, b, c)), Int, (Int, d, Int, e, Int)) -> (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (a, Int, Int, Int), (Int, Int, Float, b, c)), Int, (Int, d, Int, e, Int))
one frame: the world's frame (pl:f_rameV), then the game's turn and its labels
ᵘf̲rame ← { (s, sel, game) → ᵉⁿs̲topped s ? (s, sel, game) (s, sel, v) ← ᵖˡf̲rameV (s, sel) game ← ᵘt̲urn (s, v, game) (s, sel, ᵘs̲how (s, game)) }
ᵘt̲urn : (Num a, Num b, Num c, Num d, Truthy d, Num e, Truthy e) => (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (a, Int, Int, Int), (Int, Int, Float, b, c)), Char, (Int, d, Int, e, Int)) -> (Int, d, Int, e, Int)
the game's turn: the gems found, the clock, and the end when the time is up, all are found or G is pressed (once over, it stays over)
ᵘt̲urn ← { (s, v, game) → (gs, found, left, over, seen) ← game over ? game game ← ᵘf̲inds (s, game) (gs, found, left, over, seen) ← game left ← 0 m̲ax left − 1 game ← (gs, found, left, over, seen) done ← (0 = left) + (0 = t̲ally gs) + v m̲atch "key g" 0 < done ? ᵘe̲nd game game }
s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))
s ← (4 × (1 + 2 × ᵉⁿreach) × 1 + 2 × ᵉⁿreach) 'ᵉⁿs̲tream p̲ower s
last : (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int)), Int, (Int, Int, Int, Int, Int))
last ← 100000 'ᵘf̲rame p̲ower (s, 1, game)
ᵘf̲oundOf : (Any a, Any b, Any c, Any d, Any e) => (a, b, c, d, e) -> b
ᵘf̲oundOf ← { (_, found, _, _, _) → found }