我仍在尝试围绕 agda 进行思考,所以我写了一个小井字游戏类型
data Game : Player -> Vec Square 9 -> Set where
start : Game x ( - ∷ - ∷ - ∷
- ∷ - ∷ - ∷
- ∷ - ∷ - ∷ [] )
xturn : {gs : Vec Square 9} -> (n : ℕ) -> Game x gs -> n < (#ofMoves gs) -> Game o (makeMove gs x n )
oturn : {gs : Vec Square 9} -> (n : ℕ) -> Game o gs -> n < (#ofMoves gs) -> Game x (makeMove gs o n )
这将拥有一个有效的游戏路径。
这里#ofMoves gs
将返回空Square
s 的数量,
n < (#ofMoves gs)
将证明n
第 th 步是有效的,并makeMove gs x n
替换n
游戏状态向量中的第 th 个空 Square。
在与自己进行了几场刺激的比赛之后,我决定拍摄更棒的东西。目标是创建一个函数,让 x 玩家和 o 玩家在史诗般的生死战中相互对抗。
--two programs enter, one program leaves
gameMaster : {p : Player } -> {gs : Vec Square 9} --FOR ALL
-> ({gs : Vec Square 9} -> Game x gs -> (0 < (#ofMoves gs)) -> Game o (makeMove gs x _ )) --take an x player
-> ({gs : Vec Square 9} -> Game o gs -> (0 < (#ofMoves gs)) -> Game x (makeMove gs o _ )) --take an o player
-> ( Game p gs) --Take an initial configuration
-> GameCondition --return a winner
gameMaster {_} {gs} _ _ game with (gameCondition gs)
... | xWin = xWin
... | oWin = oWin
... | draw = draw
... | ongoing with #ofMoves gs
... | 0 = draw --TODO: really just prove this state doesn't exist, it will always be covered by gameCondition gs = draw
gameMaster {x} {gs} fx fo game | ongoing | suc nn = gameMaster (fx) (fo) (fx game (s≤s z≤n)) -- x move
gameMaster {o} {gs} fx fo game | ongoing | suc nn = gameMaster (fx) (fo) (fo game (s≤s z≤n)) -- o move
这(0 < (#ofMoves gs))
是游戏正在进行的证明的“速记”,
将返回您所期望的游戏状态gameCondition gs
(之一xWin
,,,或oWin
)draw
ongoing
我想证明有有效的动作(s≤s z≤n
部分)。这应该是可能的,因为suc nn
<= #ofMoves gs
。我不知道如何在 agda 中完成这项工作。