我想在Haskell中使用極小極大算法編寫井字節程序。我建立我自己的「玫瑰」數據類型,如下所示:Haskell遞歸極大極小樹
data Rose a = a :> [Rose a]
這是我想「商店」我最小最大樹中的數據類型。我理解minimax算法是如何工作的,但似乎無法在遞歸函數中實現它。
minimax :: Player -> Rose Board -> Rose Int
minimax p (r :> []) | hasWinner r == Just p = 1 :> []
| hasWinner r == Just (nextPlayer p) = (-1) :> []
| otherwise = 0 :> []
minimax p (r :> rs) = maximum(map root xs) :> xs
where xs = map (minimax' (nextPlayer p)) rs
minimax' :: Player -> Rose Board -> Rose Int
minimax' p [email protected](r :> []) = minimax p b
minimax' p (r :> rs) = minimum(map root xs) :> xs
where xs = map (minimax p) rs
「玩家」也是一個自建的數據類型,它可以是P1或P2的值。 「hasWinner」函數檢查給定的「Board」(可以容納井字棋牌的數據類型)是否具有贏家,並且返回Maybe P1或Maybe P2或Nothing。
我寫的這個「minimax」函數並沒有給我錯誤,但結果是不正確的。我的minimax實施中的缺陷在哪裏?
嗨Cirdec,非常感謝您的回覆。但是,當我測試給出P1和示例Board輸入的極小極大函數時,你的代碼似乎是合乎邏輯的,我的極大極小樹填充了'1'。但是示例Board實際上有P2獲勝的場景,這意味着樹中應該有'-1'......我仔細檢查了「hasWinner」函數是否工作,並且經過一些測試,似乎工作正常。 – Felix
如果'r'是由'P1'選擇的移動,'rs'是可用於'P2'的移動,'P2'正嘗試'最小化'。也許'P1'需要考慮另一個玩家如何選擇一個移動,而不是選擇一個最適合'P2'的P1。 – Cirdec
這與P2的移動最小化並不相同嗎?我如何在你的代碼中實現你的理論? – Felix