sourcegames/minesweeper/minesweeper.xtl
1⍝!/usr/bin/env xetal
2⍝# Minesweeper, scripted (seed 1), with the rules of Mines.xtl.
3ᵐ⁼u̲se< "Mines"
4
5⍝ A new field: 10 mines on the first 10 squares of a random order.
6s ← ᵐn̲ew 0
7ᵐm̲ines s
8
9⍝ How many mines touch each square: the mines inside a border of zeros,
10⍝ rotated along both axes by -1, 0 and 1 (nine boards at once, a 3 by 3
11⍝ by 11 by 11 array), summed over the first two axes, less the board,
12⍝ the border dropped.
13p ← 0 c̲at₂ (0 c̲at (ᵐm̲ines s) c̲at 0) c̲at₂ 0
14s̲hape -1 0 1 o̲-₁₂ p
15ᵐc̲ounts s
16
17⍝# Opening a square with no mine around it floods: watch the opened
18⍝# region grow, one ring of neighbors at a time, until it stops.
19ᵘs̲teps ← { o →
20 said ← p̲rint! '+ r̲/ r̲avel o
21 more ← 1 × (o ∨ 0 < ᵐa̲round o ∧ 0 = ᵐc̲ounts s) ∧ n̲ot ᵐm̲ines s
22 more m̲atch o ? o
23 ᵘs̲teps more
24}
25start ← 1 × 9 9 r̲eshape 37 = r̲ange 81 ⍝ row 5, column 1
26grown ← ᵘs̲teps start
27grown
28
29⍝# Open every safe square, one after another: the field is cleared.
30ᵘc̲lear ← { s v →
31 0 = t̲ally v ? s
32 next ← s ᵐr̲eveal (1 + ((f̲irst v) − 1) d̲iv 9) c̲at 1 + ((f̲irst v) − 1) m̲od 9
33 next ᵘc̲lear 1 d̲rop v
34}
35done ← s ᵘc̲lear w̲here n̲ot r̲avel ᵐm̲ines s
36ᵐv̲iew done
37ᵐs̲tatus done ⍝ 1: won
38pic ← ⎕S̲HOW ᵐp̲icture done
39
40⍝ What the game guarantees, checked by a_ssert< (the condition as
41⍝ written; silent when it holds, a line on standard error, which fails
42⍝ the tests, when it does not).
43ok ← "10 = '+ r_/ r_avel m:m_ines s" a̲ssert< "ten mines"
44ok ← "1 = m:s_tatus done" a̲ssert< "opening every safe square wins"
a̲ssert< expands to
({ @ → (10 = '+ r̲/ r̲avel ᵐm̲ines s) ? @◆ ⎕E̲RR "assertion failed: 10 = '+ r_/ r_avel m:m_ines s (ten mines) [games/minesweeper/minesweeper.xtl:43]"◆ @ } @)