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"
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]"◆ @ } @)
48ok ← "3 = t:s_tatus end" a̲ssert< "perfect play is a draw"
a̲ssert< expands to
({ @ → (3 = ᵗs̲tatus end) ? @◆ ⎕E̲RR "assertion failed: 3 = t:s_tatus end (perfect play is a draw) [games/tic-tac-toe/tic-tac-toe.xtl:48]"◆ @ } @)