我正在努力确定一个有效的举措。移动必须满足两个条件才能使其成为有效的移动。第一个条件是确保在我想要移动的位置上没有现有的棋子,第二个条件是确保我在移动时得分。
我已经完成了第一个条件的代码,但我不知道如何在第二个条件下执行此操作。也许之所以困难,是因为它返回了一个Bool,当满足其他条件之一时,需要将其设置为True或False。例如
valid :: Piece -> Pieces -> Bool
valid p [] = True
valid p (x:xs) | getPos(p) == getPos(x) = False
| otherwise = valid p xs
你可以看到,我已经完成了第一个条件的代码,现在我该如何添加第二个条件?
像
这样的东西valid :: Piece -> Pieces -> Bool
valid p [] = True
valid p (x:xs) | getPos(p) == getPos(x) = False
| otherwise = valid p xs
&& ...
但是,如果第一个条件失败或通过,此函数将停止。这是为了解决这个问题吗?
编辑:声明
data Piece = Piece Position Player
type Pieces = [Piece]
编辑:getPos
getPos是一个检索作品位置的函数
答案 0 :(得分:4)
您可以将空位置的测试移动到辅助函数(例如vacant
)并在valid
中写下您的其他条件,例如使用其他score
函数:< / p>
valid :: Piece -> Pieces -> Bool
valid p xs = vacant p xs && score p xs > 0
vacant :: Piece -> Pieces -> Bool
vacant p [] = True
vacant p (x:xs)
| getPos p == getPos x = False
| otherwise = vacant p xs
score :: Piece -> Pieces -> Int
score p xs = error "TODO"
您还可以更简单地表达vacant
,避免显式递归:
import Data.List (notElem)
vacant p xs = getPos p `notElem` map getPos xs
但是,我猜计算得分取决于这一举动是否可行。因此,您可能会发现将其转换为单个函数是一种改进,该函数测试具有正分数的有效移动并返回Maybe
:
score :: Piece -> Pieces -> Maybe Int
score p xs
| getPos p `notElem` map getPos xs = let
computedScore = error "TODO"
in if computedScore > 0
then Just computedScore
else Nothing
| otherwise = Nothing
现在,您可以对score
的结果进行模式匹配:如果您获得Nothing
,那么移动无效或未获得正分数;如果您获得Just s
,则此移动有效并产生得分s
。