Haskell Code Simplification

So I'm working on a minimax checker implementation to help myself learn more about Haskell. The function I am having problems with contains a list of game states and generates a list of immediate successor game states. Like checkers, if a jump is available, the player must take it. If there is more than one, the player can choose.

For the most part, this works great with the monad list: loop over all input game states, loops over all balls that could be jumped, loops over all jumps of this marble. This monad list nicely aligns all lists into a simple state list at the end.

The trick is that if no jumps are found for a given game state, I need to return the current state of the game, not an empty list. The code below is the best way I came up with this, but to me it seems ugly. Any suggestions for cleaning it?

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 []

EDIT: Specify type signature types for * Hex functions.

+3
source share
2 answers

The trick is that if no jumps are found for a given game state, I need to return the current state of the game, not an empty list.

Why? I wrote minimax several times, and I cannot imagine such a function. Wouldn't you be better off with a function like

nextStates :: [ZertzState] -> [Maybe [ZertzState]]

or

nextStates :: [ZertzState] -> [[ZertzState]]

, " , , ", , ,

nextStates :: [ZertzState] -> [Either ZertzState [ZertzState]]

.

,

[ZertzState] -> [(ZertzState, [ZertzState])]

(\(start, succs) -> if null succs then Left start else Right succs)

, .

(), , .

+3

, . , :

do x <- [1..3]
   y <- [2..5]      <=>  [ x + y | x <- [1..3], y <- [2..5] ]
   return x + y

""

listOfHex :: [(Coord -> Coord,Coord -> Coord)]
listOfHex = [ (eHex, wHex), (wHex, eHex), (swHex, neHex)
            , (neHex, swHex), (nwHex, seHex), (seHex, nwHex)]

generateJumpsIter :: [ZertzState] -> [ZertzState]
generateJumpsIter states =
    [if null ws then ws else children ws | ws <- states]
  where -- I named it foo because I don t know what it do....
    foo True   1  = ZertzState (scoreMarble s1 color) s2
                               (jumpMarble (start c) c (end c) b) p
    foo True (-1) = ZertzState s1 (scoreMarble s2 color)
                               (jumpMarble (start c) c (end c) b) p
    foo False  _  = []
    foo _ _ = error "Bleh"

    children ws@(ZertzState s1 s2 b p) =
      [ foo (valid c hex) p | (c, _)  <- occupiedCoords ws, hex <- listOfHex ]
        where valid c (start, end) =
                 (hexOccupied b $ start c) && (hexOpen b $ end c)

commprehension , , , . , (, foldr, foldl" ..), .

, .

+1

Source: https://habr.com/ru/post/1714381/


All Articles