Haskell递归极小极大树

时间:2016-09-30 18:56:52

标签: algorithm haskell recursion minimax

我正在尝试使用minimax算法在Haskell中编写Tic Tac Toe程序。我构建了自己的“Rose a”数据类型如下:

data Rose a = a :> [Rose a]

这是我想要“存储”我的minimax树的数据类型。我理解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 b@(r :> []) = minimax p b
minimax' p   (r :> rs) = minimum(map root xs) :> xs
    where xs = map (minimax p) rs

“播放器”也是一种自构造的数据类型,其值可以是P1或P2。 “hasWinner”函数检查给定的“Board”(可以容纳Tic Tac Toe板的数据类型)是否有赢家,并返回Maybe P1或Maybe P2,或者Nothing。

我写的这个“minimax”函数并没有给我错误,但结果不正确。我的minimax实现中的缺陷在哪里?

2 个答案:

答案 0 :(得分:5)

您没有正确切换两个玩家。 minimax' p b@(r :> []) = minimax p b错了。 map (minimax p) rs中的minimax'不会切换到最大化一半的其他玩家。

我建议明确写出P1(尝试最大化)和P2(尝试最小化)。

最后阶段可以指定获胜者而不关心当前正在玩哪个玩家

minimax :: Player -> Rose Board -> Rose Int
minimax p (r :> [])   | hasWinner r == Just P1 = 1    :> []
                      | hasWinner r == Just P2 = (-1) :> []
                      | otherwise              = 0    :> []

玩家P1正在尝试最大化

minimax P1 (r :> rs) = maximum (map root xs) :> xs
    where xs = map (minimax (nextPlayer p)) rs

玩家P2正在尝试最小化

minimax P2 (r :> rs) = minimum (map root xs) :> xs
    where xs = map (minimax (nextPlayer p)) rs

答案 1 :(得分:-1)

经过大量的测试和困惑,我发现创建游戏树的功能有一些缺陷。调试完毕后,Cirdec建议的算法工作正常!