Created
July 6, 2021 12:25
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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