Skip to content

Instantly share code, notes, and snippets.

@el-hult
Created July 6, 2021 12:25
Show Gist options
  • Save el-hult/c0c26e4d9cbc4cf39178d3da579380ba to your computer and use it in GitHub Desktop.
Save el-hult/c0c26e4d9cbc4cf39178d3da579380ba to your computer and use it in GitHub Desktop.
A simple haskell program that is the base minimum for a text based dungeon crawler.
module RPG where
import Text.Read (readMaybe)
type UIState = String
data Domain = Domain (UIState,World) deriving Show
data World = World {loc:: Int} deriving Show
data Dir = L | R deriving (Read, Show)
{- | By using the "deriving (Read)" we get a low-code input mechanism, but you should probalbly write
your own input parser
-}
data Event = EventExit | EventWalk Dir| EventLook deriving (Read)
-- | The run-loop has two steps. Render UI and get new events. Process events. Finally recurse.
run :: Domain -> [Event] -> IO ()
run dm [] = uiUpdate dm >> getAction >>= run dm
run _ (EventExit:_) = return ()
run dm (e:es) = run (dmUpdate dm e) es
{-| Update the domain when a single event acts on it -}
dmUpdate :: Domain -> Event -> Domain
dmUpdate (Domain v) (EventLook) = look (snd v)
dmUpdate (Domain v) (EventWalk direction) = walk direction (snd v)
dmUpdate dm _ = dm
look w = Domain ("You are at coordinate " ++ (show .loc $ w), w)
walk L w@World{loc=l}= Domain ("You went left", w{loc=l-1})
walk R w@World{loc=l} = Domain ("You went right", w{loc=l+1})
{-| Present the "output" that the domain holds for us -}
uiUpdate :: Domain -> IO ()
uiUpdate dm = do
let Domain (usState,s) = dm
putStrLn usState
{-| Ask user for input. Only a single event is collected. -}
getAction :: IO [Event]
getAction = do
putStrLn "What do you want to do? Choose between EventExit | EventWalk R | EventWalk L | EventLook"
act <- readMaybe <$> getLine
case act of
Nothing -> putStrLn "Not a valid action" >> getAction
Just evt -> pure [evt]
main :: IO ()
main = run (Domain ("",World 0)) [EventLook]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment