私はハスケルをよりよく学ぶのに役立つチェッカーのようなゲームのミニマックスの実装に取り組んでいます。私が問題を抱えている関数は、ゲーム状態のリストをとり、直後のゲーム状態のリストを生成します。チェッカーのように、ジャンプが利用可能な場合、プレイヤーはそれを取る必要があります。複数ある場合は、選ぶことができます。いくつかのハスケルコードを簡略化
ほとんどの場合、入力されたすべてのゲーム状態に対してmonad:loopというリストがうまく機能し、ジャンプできるすべての大理石をループし、その大理石のすべてのジャンプをループします。このリストモナドは、すべてのリストを終わりに単純な状態リストにまとめることができます。
トリックは、特定のゲーム状態でジャンプが見つからない場合は、空のリストではなく現在のゲーム状態を返す必要があるということです。下のコードは私がこれをやっている最善の方法ですが、それは私には本当に醜いようです。どのようにそれをきれいにする上の任意の提案?
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
[email protected]_ -> n
where
children [email protected](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 []
EDIT:* Hex関数のサンプル署名を提供します。
これは、minimaxへの入力の一部である可能な移動の集合を生成するためのコードのちょうど_part_です。特に、利用可能なジャンプの生成に関係する部分です。 – Resistor
ルールはチェッカーのようなものです:利用可能なジャンプがある場合、それを実行する必要があります。利用可能なものが複数ある場合、プレイヤーはどちらを取るかを選択できます。連鎖ジャンプ(チェッカーでのダブルジャンプ)は許可され、同じ必要な場合は同じルールが適用されます。 – Resistor
私はこれを再帰的に生成された状態のツリーと考えています。私は最初の状態を含むリストから始めます。それから、私は、最大で1回離れて到達可能な状態のリストを生成します。それらから、私はリストが変わるのを止めるまで、このプロセスを繰り返します。 「デッドエンド」の状態がリストに残り、空のリストに行く場合にのみ有効です。 – Resistor