sourcegames/lights-out/lights-out.xtl
1⍝!/usr/bin/env xetal
2⍝# Lights out, scripted (seed 1), with the rules, solver and drawing of
3⍝# Lamps.xtl: a press as a matrix, a board of presses as one product mod
4⍝# 2, and the puzzle solved by Gaussian elimination over GF(2).
5ˡᵒ⁼u̲se< "Lamps"
6
7⍝ The press matrix: row 13 (the middle square) is the plus around it.
8P ← ˡᵒp̲resses @
9s̲hape P
105 5 r̲eshape 13 s̲elect P
11
12⍝ A puzzle (seed 1): some squares pressed at random from all off.
13s ← ˡᵒn̲ew 0
145 5 r̲eshape ˡᵒl̲ights s
15
16⍝ Its solution: the presses that turn it off, by elimination mod 2;
17⍝ pressing them all at once (one product with the press matrix, mod 2)
18⍝ leaves every light off.
19x ← ˡᵒs̲olve ˡᵒl̲ights s
205 5 r̲eshape x
215 5 r̲eshape (ˡᵒl̲ights s) ˡᵒa̲fter x
22
23⍝ Why every puzzle has four solutions: two quiet patterns, sets of
24⍝ presses that change nothing (each light flipped an even number of
25⍝ times), and so can be added to any solution.
26q ← 2 25 r̲eshape 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1
27'{ i → '+ r̲/ (25 r̲eshape 0) ˡᵒa̲fter i s̲elect q } e̲ach 1 2
28
29⍝ Played by clicks: the hint's square, then each press of the solution.
30t ← s ˡᵒc̲lick 500 67.0
31ˡᵒs̲ay t
32ᵘp̲ressAll ← { s ks → 0 = t̲ally ks ? s◆ (s ˡᵒp̲ress f̲irst ks) ᵘp̲ressAll 1 d̲rop ks }
33done ← s ᵘp̲ressAll w̲here x
34ˡᵒs̲ay done
35pic ← ⎕S̲HOW ˡᵒd̲raw done
36
37⍝ What the game guarantees, checked by a_ssert< (silent when it holds).
38ok ← "0 = '+ r_/ (lo:l_ights s) lo:a_fter x" a̲ssert< "the solution turns every light off"
39ok ← "1 = lo:s_tatus done" a̲ssert< "pressing the solution wins"
40ok ← "0 = '+ r_/ r_avel (q '+ '* i_nner lo:p_resses @) m_od 2" a̲ssert< "the quiet patterns change nothing"
a̲ssert< expands to
({ @ → (0 = '+ r̲/ (ˡᵒl̲ights s) ˡᵒa̲fter x) ? @◆ ⎕E̲RR "assertion failed: 0 = '+ r_/ (lo:l_ights s) lo:a_fter x (the solution turns every light off) [games/lights-out/lights-out.xtl:38]"◆ @ } @)a̲ssert< expands to
({ @ → (1 = ˡᵒs̲tatus done) ? @◆ ⎕E̲RR "assertion failed: 1 = lo:s_tatus done (pressing the solution wins) [games/lights-out/lights-out.xtl:39]"◆ @ } @)