sourcegames/2048/2048.xtl
1⍝!/usr/bin/env xetal
2⍝# 2048, scripted (seed 1), with the rules of Twenty48.xtl.
3ᵗ⁼u̲se< "Twenty48"
4
5⍝ A board, every row slid left at once: compress (running counts and a
6⍝ 4 by 4 by 4 table), merge (places in runs of equal tiles, by a
7⍝ max-scan), compress again.
8b ← 4 4 r̲eshape 2 2 2 2 0 2 0 2 4 4 8 8 2 0 0 4
9ᵗc̲ompress b
10ᵗp̲lace ᵗc̲ompress b
11ᵗd̲oubles ᵗc̲ompress b
12ᵗl̲eft b
13b ᵗg̲ain 1 ⍝ the merged tiles' values
14
15⍝ The other moves turn the board, move left, and turn it back.
16b ᵗs̲lide 2
17b ᵗs̲lide 3
18b ᵗs̲lide 4
19
20⍝# A whole game by a simple corner player: left, then down, then right,
21⍝# then up, the first of them that moves anything.
22ᵘp̲ick ← { s →
23 ok ← '{ n̲ot (s ᵗm̲ove ⍵) m̲atch s } e̲ach 1 4 2 3
24 f̲irst (ok r̲eplicate 1 4 2 3) c̲at 1
25}
26ᵘg̲ame ← { s →
27 0 < ᵗs̲tatus s ? s
28 ᵘg̲ame s ᵗm̲ove ᵘp̲ick s
29}
30end ← ᵘg̲ame ᵗn̲ew 0
31ᵗb̲oard end
32ᵗs̲core end
33ᵗs̲tatus end ⍝ 2: no move left
34
35⍝ What the game guarantees, checked by a_ssert< (the condition as
36⍝ written; silent when it holds, a line on standard error, which fails
37⍝ the tests, when it does not).
38ok ← "('+ r_/ r_avel b) = '+ r_/ r_avel b t:s_lide 2" a̲ssert< "a slide keeps the tiles' total"
39ok ← "2 = t:s_tatus end" a̲ssert< "the game ends with no move left"
a̲ssert< expands to
({ @ → (('+ r̲/ r̲avel b) = '+ r̲/ r̲avel b ᵗs̲lide 2) ? @◆ ⎕E̲RR "assertion failed: ('+ r_/ r_avel b) = '+ r_/ r_avel b t:s_lide 2 (a slide keeps the tiles' total) [games/2048/2048.xtl:38]"◆ @ } @)