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"
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]"◆ @ } @)
39ok ← "1 = lo:s_tatus done" a̲ssert< "pressing the solution wins"
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]"◆ @ } @)
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̲/ r̲avel (q '+ '× i̲nner ˡᵒp̲resses @) m̲od 2) ? @◆ ⎕E̲RR "assertion failed: 0 = '+ r_/ r_avel (q '+ '* i_nner lo:p_resses @) m_od 2 (the quiet patterns change nothing) [games/lights-out/lights-out.xtl:40]"◆ @ } @)