2012-10-23 68 views
2

的問題是,我不知道如何創建類型Behavior t GameState功能香蕉旅行者 - 組建行爲牛逼的遊戲狀態

的行爲我有更多的代碼,但我想只顯示我認爲時,只需要談關於這個問題。讓我知道,如果有空格中填寫以下是我有:

data GameState = GameState {agent :: Agent 
          ,universe :: Universe 
          } 

type Universe = Gr Planet() 

data Command = Move PlanetName 
      | Look 
      | Quit 
       deriving Show 

data PlayerCommand = PlayerCommand Command PID 
        | Null 
         deriving Show 

updateGS :: PlayerCommand -> GameState -> GameState 
updateGS (PlayerCommand (Move planet) pid) gs = 
    let agent = getAgent pid gs 
     nodes = labNodes $ universe gs 
     current = location agent 
     Just fromP = lookup (fromEnum current) nodes 
     Just toP = lookup (fromEnum planet) nodes 
     fromNode = fromEnum current 
     toNode = fromEnum planet 
     uPlayer = Player pid (getPlanetName toP) (Location planet) 
     mData = MoveData uPlayer (toNode,toP) (fromNode,fromP) nodes 
     uPlanets = updateLNodeList mData 
    in GameState uPlayer (mkGraph uPlanets $ labUEdges gates 

initialGS :: GameState 
initialGS = GameState initPlayer (makeUniverse makePlanetNodes) 

和事件網絡

makeNetworkDescription :: AddHandler PlayerCommand -> IO EventNetwork 
makeNetworkDescription addCommandEvent = compile $ do 
    eInput <- fromAddHandler addCommandEvent 
    let bCommand = stepper Null eInput 
    eCommandChanged <- changes bCommand 
    let bGameState :: Behavior t GameState 
     bGameState = stepper initialGS 
    reactimate $ (\n -> appendFile "output.txt" ("Command is " ++ show n)) <$> eCommandChanged 

我相信bGameState需要使用eCommandChange,但我遇到一個問題類型

stepper :: a -> Event t a -> Behavior t a 

這使我相信,我需要改造eInput :: Event t PlayerCommandeGameState :: Event t GameState,我可以使用stepper使Behavior t GameState

所以,我的問題是,我的思路是否正確?如果不是,我可以重新定向嗎?如果是這樣,eGameState :: Event t GameState會是什麼樣子?

針對下面的迴應。當我最初考慮accumB時,我看到了製作中的類型錯誤。當我嘗試你的建議時發生了什麼。

let bGameState :: Behavior t GameState 
    bGameState = accumB initialGS $ updateGS <$ eInput 

產生錯誤

Couldn't match expected type `GameState' 
      with actual type `PlayerCommand' 
Expected type: GameState -> GameState 
    Actual type: PlayerCommand -> GameState -> GameState 
In the first argument of `(<$)', namely `updateGS' 
In the second argument of `($)', namely `updateGS <$ eInput' 

不知道該怎麼做了一番。我會看看你的例子,看看答案是否清晰。感謝您的排除accumB是正確的路要走,因爲我專注於stepper

我研究建議的代碼越多,我越感到困惑的類型錯誤。

回答

2

的確,您需要創建一個記錄GameState的事件,並將updateGS函數應用於其中以創建一個新事件。這是功能accumE及其表弟accumB的目的。特別是,你可以寫

bGameState = accumB initialGS $ updateGS <$> eInput 

要了解更多關於這種模式,看看在examples pages,特別是Counter.hs和TwoCounters.hs實例的實例。


還有一點值得一提的是,我建議避免changes功能,除非你是在處理低級別的框架的東西。正如文件中指出的那樣,它有幾個限制;最難受的限制是該值在執行reactimate之前不可用。你可以很容易地做出一個無限循環,其目的非常狹窄。

在你的情況下,bCommand無論如何似乎是多餘的,你有eCommandChanged = eInput

士氣:將事件轉化爲行爲很容易,但是沒有回頭路。

+0

我改變了'(<$)' to '(<$>)'但它需要被批准。 –

+0

謝謝。我沒有收到任何有關您的編輯的消息,但我自己就改變了它。 –