Haskell game loop with keyboard handler
up vote
1
down vote
favorite
This is function, that works correctly, but it seems to be too ugly.
panel argument is never used for anything but pushing into refreshGamePanel,
and it seems to be too much case statements. How can I cleanup this?
runGameLoop :: Game -> Panel -> Curses GameResult
runGameLoop game panel
= if victory game then return Victory else
refreshGamePanel game panel >> render >> getPanelWindow panel >>=
flip getEvent (Just 1)
>>=
event' ->
case event' of
Nothing -> runGameLoop game panel
Just event -> case event of
EventSpecialKey (KeyFunction 2) -> return Restart
EventSpecialKey (KeyFunction 10) -> return Quit
EventSpecialKey key' -> case keyToDirection key' of
Nothing -> runGameLoop game panel
Just dir -> runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
haskell event-handling
add a comment |
up vote
1
down vote
favorite
This is function, that works correctly, but it seems to be too ugly.
panel argument is never used for anything but pushing into refreshGamePanel,
and it seems to be too much case statements. How can I cleanup this?
runGameLoop :: Game -> Panel -> Curses GameResult
runGameLoop game panel
= if victory game then return Victory else
refreshGamePanel game panel >> render >> getPanelWindow panel >>=
flip getEvent (Just 1)
>>=
event' ->
case event' of
Nothing -> runGameLoop game panel
Just event -> case event of
EventSpecialKey (KeyFunction 2) -> return Restart
EventSpecialKey (KeyFunction 10) -> return Quit
EventSpecialKey key' -> case keyToDirection key' of
Nothing -> runGameLoop game panel
Just dir -> runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
haskell event-handling
Did you try to usedonotation? Further, look for more idiomatic ways to deal withMaybe(how aboutfromMaybe?).
– Landei
Dec 3 '12 at 8:31
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
This is function, that works correctly, but it seems to be too ugly.
panel argument is never used for anything but pushing into refreshGamePanel,
and it seems to be too much case statements. How can I cleanup this?
runGameLoop :: Game -> Panel -> Curses GameResult
runGameLoop game panel
= if victory game then return Victory else
refreshGamePanel game panel >> render >> getPanelWindow panel >>=
flip getEvent (Just 1)
>>=
event' ->
case event' of
Nothing -> runGameLoop game panel
Just event -> case event of
EventSpecialKey (KeyFunction 2) -> return Restart
EventSpecialKey (KeyFunction 10) -> return Quit
EventSpecialKey key' -> case keyToDirection key' of
Nothing -> runGameLoop game panel
Just dir -> runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
haskell event-handling
This is function, that works correctly, but it seems to be too ugly.
panel argument is never used for anything but pushing into refreshGamePanel,
and it seems to be too much case statements. How can I cleanup this?
runGameLoop :: Game -> Panel -> Curses GameResult
runGameLoop game panel
= if victory game then return Victory else
refreshGamePanel game panel >> render >> getPanelWindow panel >>=
flip getEvent (Just 1)
>>=
event' ->
case event' of
Nothing -> runGameLoop game panel
Just event -> case event of
EventSpecialKey (KeyFunction 2) -> return Restart
EventSpecialKey (KeyFunction 10) -> return Quit
EventSpecialKey key' -> case keyToDirection key' of
Nothing -> runGameLoop game panel
Just dir -> runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
haskell event-handling
haskell event-handling
edited yesterday
200_success
127k15148410
127k15148410
asked Dec 2 '12 at 19:13
KAction
1333
1333
Did you try to usedonotation? Further, look for more idiomatic ways to deal withMaybe(how aboutfromMaybe?).
– Landei
Dec 3 '12 at 8:31
add a comment |
Did you try to usedonotation? Further, look for more idiomatic ways to deal withMaybe(how aboutfromMaybe?).
– Landei
Dec 3 '12 at 8:31
Did you try to use
do notation? Further, look for more idiomatic ways to deal with Maybe (how about fromMaybe ?).– Landei
Dec 3 '12 at 8:31
Did you try to use
do notation? Further, look for more idiomatic ways to deal with Maybe (how about fromMaybe ?).– Landei
Dec 3 '12 at 8:31
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.
runGameLoop game panel | victory game = return Victory
| otherwise = continue
where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
isRestart = (EventSpecialKey (KeyFunction 2) ==)
isQuit = (EventSpecialKey (KeyFunction 10) ==)
continue = do
refreshGamePanel game panel
render
anyEvent >>= case
Just (isRestart -> True) -> return Restart
Just (isQuit -> True) -> return Quit
Just (EventSpecialKey (keyToDirection -> Just dir)) ->
runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
Another variant is to consider using of Monad Maybe instance
runGameLoop game panel = nextStep where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
nextStep = if victory game then return Victory else do
refreshGamePanel game panel
render
liftM react anyEvent >>= case
Just continuation -> continuation
Nothing -> runGameLoop game panel
react event' = do
event' >>= case
EventSpecialKey (KeyFunction 2) -> return (return Restart)
EventSpecialKey (KeyFunction 10) -> return (return Quit)
EventSpecialKey key -> do
dir <- keyToDirection key
return (runGameLoop (makeMove game dir) panel)
_ -> Nothing
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.
runGameLoop game panel | victory game = return Victory
| otherwise = continue
where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
isRestart = (EventSpecialKey (KeyFunction 2) ==)
isQuit = (EventSpecialKey (KeyFunction 10) ==)
continue = do
refreshGamePanel game panel
render
anyEvent >>= case
Just (isRestart -> True) -> return Restart
Just (isQuit -> True) -> return Quit
Just (EventSpecialKey (keyToDirection -> Just dir)) ->
runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
Another variant is to consider using of Monad Maybe instance
runGameLoop game panel = nextStep where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
nextStep = if victory game then return Victory else do
refreshGamePanel game panel
render
liftM react anyEvent >>= case
Just continuation -> continuation
Nothing -> runGameLoop game panel
react event' = do
event' >>= case
EventSpecialKey (KeyFunction 2) -> return (return Restart)
EventSpecialKey (KeyFunction 10) -> return (return Quit)
EventSpecialKey key -> do
dir <- keyToDirection key
return (runGameLoop (makeMove game dir) panel)
_ -> Nothing
add a comment |
up vote
3
down vote
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.
runGameLoop game panel | victory game = return Victory
| otherwise = continue
where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
isRestart = (EventSpecialKey (KeyFunction 2) ==)
isQuit = (EventSpecialKey (KeyFunction 10) ==)
continue = do
refreshGamePanel game panel
render
anyEvent >>= case
Just (isRestart -> True) -> return Restart
Just (isQuit -> True) -> return Quit
Just (EventSpecialKey (keyToDirection -> Just dir)) ->
runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
Another variant is to consider using of Monad Maybe instance
runGameLoop game panel = nextStep where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
nextStep = if victory game then return Victory else do
refreshGamePanel game panel
render
liftM react anyEvent >>= case
Just continuation -> continuation
Nothing -> runGameLoop game panel
react event' = do
event' >>= case
EventSpecialKey (KeyFunction 2) -> return (return Restart)
EventSpecialKey (KeyFunction 10) -> return (return Quit)
EventSpecialKey key -> do
dir <- keyToDirection key
return (runGameLoop (makeMove game dir) panel)
_ -> Nothing
add a comment |
up vote
3
down vote
up vote
3
down vote
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.
runGameLoop game panel | victory game = return Victory
| otherwise = continue
where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
isRestart = (EventSpecialKey (KeyFunction 2) ==)
isQuit = (EventSpecialKey (KeyFunction 10) ==)
continue = do
refreshGamePanel game panel
render
anyEvent >>= case
Just (isRestart -> True) -> return Restart
Just (isQuit -> True) -> return Quit
Just (EventSpecialKey (keyToDirection -> Just dir)) ->
runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
Another variant is to consider using of Monad Maybe instance
runGameLoop game panel = nextStep where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
nextStep = if victory game then return Victory else do
refreshGamePanel game panel
render
liftM react anyEvent >>= case
Just continuation -> continuation
Nothing -> runGameLoop game panel
react event' = do
event' >>= case
EventSpecialKey (KeyFunction 2) -> return (return Restart)
EventSpecialKey (KeyFunction 10) -> return (return Quit)
EventSpecialKey key -> do
dir <- keyToDirection key
return (runGameLoop (makeMove game dir) panel)
_ -> Nothing
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.
runGameLoop game panel | victory game = return Victory
| otherwise = continue
where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
isRestart = (EventSpecialKey (KeyFunction 2) ==)
isQuit = (EventSpecialKey (KeyFunction 10) ==)
continue = do
refreshGamePanel game panel
render
anyEvent >>= case
Just (isRestart -> True) -> return Restart
Just (isQuit -> True) -> return Quit
Just (EventSpecialKey (keyToDirection -> Just dir)) ->
runGameLoop (makeMove game dir) panel
_ -> runGameLoop game panel
Another variant is to consider using of Monad Maybe instance
runGameLoop game panel = nextStep where
anyEvent = gatPanelWindow panel >>= flip getEvent (Just 1)
nextStep = if victory game then return Victory else do
refreshGamePanel game panel
render
liftM react anyEvent >>= case
Just continuation -> continuation
Nothing -> runGameLoop game panel
react event' = do
event' >>= case
EventSpecialKey (KeyFunction 2) -> return (return Restart)
EventSpecialKey (KeyFunction 10) -> return (return Quit)
EventSpecialKey key -> do
dir <- keyToDirection key
return (runGameLoop (makeMove game dir) panel)
_ -> Nothing
edited Dec 12 '12 at 21:36
answered Dec 12 '12 at 20:40
ony
61135
61135
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f19238%2fhaskell-game-loop-with-keyboard-handler%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Did you try to use
donotation? Further, look for more idiomatic ways to deal withMaybe(how aboutfromMaybe?).– Landei
Dec 3 '12 at 8:31