sourcegames/tic-tac-toe/tic-tac-toe.xtl
1⍝!/usr/bin/env xetal
2⍝# Tic-tac-toe, scripted (seed 1), with the rules of TicTacToe.xtl.
3ᵗ⁼u̲se< "TicTacToe"
4
5⍝ The eight lines as a table of squares, and a board.
6ᵗl̲ines @
7b ← 1 1 0 -1 -1 0 0 0 0
8ᵗv̲iew b
9
10⍝ Used as indices, the lines table picks every line's squares from the
11⍝ board at once (8 by 3); summed along the rows, a 2 says X needs one
12⍝ more there.
13(ᵗl̲ines @) s̲elect b
14ᵗs̲ums b
15ᵗl̲egal b
16
17⍝ X to move (two marks each). The quick player rates every empty square
18⍝ at once and completes its line.
19ᵗa̲i b
20b ← b ᵗm̲ove ᵗa̲i b
21ᵗv̲iew b
22ᵗs̲tatus b ⍝ 1: X won
23
24⍝ Which squares lie on which lines: a 9 by 8 table.
25ᵗo̲n @
26
27⍝ Minimax from a position with five empty squares: every legal move's
28⍝ value, by recursion over the moves (1 X wins, -1 O wins, 0 draw).
29p ← 1 -1 0 0 1 0 0 0 -1
30ᵗv̲iew p
31'{ ᵗv̲alue p ᵗm̲ove ⍵ } e̲ach ᵗl̲egal p
32ᵗb̲est p
33
34⍝# The quick player against itself, from an empty board: a draw.
35ᵘs̲elf ← { b →
36 0 < ᵗs̲tatus b ? b
37 ᵘs̲elf b ᵗm̲ove ᵗa̲i b
38}
39end ← ᵘs̲elf ᵗn̲ew 0
40ᵗv̲iew end
41pic ← ⎕S̲HOW ᵗp̲icture end
42ᵗs̲tatus end ⍝ 3: a draw
43
44⍝ What the game guarantees, checked by a_ssert< (the condition as
45⍝ written; silent when it holds, a line on standard error, which fails
46⍝ the tests, when it does not).
47ok ← "1 = t:s_tatus b" a̲ssert< "X completes a line"
48ok ← "3 = t:s_tatus end" a̲ssert< "perfect play is a draw"
a̲ssert< expands to
({ @ → (1 = ᵗs̲tatus b) ? @◆ ⎕E̲RR "assertion failed: 1 = t:s_tatus b (X completes a line) [games/tic-tac-toe/tic-tac-toe.xtl:47]"◆ @ } @)