Martin Escardo, Paulo Oliva, 2-27 July 2021
Example: Tic-tac-toe. We have two versions. The other version is in
another file.
\begin{code}
{-# OPTIONS --safe --without-K --no-exact-split #-}
module Games.TicTacToe2 where
open import MLTT.Spartan hiding (J)
open import MLTT.Fin
data π : Type where
 O-wins draw X-wins : π
open import Games.Constructor π
open import Games.FiniteHistoryDependent π
open import Games.TypeTrees
open import MonadOnTypes.J
open import MLTT.Athenian
open list-util
tic-tac-toeβJ : GameJ
tic-tac-toeβJ = build-GameJ draw Board transition 9 boardβ
 where
  flip : π β π
  flip O-wins = X-wins
  flip draw   = draw
  flip X-wins = O-wins
  data Player : Type where
   O X : Player
  Cell = Fin 9
  record Board : Type where
   pattern
   constructor board
   field
    next-player     : Player
    available-moves : List Cell
    X-moves         : List Cell
    O-moves         : List Cell
  open Board
  opponent-wins : Player β π
  opponent-wins X = O-wins
  opponent-wins O = X-wins
  winning : List Cell β Bool
  winning = some-contained ((π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· (π β· π β· π β· [])
                          β· [])
  wins : Board β Bool
  wins (board O _ _  os) = winning os
  wins (board X _ xs  _) = winning xs
  boardβ : Board
  boardβ = board X (list-Fin 9) [] []
  Move : List Cell β Type
  Move xs = Ξ£ c κ Cell , ((c is-in xs) οΌ true)
\end{code}
The following definition of argmax is somewhat convoluted because it
is optimized for time, by minimizing the number of evaluations of the
predicate q:
\begin{code}
  argmax : (m : Cell) (ms : List Cell) β π β (Move (m β· ms) β π) β Move (m β· ms)
  argmax m ms       X-wins  q = m , need m == m || (m is-in ms) οΌ true
                                    which-is-given-by ||-left-intro _ (==-refl m)
  argmax m []       r       q = m , need m == m || (m is-in []) οΌ true
                                    which-is-given-by ||-left-intro _ (==-refl m)
  argmax m (x β· xs) O-wins  q = ΞΉ Ξ³
   where
    ΞΉ : Move (x β· xs) β Move (m β· x β· xs)
    ΞΉ (c , e) = c , need c == m || (c is-in (x β· xs)) οΌ true
                    which-is-given-by ||-right-intro {c == m} _ e
    q' : Move (x β· xs) β π
    q' m = q (ΞΉ m)
    a : (x == m) || ((x == x) || (x is-in xs)) οΌ true
    a = ||-right-intro {x == m} _ (||-left-intro _ (==-refl x))
    Ξ³ : Move (x β· xs)
    Ξ³ = argmax x xs (q (x , a)) q'
  argmax m us@(x β· ms) draw q = g us c
   where
    c : ((x == x) || (x is-in ms)) && (ms contained-in (x β· ms)) οΌ true
    c = &&-intro (||-left-intro _ (==-refl x)) (contained-lemmaβ x ms)
    g : (vs : List Cell) β vs contained-in us οΌ true β Move (m β· us)
    g []       c = m , need m == m || (m is-in (x β· ms)) οΌ true
                       which-is-given-by ||-left-intro _ (==-refl m)
    g (y β· vs) c = k (q (y , a))
     where
      a : (y == m) || ((y == x) || (y is-in ms)) οΌ true
      a = ||-right-intro {y == m} _ (prβ (&&-gives-Γ c))
      b : (vs contained-in (x β· ms)) οΌ true
      b = prβ (&&-gives-Γ c)
      k : π β Move (m β· us)
      k X-wins = y , a
      k r      = g vs b
  open J-definitions π
  argmin : (m : Cell) (ms : List Cell) β π β (Move (m β· ms) β π) β Move (m β· ms)
  argmin m ms r q = argmax m ms (flip r) (Ξ» xs β flip (q xs))
  arg : Player β (ms : List Cell) β empty ms οΌ false β  J (Move ms)
  arg _ []       e q = π-elim (true-is-not-false e)
  arg X (m β· ms) e q = argmax m ms (q (m , ||-left-intro (m is-in ms) (==-refl m))) q
  arg O (m β· ms) e q = argmin m ms (q (m , ||-left-intro (m is-in ms) (==-refl m))) q
  play : (b : Board) β Move (available-moves b) β Board
  play (board X as xs os) (c , e) = board O (remove c as) (insert c xs) os
  play (board O as xs os) (c , e) = board X (remove c as) xs            (insert c os)
  transition : Board β π + (Ξ£ M κ Type , (M β Board) Γ J M)
  transition b@(board next as xs os) =
   if wins b
   then inl (opponent-wins next)
   else Bool-equality-cases (empty as)
         (Ξ» (_ : empty as οΌ true)  β inl draw)
         (Ξ» (e : empty as οΌ false) β inr (Move as , play b , arg next as e))
tic-tac-toeβ : Game
tic-tac-toeβ = Game-from-GameJ tic-tac-toeβJ
tβ : π
tβ = optimal-outcome tic-tac-toeβ
sβ : Path (game-tree tic-tac-toeβ)
sβ = strategic-path (selection-strategy (selections tic-tac-toeβJ) (payoff-function tic-tac-toeβ))
uβ : Path (game-tree tic-tac-toeβ)
uβ = sequenceα΄Ά (selections tic-tac-toeβJ) (payoff-function tic-tac-toeβ)
lβ : β
lβ = plength sβ
\end{code}