【问题标题】:Changing variables inside a recursive function在递归函数中更改变量
【发布时间】:2015-10-30 23:58:40
【问题描述】:

我正在尝试用 Haskell 制作游戏。现在,我正在处理敌人的碰撞问题:也就是说,如果敌人与玩家发生碰撞,则分数会重置为 0,并且敌人会死亡。但是,我就是不知道如何

我已经考虑过do 块,但这是不对的(我不想返回 IO)。我找不到任何可以为我指明正确方向的东西,让我怀疑这是否可能......

我拥有的(有点难看的)代码是这样的:

newEnemies = updateEnemies enemies
    updateEnemies :: [Point] -> [Point]
    updateEnemies [] = []
    updateEnemies (x:xs) | hitPlayer (nextLocation x) = -- TODO: Reset multipliers
                                                        updateEnemies xs
                         | otherwise = nextLocation x : updateEnemies xs
        where
        hitPlayer :: Point -> Bool
        hitPlayer (x, y) | abs (fst newPosition - x) < 10 && abs (snd newPosition - y) < 10
                            = True
                         | otherwise = False
        nextLocation loc = (loc + ((dirToPlayer loc) * (100, 100) * (timeStep, timeStep)))
        dirToPlayer loc = normalizeV (playerPosition - loc)

你们谁能指出我正确的方向,还是我太习惯命令式语言了?

谢谢!

【问题讨论】:

  • 如果您的函数不返回分数,您希望它如何重置分数?如果你想重构,那么我建议你使用 State monad。相反,如果您想从当前代码逐步改进,请考虑创建updateEnemies :: Score -&gt; [Point] -&gt; (Score, [Point])。如果命中,您返回(0, updateEnemies xs)
  • 那么,我尝试做的事情不起作用?我同样害怕。无论如何,谢谢,我要试试别的!

标签: haskell recursion


【解决方案1】:

所有updateEnemies 真正做的是将nextLocation 应用于输入列表的每个元素,然后丢弃hitPlayer 的元素。因此,主体可以简化为:

updateEnemies xs = filter (not . hitPlayer) $ map nextLocation xs

或者,如果您更喜欢免积分:

updateEnemies = filter (not . hitPlayer) . map nextLocation

另外,定义hitPlayer,用一个守卫来决定是返回True还是False是错误的;其他语言中的等效错误是写if (condition) return true; else return false;。直接返回测试结果即可!

hitPlayer (x, y) = abs (fst newPosition - x) < 10 && abs (snd newPosition - y) < 10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2020-10-02
    • 2015-09-27
    • 2021-12-11
    相关资源
    最近更新 更多