そこで私はチェッカーのようなゲームのミニマックスの実装に取り組んでおり、Haskell をよりよく学べるようにしています。私が問題を抱えている関数は、ゲームの状態のリストを取得し、直後の後続のゲームの状態のリストを生成します。チェッカーと同様に、ジャンプが利用可能な場合、プレーヤーはジャンプする必要があります。複数ある場合は、プレイヤーが選択できます。
ほとんどの場合、これは list モナドとうまく機能します: すべての入力ゲーム状態をループし、ジャンプできるすべてのビー玉をループし、そのビー玉のすべてのジャンプをループします。このリストモナドは、最後にすべてのリストを単純な状態のリストにうまくフラット化します。
トリックは、特定のゲーム ステートでジャンプが見つからない場合、空のリストではなく、現在のゲーム ステートを返す必要があるということです。以下のコードは、私が思いついた最良の方法ですが、私には本当に醜いようです。それをきれいにする方法について何か提案はありますか?
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 関数の型シグネチャの例を提供します。