Итак, я работаю над минимаксной реализацией для игры, похожей на шашки, чтобы помочь мне лучше изучить Haskell. Функция, с которой у меня возникли проблемы, берет список состояний игры и генерирует список непосредственных преемников игры. Как и в шашках, если прыжок доступен, игрок должен его выполнить. Если их больше одного, игрок может выбрать.
По большей части это хорошо работает с монадой списка: цикл по всем входным состояниям игры, цикл по всем шарикам, которые можно перепрыгнуть, цикл по всем прыжкам этого мрамора. Эта монада списков в конце хорошо сглаживает все списки в простой список состояний.
Хитрость в том, что, если для данного игрового состояния не найдено никаких переходов, мне нужно вернуть текущее игровое состояние, а не пустой список. Приведенный ниже код - лучший способ сделать это, но мне он кажется ужасным. Любые предложения о том, как его почистить?
eHex :: Coord -> Coord -- Returns the coordinates immediately to the east on the board
nwHex :: Coord -> Coord -- Returns the coordinates immediately to the northwest on the board
generateJumpsIter :: [ZertzState] -> [ZertzState]
generateJumpsIter states = do
ws <- states
case children ws of
[] -> return ws
n@_ -> n
where
children ws@(ZertzState s1 s2 b p) = do
(c, color) <- occupiedCoords ws
(start, end) <- [(eHex, wHex), (wHex, eHex), (swHex, neHex),
(neHex, swHex), (nwHex, seHex), (seHex, nwHex)]
if (hexOccupied b $ start c) && (hexOpen b $ end c)
then case p of
1 -> return $ ZertzState (scoreMarble s1 color) s2
(jumpMarble (start c) c (end c) b) p
(-1) -> return $ ZertzState s1 (scoreMarble s2 color)
(jumpMarble (start c) c (end c) b) p
else []
РЕДАКТИРОВАТЬ: Предоставить пример подписей типов для функций * Hex.