Vocabulary memory game in Haskell
up vote
2
down vote
favorite
As a beginner I try to implement a vokable memory game. It is still missing some feature (Loading, Display), but I would like to hear how to improve what is already there.
The user should identify matching pairs. Theses are then removed from the game. The game ends when there are not any pairs left.
I think there has to be nicer way to write the code for game' in mainLoop.
Any other suggestions to improve the code are also welcome.
module Main where
import Data.Maybe (fromMaybe)
import qualified Data.List.Safe as List
import Data.List (foldl')
type Vokabel = (String,String)
data Tile = Tile { _front :: Bool
, _vokabel :: Vokabel
} deriving (Show)
instance Eq Tile where
(==) (Tile _ v1) (Tile _ v2) = v1 == v2
getText :: Tile -> String
getText (Tile b (s1,s2)) | b = s1
| not b = s2
newtype Game = Game { _tiles :: [Tile]
} deriving Show
displayGame :: Game -> String
displayGame g = let
tile2Line s x = s ++ getText x ++ "n"
in foldl' tile2Line "" . _tiles $ g --(foldl' "" tile2Line) . _tiles $ g
makeTile s = Tile True (s++"-Front",s++"-Back")
makeVok s = (s++"-Front",s++"-Back")
gameExampel :: Game
gameExampel = generateGame . map makeVok $ ["Alpha","Beta","Gamma"]
generateGame :: [Vokabel] -> Game
generateGame vs = Game (map (Tile True) vs ++ map (Tile False) vs)
main :: IO ()
main = do
putStrLn "Vokabel Memory"
mainLoop gameExampel
pure ()
chooseTile :: Game -> Int -> Maybe Tile
chooseTile g x = _tiles g List.!! x
mainLoop :: Game -> IO ()
mainLoop game = do
putStrLn . displayGame $ game
putStrLn "choose Tile, or exit"
input <- getLine
if input == "exit"
then
do
putStrLn "exit now!"
pure()
else
do
let indexA = read input
let choosenTileA = chooseTile game indexA
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileA)
indexB <- read <$> getLine
let choosenTileB = chooseTile game indexB
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileB)
let game' = fromMaybe game (do
vokA <- _vokabel <$> choosenTileA
vokB <- _vokabel <$> choosenTileB
if vokA == vokB && indexA /= indexB then
Game <$> ((List.delete <$> choosenTileB) <*> ((List.delete <$> choosenTileA) <*> (pure . _tiles $ game)))
else
pure game
)
if null . drop 1 . _tiles $ game' then
return ()
else
mainLoop game'
EDIT: Having thought about it: I would like to know how to use the state monade in this example.
beginner game haskell
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
up vote
2
down vote
favorite
As a beginner I try to implement a vokable memory game. It is still missing some feature (Loading, Display), but I would like to hear how to improve what is already there.
The user should identify matching pairs. Theses are then removed from the game. The game ends when there are not any pairs left.
I think there has to be nicer way to write the code for game' in mainLoop.
Any other suggestions to improve the code are also welcome.
module Main where
import Data.Maybe (fromMaybe)
import qualified Data.List.Safe as List
import Data.List (foldl')
type Vokabel = (String,String)
data Tile = Tile { _front :: Bool
, _vokabel :: Vokabel
} deriving (Show)
instance Eq Tile where
(==) (Tile _ v1) (Tile _ v2) = v1 == v2
getText :: Tile -> String
getText (Tile b (s1,s2)) | b = s1
| not b = s2
newtype Game = Game { _tiles :: [Tile]
} deriving Show
displayGame :: Game -> String
displayGame g = let
tile2Line s x = s ++ getText x ++ "n"
in foldl' tile2Line "" . _tiles $ g --(foldl' "" tile2Line) . _tiles $ g
makeTile s = Tile True (s++"-Front",s++"-Back")
makeVok s = (s++"-Front",s++"-Back")
gameExampel :: Game
gameExampel = generateGame . map makeVok $ ["Alpha","Beta","Gamma"]
generateGame :: [Vokabel] -> Game
generateGame vs = Game (map (Tile True) vs ++ map (Tile False) vs)
main :: IO ()
main = do
putStrLn "Vokabel Memory"
mainLoop gameExampel
pure ()
chooseTile :: Game -> Int -> Maybe Tile
chooseTile g x = _tiles g List.!! x
mainLoop :: Game -> IO ()
mainLoop game = do
putStrLn . displayGame $ game
putStrLn "choose Tile, or exit"
input <- getLine
if input == "exit"
then
do
putStrLn "exit now!"
pure()
else
do
let indexA = read input
let choosenTileA = chooseTile game indexA
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileA)
indexB <- read <$> getLine
let choosenTileB = chooseTile game indexB
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileB)
let game' = fromMaybe game (do
vokA <- _vokabel <$> choosenTileA
vokB <- _vokabel <$> choosenTileB
if vokA == vokB && indexA /= indexB then
Game <$> ((List.delete <$> choosenTileB) <*> ((List.delete <$> choosenTileA) <*> (pure . _tiles $ game)))
else
pure game
)
if null . drop 1 . _tiles $ game' then
return ()
else
mainLoop game'
EDIT: Having thought about it: I would like to know how to use the state monade in this example.
beginner game haskell
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
As a beginner I try to implement a vokable memory game. It is still missing some feature (Loading, Display), but I would like to hear how to improve what is already there.
The user should identify matching pairs. Theses are then removed from the game. The game ends when there are not any pairs left.
I think there has to be nicer way to write the code for game' in mainLoop.
Any other suggestions to improve the code are also welcome.
module Main where
import Data.Maybe (fromMaybe)
import qualified Data.List.Safe as List
import Data.List (foldl')
type Vokabel = (String,String)
data Tile = Tile { _front :: Bool
, _vokabel :: Vokabel
} deriving (Show)
instance Eq Tile where
(==) (Tile _ v1) (Tile _ v2) = v1 == v2
getText :: Tile -> String
getText (Tile b (s1,s2)) | b = s1
| not b = s2
newtype Game = Game { _tiles :: [Tile]
} deriving Show
displayGame :: Game -> String
displayGame g = let
tile2Line s x = s ++ getText x ++ "n"
in foldl' tile2Line "" . _tiles $ g --(foldl' "" tile2Line) . _tiles $ g
makeTile s = Tile True (s++"-Front",s++"-Back")
makeVok s = (s++"-Front",s++"-Back")
gameExampel :: Game
gameExampel = generateGame . map makeVok $ ["Alpha","Beta","Gamma"]
generateGame :: [Vokabel] -> Game
generateGame vs = Game (map (Tile True) vs ++ map (Tile False) vs)
main :: IO ()
main = do
putStrLn "Vokabel Memory"
mainLoop gameExampel
pure ()
chooseTile :: Game -> Int -> Maybe Tile
chooseTile g x = _tiles g List.!! x
mainLoop :: Game -> IO ()
mainLoop game = do
putStrLn . displayGame $ game
putStrLn "choose Tile, or exit"
input <- getLine
if input == "exit"
then
do
putStrLn "exit now!"
pure()
else
do
let indexA = read input
let choosenTileA = chooseTile game indexA
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileA)
indexB <- read <$> getLine
let choosenTileB = chooseTile game indexB
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileB)
let game' = fromMaybe game (do
vokA <- _vokabel <$> choosenTileA
vokB <- _vokabel <$> choosenTileB
if vokA == vokB && indexA /= indexB then
Game <$> ((List.delete <$> choosenTileB) <*> ((List.delete <$> choosenTileA) <*> (pure . _tiles $ game)))
else
pure game
)
if null . drop 1 . _tiles $ game' then
return ()
else
mainLoop game'
EDIT: Having thought about it: I would like to know how to use the state monade in this example.
beginner game haskell
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
As a beginner I try to implement a vokable memory game. It is still missing some feature (Loading, Display), but I would like to hear how to improve what is already there.
The user should identify matching pairs. Theses are then removed from the game. The game ends when there are not any pairs left.
I think there has to be nicer way to write the code for game' in mainLoop.
Any other suggestions to improve the code are also welcome.
module Main where
import Data.Maybe (fromMaybe)
import qualified Data.List.Safe as List
import Data.List (foldl')
type Vokabel = (String,String)
data Tile = Tile { _front :: Bool
, _vokabel :: Vokabel
} deriving (Show)
instance Eq Tile where
(==) (Tile _ v1) (Tile _ v2) = v1 == v2
getText :: Tile -> String
getText (Tile b (s1,s2)) | b = s1
| not b = s2
newtype Game = Game { _tiles :: [Tile]
} deriving Show
displayGame :: Game -> String
displayGame g = let
tile2Line s x = s ++ getText x ++ "n"
in foldl' tile2Line "" . _tiles $ g --(foldl' "" tile2Line) . _tiles $ g
makeTile s = Tile True (s++"-Front",s++"-Back")
makeVok s = (s++"-Front",s++"-Back")
gameExampel :: Game
gameExampel = generateGame . map makeVok $ ["Alpha","Beta","Gamma"]
generateGame :: [Vokabel] -> Game
generateGame vs = Game (map (Tile True) vs ++ map (Tile False) vs)
main :: IO ()
main = do
putStrLn "Vokabel Memory"
mainLoop gameExampel
pure ()
chooseTile :: Game -> Int -> Maybe Tile
chooseTile g x = _tiles g List.!! x
mainLoop :: Game -> IO ()
mainLoop game = do
putStrLn . displayGame $ game
putStrLn "choose Tile, or exit"
input <- getLine
if input == "exit"
then
do
putStrLn "exit now!"
pure()
else
do
let indexA = read input
let choosenTileA = chooseTile game indexA
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileA)
indexB <- read <$> getLine
let choosenTileB = chooseTile game indexB
putStrLn ("choosen: " ++ maybe "nothing" getText choosenTileB)
let game' = fromMaybe game (do
vokA <- _vokabel <$> choosenTileA
vokB <- _vokabel <$> choosenTileB
if vokA == vokB && indexA /= indexB then
Game <$> ((List.delete <$> choosenTileB) <*> ((List.delete <$> choosenTileA) <*> (pure . _tiles $ game)))
else
pure game
)
if null . drop 1 . _tiles $ game' then
return ()
else
mainLoop game'
EDIT: Having thought about it: I would like to know how to use the state monade in this example.
beginner game haskell
beginner game haskell
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited yesterday
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 2 days ago
Drei
113
113
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Drei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Drei is a new contributor. Be nice, and check out our Code of Conduct.
Drei is a new contributor. Be nice, and check out our Code of Conduct.
Drei is a new contributor. Be nice, and check out our Code of Conduct.
Drei is a new contributor. Be nice, and check out our Code of Conduct.
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%2f208347%2fvocabulary-memory-game-in-haskell%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