【问题标题】:Haskell - RecursionHaskell - 递归
【发布时间】:2015-11-21 17:44:00
【问题描述】:

我正在尝试制作一个纸牌游戏,两名玩家在那里展示牌,排名最高的人获胜并拿到牌。(战争纸牌游戏)。我遇到的麻烦是运行整个游戏,看看谁是赢家的最终结果。我已经做了可以做一轮游戏的代码:

type ComparisonRule = Card -> Card -> Bool
type RoundRule = ([Card],[Card]) -> ([Card],[Card])

standardComparison :: ComparisonRule
standardComparison (Card r1 _) (Card r2 _)
    | r1 > r2  = True
    |otherwise = False

roundWithoutWar :: ComparisonRule -> RoundRule
roundWithoutWar f (x:xs,y:ys)
        |f x y     = (xs ++ [x] ++ [y],ys)
        |f y x     = (xs,ys ++ [y] ++ [x])
        |otherwise = (xs,ys)

我用

standardRound :: RoundRule
standardRound =  roundWithoutWar standardComparison
to run one round of the game.

我正在尝试制作一个完整的游戏功能,以递归方式运行回合,直到有人获胜(获胜者是拥有最多牌的人):

fullGame :: RoundRule -> ([Card],[Card]) -> [([Card],[Card])]
fullGame r  ([],[]) = [([],[])]
fullGame r ([],y:ys)        = [([],y:ys)]
fullGame r (x:xs,[])      = [(x:xs,[])]
fullGame r (x:xs,y:ys)       = (x:xs,y:ys) : fullGame ( r (x:xs,y:ys))

“r”是单轮函数(StandardRound)但是,当我尝试运行完整的游戏函数时出现错误

 War_Project_2.hs:138:46:
    Couldn't match expected type ‘[([Card], [Card])]’
                with actual type ‘([Card], [Card]) -> [([Card], [Card])]’
    Probable cause: ‘fullGame’ is applied to too few arguments
    In the second argument of ‘(:)’, namely
      ‘fullGame (r (x : xs, y : ys))’
    In the expression: (x : xs, y : ys) : fullGame (r (x : xs, y : ys))

War_Project_2.hs:138:57:
    Couldn't match type ‘([Card], [Card])’
                   with ‘([Card], [Card]) -> ([Card], [Card])’

    Expected type: RoundRule
      Actual type: ([Card], [Card])
    Possible cause: ‘r’ is applied to too many arguments
    In the first argument of ‘fullGame’, namely ‘(r (x : xs, y : ys))’
    In the second argument of ‘(:)’, namely
      ‘fullGame (r (x : xs, y : ys))’

我尝试编写运行完整游戏的无点函数是:

simpleFullGame ::([Card],[Card]) -> [([Card],[Card])]
simpleFullGame = fullGame simpleRound

【问题讨论】:

  • fullGame ( r (x:xs,y:ys)) 应该是fullGame r ( r (x:xs,y:ys))

标签: haskell recursion functional-programming


【解决方案1】:

有一个有用的功能几乎可以完全满足您的需求。

  iterate :: (a -> a) -> a -> [a]

这可以连续应用你的RoundRule 函数,它本质上是一个更新函数。你所要做的就是在游戏结束后停下来。

done :: ([Card],[Card]) -> Bool

那么当你拥有这个功能时,你的完整游戏将是。

fullGame roundRule initState = takeWhile (not . done) (iterate roundRule initState)

由于 Haskell 是惰性的,它不会在游戏状态超过结束状态时生成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 2011-02-14
    • 2019-02-28
    • 2019-07-21
    • 2012-04-08
    相关资源
    最近更新 更多