所以我写了一个hexapawn游戏,我试图创建一个函数,如果董事会处于获胜状态,则返回True,此时看起来像这样:
checkWin :: BoardState -> Bool
checkWin b1@(blackPieces,whitePieces,turn,size,win)
|(length blackPieces) == 0 = True
|(length whitePieces) == 0 = True
|length (generateMoves b1) == 0 = True
|otherwise = False
所以如果没有黑色或白色碎片或没有人可以移动但是如果一个对手的棋子到达棋盘的末端(另一种赢得六声道的方式)则不起作用。变量 blackPieces 和 whitePieces 是坐标列表,即[(1,1),(2,1),(3,1)]这些棋子在哪里 size n的电路板(转如果白色转动则为真)
我很想将这些条件添加到方法中,但编译器不喜欢它。
|(_,1) `elem` whitePieces = True
|(_,size) `elem` blackPieces = True
还有其他方式可以说“ whitePieces 中是否有任何元组是第二个元素是1(即到达了电路板的另一侧)。”
提前致谢有用的评论。
答案 0 :(得分:7)
所以我们想要一个函数,它接收一些[a]
的列表,一个谓词(a->Bool)
的谓词,并返回一个Bool
。快速查看Hoogle,然后我们回来
any :: (a -> Bool) -> [a] -> Bool
Applied to a predicate and a list, any determines if any element of
the list satisfies the predicate. For the result to be False, the list must be finite
所以
(_,1) `elem` whitePieces
变为
any (\(_, x) -> x == 1) whitePieces
或(正如eternalmatt提醒我的那样)
any (==1) ( map snd whitePieces )
等等
顺便说一下,检查的最佳方法是列表为空是通过模式匹配或null
函数。长度== 0方法将遍历所有链表,如果列表是无限的,甚至可能进入无限循环。
答案 1 :(得分:2)
您可以使用filter
:
not $ null (filter wincond whitePieces)
where wincond x = snd x == 1
如果带有第二个条目True
的{{1}}列表不是空列表(whitePieces
)
1
或者您可以使用[]
:
map
此表达式:首先检查or (map (\x -> snd x == size) blackPieces)
的元素是否具有等于blackPieces
的第二个条目,并提供size
和Trues
的列表({{1} })然后函数Falses
给出[Bool]
,如果其中任何一个是or
答案 2 :(得分:2)
编译器不喜欢的原因是因为_
仅适用于模式匹配。下划线表示“我可以将这部分数据绑定到变量名称,但我不需要。”
您尝试使用它的方式不同:您基本上说“是否存在 x
,(x,1)
是whitePieces
的元素? “
你能看出区别吗?另请参阅Haskell 2010 > Expressions # Patter Matching