Я хочу использовать реактивный банан, чтобы написать путевую игру, в которой люди могут писать ботов. FRP совершенно для меня совершенно, и у меня возникли проблемы с запуском. Когда я начал, я создал более сложный график, но для моих целей здесь я попытался сделать его максимально простым. Я хотел бы получить некоторые рекомендации, в основном о том, с чего начать, и как разбить эту большую проблему на более мелкие проблемы. Здесь начальный дизайн.
Идея состоит в том, чтобы иметь график LNodes (с взвешенными ребрами, на которые я сейчас игнорирую для простоты). Эти LNodes я описываю как Planet s. Planet имеют имя, карту игроков на Planet и Resource s. Игроки имеют идентификатор, ресурсы и планету. Здесь строятся данные и некоторые связанные с ними функции, за которыми следует больше обсуждений.
-- Graph-building records and functions
data PlanetName = Vulcan
                | Mongo
                | Arakis
                | Dantooine
                | Tatooine
                     deriving (Enum,Bounded,Show)
data Planet = Planet {pName :: PlanetName
                     ,player :: IntMap Player
                     ,resources :: Int
                     } deriving Show
data Player = Player {pid :: Int
                    ,resources :: Int
                    } deriving Show
makePlanetNodes :: PlanetName -> [LNode Planet]
makePlanetNodes planet = Prelude.map makePlanetNodes' $
                         zip [planet ..] [0 ..]
  where makePlanetNodes' (planet,i) =
          (i,Planet {pName = planet, players = IM.empty})
makePlanetGraph p = mkGraph p [(0,1,1),(1,2,2),(2,3,4),(3,4,3),(4,0,2)]
-- Networking and command functions
prepareSocket :: PortNumber -> IO Socket
prepareSocket port = do
   sock' <- socket AF_INET Stream defaultProtocol
   let socketAddress = SockAddrInet port 0000
   bindSocket sock' socketAddress
   listen sock' 1
   putStrLn $ "Listening on " ++ (show port)
   return sock'
acceptConnections :: Socket -> IO ()
acceptConnections sock' = do
   forever $ do
       (sock, sockAddr) <- Network.Socket.accept sock'
       handle <- socketToHandle sock ReadWriteMode
       sockHandler sock handle
sockHandler :: Socket -> Handle -> IO ()
sockHandler sock' handle = do
    hSetBuffering handle LineBuffering
    forkIO  $ commandProcessor handle
    return ()
commandProcessor :: Handle -> IO ()
commandProcessor handle = untilM (hIsEOF handle) handleCommand >> hClose handle
  where
    handleCommand = do
        line <- hGetLine handle
        let (cmd:arg) = words line
        case cmd of
            "echo" -> echoCommand handle arg
            "move" -> moveCommand handle arg
            "join" -> joinCommand handle arg
            "take" -> takeCommand handle arg
            "give" -> giveCommand handle arg
            _ -> do hPutStrLn handle "Unknown command"
echoCommand :: Handle -> [String] -> IO ()
echoCommand handle arg = do
    hPutStrLn handle (unwords arg)
moveCommand = undefined
joinCommand = undefined
takeCommand = undefined
giveCommand = undefined
Здесь, что я знаю до сих пор, мои события будут включать типы Planet и Player. поведения
будет включать в себя перемещение, соединение, принятие и предоставление. Когда игрок присоединяется, он создаст новое событие Player и обновит карту на Vulcan с помощью Player. Перемещение позволит пройти от одного
LNode к другому, если LNode соединены ребром. Take удалит resources из текущего Planet Player "on" и добавит те resources в
Player. Дайте будет делать обратное.
Как я могу разбить эту большую проблему на более мелкие проблемы, чтобы я мог разглядеть эту тему?
Обновление: Оказывается, Hunt Wumpus не является хорошим выбором, чтобы помочь узнать FRP, см. объяснение того, что FRP для здесь. Это в ответ Генрих Апфельмус.
Тем не менее, я полностью проигнорирую сетевой код. Я мог бы просто написать несколько фиктивных ботов для проверки времени и т.д.
Обновление. Некоторые люди, похоже, заинтересованы в этой проблеме, поэтому я собираюсь отслеживать связанные вопросы здесь.