0
\$\begingroup\$

This code is to recreate the game 'Earthworms'. The part I need help with is the main :: IO() part. I want to split this part ...

          let aantalTegenspelers = 2
          let rijTegels = maakDeRijTegels
          let spelers = deSpelers ( aantalTegenspelers) firstName 

from the main IO() to a function createGame

I tried this

 createGame :: Int -> String -> IO ()
 createGame aantal firstName= do let rijTegels = volleRijTegels
                                    let spelers = deSpelers aantal firstName 
                                    w <- spelSpelen rijTegels spelers 0
                                    putStrLn (w ++ "dit is iets")

and then call it in main with

eindstand <- createGame (digitToInt aantalTegenspelers) firstName

Another thing I tried is


 eindstand <- spelSpelen rijTegels spelers 0 
            where rijTegels = volleRijTegels
                   spelers = deSpelers (digitToInt aantalTegenspelers) firstName  

But then it says "parse error on input ‘=’ Perhaps you need a 'let' in a 'do' block?"

I don't know where to look for the mistake. Whether it is syntax or semantics. Is there anyone who could tell me how to create the function and get the main split?

This is the whole code:

module Dobbelspel where

import Data.Char
import Data.List 
import System.IO
import System.Random
import Data.IORef

data Dobbelsteen = Steen Char 
                   deriving (Show, Eq)  
data Tegel = Teg Int Int 
             deriving (Show, Eq)  
data Speler = Spel Tactiek Spelersstapel String 
type Tactiek = ([Dobbelsteen]  -> [Dobbelsteen] -> IO [Dobbelsteen], [Dobbelsteen]  -> Int -> IO Bool)
type Spelersstapel = [Tegel]


------------------------------ROTZOOITJE MET MAIN  ...   NOG OPSCHONEN----------------------------------------- 

main :: IO ()  
main = do putStrLn ("Hoi! Je speelt regenwormen. Wat is je naam?")
          firstName <- getLine  
          putStrLn ("Beste "++ firstName ++ ", je speelt tegen twee computertegenstanders. Ze heten Lap en Top.")
         -- putStr "Tegen hoeveel computertegenstanders wil u spelen? (Dit spel is voor 2 tot 8 personen) Niet dat ik met dit getal iets ga doen, want de default waarde staat op 2 en die wordt gepakt "
      --    n <- getChar
          let aantalTegenspelers = 2 
          let rijTegels = maakDeRijTegels
          let spelers = deSpelers ( aantalTegenspelers) firstName 
    --      putStrLn ("Alle " ++ show (length rijTegels) ++ " tegels liggen klaar. " ++ firstName ++ " begint!")
          winnaar <- {-maakNieuwSpel (digitToInt aantalTegenspelers) firstName-} spelSpelen rijTegels spelers 0 (aantalTegenspelers +1) -- dit getal betekent wie er gaat beginnen
           {-     where rijTegels = maakDeRijTegels
                       spelers = deSpelers (digitToInt aantalTegenspelers) firstName  -}
          putStrLn ("Het spel is afgelopen. De eindstand is " ++ winnaar)

deSpelers :: Int -> String -> [Speler]
deSpelers aantalTegenspelers firstName = do [Spel {- HIERZOOOOOO -} computerTactiek [] firstName, Spel computerTactiek [] "Lap", Spel computerTactiek [] "Top"]

maakSpelers :: Int -> String -> IO [Speler]
maakSpelers n naam = undefined -- do return (spelers n+1 naam)

spelers 0 naam = [(naam, [], spelerTactiek)]
spelers n naam = [("Speler" ++ [(intToDigit n)], [], computerTactiek)]

maakDeRijTegels :: [Tegel] -- deze functie maakt de rij tegels van 21 tot 36.
maakDeRijTegels = zipWith Teg [21..36] (replicate 4 1 ++ replicate 4 2 ++ replicate 4 3 ++ replicate 4 4)


------------------------------SPEL SPELEN----------------------------------------- 

spelSpelen :: [Tegel]  -> [Speler]  -> Int -> Int -> IO String -- de RijTegels, de spelers en degene die gaat spelen (int)
spelSpelen []        spelers spelerNr aantalSpelers= do return (show (bepaalWinnaar spelers))
spelSpelen rijTegels spelers spelerNr aantalSpelers= do let Spel tactiek stapel naam = (spelers !! spelerNr) -- ??? wat betekent dit

                                                        putStrLn ("\nDeze speler is nu aan de beurt: " ++ naam)
                                                        score <- startBeurt tactiek (\x -> elem x (geldigeScore spelers naam rijTegels))
                                                        let rijTegelsNieuw = pakTegelAlsMogelijk rijTegels score
                                                        let rijTegelsTeruggelegdNieuw = geefTegelTerug spelers rijTegels score
                                                        let spelersAfgepaktNieuw = pakTegelAf spelers score
                                                        let spelersNieuw = voegTegelToeAanSpelerVanStapel spelersAfgepaktNieuw score naam rijTegelsTeruggelegdNieuw
                                                        putStrLn ("De beurt van speler " ++ naam ++ " is nu afgelopen.")
                                                        printStatus rijTegelsNieuw spelersNieuw
                                                        spelSpelen rijTegelsNieuw spelersNieuw ( (spelerNr+1) `mod` aantalSpelers) aantalSpelers  -- die 3 moet het aantal spelers zijn. 

geefTegelTerug :: [Speler]  -> [Tegel]  -> Int -> [Tegel] 
geefTegelTerug spelers rijTegels score = [stapel !! 0  | (Spel tactiek stapel naam) <- spelers,  (heeftTegelNr (stapel) score)] ++ rijTegels
     where 
          heeftTegelNr:: Spelersstapel -> Int -> Bool
          heeftTegelNr [] _ = False
          heeftTegelNr ((Teg nr waarde):xs) score = nr == score

pakTegelAf :: [Speler]  -> Int -> [Speler] 
pakTegelAf spelers score = [Spel tactiek (pakTegelAlsMogelijk stapel score) naam  | (Spel tactiek stapel naam) <- spelers]

voegTegelToeAanSpelerVanStapel :: [Speler]  -> Int -> String -> [Tegel]  -> [Speler] 
voegTegelToeAanSpelerVanStapel spelers score spelerAandeBeurt rijTegels = [ Spel tactiek (voegTegelToe rijTegels (Spel tactiek stapel naam) spelerAandeBeurt score ) naam | (Spel tactiek stapel naam) <- spelers]
     where
          voegTegelToe :: [Tegel]-> Speler -> String -> Int -> Spelersstapel
          voegTegelToe rijTegels (Spel _ stapel naam) spelerAandeBeurt score = if naam == spelerAandeBeurt then 
                                                                                 [Teg nr waarde | (Teg nr waarde)<- rijTegels, nr == score] ++ stapel
                                                                               else
                                                                                 stapel

bepaalWinnaar :: [Speler]  -> [(Int, String)]
bepaalWinnaar spelers = [    (sum [waarde | (Teg _ waarde) <- stapel], naam)   |   (Spel _ stapel naam) <- spelers]

printStatus :: [Tegel]  -> [Speler]  -> IO ()
printStatus rijTegels spelers = do putStrLn ("Overgebleven tegels zijn " ++ show rijTegels)
                                   putStrLn ("De gepakte tegels van de spelers zijn " ++ show [ (naam, stapel) | (Spel _ stapel naam) <- spelers])

pakTegelAlsMogelijk :: [Tegel] -> Int -> Spelersstapel
pakTegelAlsMogelijk stapel score = [Teg nr waarde | (Teg nr waarde) <- stapel, not(nr == score)]

geldigeScore :: [Speler]  -> String -> [Tegel]  -> [Int]
geldigeScore spelers spelerNrAandeBeurt tegels = [x | (Teg x _) <- tegels] ++ [y | (Teg y _) <- (geefBovensteTegelSpelers spelers spelerNrAandeBeurt)]

geefBovensteTegelSpelers :: [Speler]  -> String -> [Tegel] 
geefBovensteTegelSpelers spelers spelerAandeBeurt = [stapel!!0 | (Spel _ stapel naam) <- spelers, not (null stapel) , not (naam == spelerAandeBeurt)]


------------------------------BEURT---------------------------------------- 

startBeurt :: Tactiek -> (Int -> Bool) -> IO Int
startBeurt (pakken, doorgaan) f = do stenen <- worp 8
                                     putStrLn ("Je hebt deze stenen geworpen: " ++ (intercalate ", " [[x] | Steen x <- stenen] ))
                                     gepakteStenen <- pakken stenen []
                                     restvdBeurt (pakken, doorgaan) f gepakteStenen

restvdBeurt :: Tactiek -> (Int -> Bool) -> [Dobbelsteen]  -> IO Int
restvdBeurt (pakken, doorgaan) f gepakteStenen = do stenen <- worp (8 - (length gepakteStenen))
                                                    putStrLn ("worp: " ++ intercalate ", " [[x] | Steen x <- stenen]  ++ "     -- Al gepakte stenen: (" ++ intercalate ", " [[x] | Steen x <- gepakteStenen] ++ ")")
                                                    if kanSpelerPakken stenen gepakteStenen then
                                                      do gepakteStenenDezeBeurt <- pakken stenen gepakteStenen
                                                         let alleStenen = gepakteStenen ++ gepakteStenenDezeBeurt
                                                         let score = sum[if d == 'W' then 5 else digitToInt d | (Steen d) <- alleStenen]
                                                         if scoreControle alleStenen f score then
                                                          do gaDoor <- doorgaan alleStenen score
                                                             if gaDoor then 
                                                               do restvdBeurt (pakken, doorgaan) f alleStenen
                                                             else
                                                               return score
                                                             else
                                                               do restvdBeurt (pakken, doorgaan) f alleStenen
                                                    else 
                                                     do putStrLn ("Helaas! Je kan niet meer pakken! Je score is 0")
                                                        return 0

scoreControle:: [Dobbelsteen] -> (Int -> Bool) -> Int -> Bool 
scoreControle alleStenen functie score = if length [x | Steen(x) <- alleStenen, x == 'W'] > 0 && (if functie score then True else False ) then True
                                   else  False

worp :: Int -> IO [Dobbelsteen]   -- goed
worp 0 = return []
worp aantalStenen = do x  <- randomRIO (1,6::Int)
                       xs <- worp (aantalStenen-1)
                       return (Steen (['1', '2', '3', '4', '5', 'W'] !! (x-1)):xs)

kanSpelerPakken :: [Dobbelsteen] -> [Dobbelsteen]  -> Bool
kanSpelerPakken stenen gepakteStenen = length [Steen x | Steen (x) <- stenen, (aantalStenenInLijst gepakteStenen (x:"")) == 0] > 0

aantalStenenInLijst :: [Dobbelsteen] -> String -> Int
aantalStenenInLijst stenen [] = 0
aantalStenenInLijst stenen keuzeSteen = length [Steen x | Steen (x) <- stenen , x == (keuzeSteen !! 0)]
------------------------------INTERACTIEVE SPELER----------------------------- 
spelerTactiek :: Tactiek
spelerTactiek = (pakkenSpeler, doorgaanSpeler)

pakkenSpeler :: [Dobbelsteen] -> [Dobbelsteen]  -> IO [Dobbelsteen]
pakkenSpeler stenen gepakteStenen = do putStr ("Kies welke dobbelstenen je opzij wil leggen, minimaal 1.\n")
                                       putStr ("Deze steen moet een andere letter/cijfer hebben dan wat je al gepakt hebt.\n")
                                       putStr ("Typ in welke soort steen je wil pakken: ")
                                       keuzeSteen <- getLine
                                       if (aantalStenenInLijst stenen keuzeSteen) < 1 {-|| (aantalStenenInLijst gepakteStenen keuzeSteen) > 0)-} then--isGepakteSteenOngeldig stenen gepakteStenen keuzeSteen then
                                         do putStrLn ("Je hebt deze leter/cijfer niet gegooid. Pak iets anders.")
                                            pakkenSpeler stenen gepakteStenen
                                       else if (aantalStenenInLijst gepakteStenen keuzeSteen) > 0 then
                                         do putStrLn ("Je hebt deze steen al. Pak iets anders.")
                                            pakkenSpeler stenen gepakteStenen
                                       else
                                         return [Steen x | Steen (x) <- stenen , x == (keuzeSteen !! 0)]

doorgaanSpeler :: [Dobbelsteen]  -> Int -> IO Bool
doorgaanSpeler gepakteStenen score = do putStr ("doorgaan (score is " ++ show score ++ ")?(j/n)")
                                        doorgaan <- getLine
                                        if doorgaan == "j" then
                                          do return True
                                        else
                                          do putStrLn ("score is " ++ show score)
                                             return False

------------------------------EENVOUDIGE SPELCOMPUTER----------------------------- 
computerTactiek :: Tactiek
computerTactiek = (pakkenComputer, doorgaanComputer)

pakkenComputer :: [Dobbelsteen] -> [Dobbelsteen]  -> IO [Dobbelsteen] 
pakkenComputer stenen gepakteStenen = do return [Steen x | Steen(x) <- stenen, x == maximum [x | Steen (x) <- stenen, (aantalStenenInLijst gepakteStenen (x:[])) == 0]]

doorgaanComputer :: [Dobbelsteen]  -> Int -> IO Bool
doorgaanComputer gepakteStenen score = do putStrLn ("computer stopt met " ++ intercalate ", " [[x] | Steen x <- gepakteStenen]  ++ " (score is " ++ show score ++ ")")
                                          return False


New contributor
Elzine Burger is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

put on hold as off-topic by esote, 200_success, pacmaninbw, Edward, яүυк 2 days ago

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – esote, 200_success, pacmaninbw, Edward, яүυк
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ This is a request for a specific rewrite, not a request for review. Please take a look at the help center and note that we only deal with questions that request reviews here. \$\endgroup\$ – Mast Apr 17 at 10:57
  • \$\begingroup\$ An unrelated side-note: please stick to English when programming software you might want to share with others. Code should be self-explanatory, and yours is only so when you happen to know Dutch. There's a lot more people on the internet fluent in English than in Dutch ;-) \$\endgroup\$ – Mast Apr 17 at 10:58
0
\$\begingroup\$

I fixed it! Jeahj :)


main :: IO ()  
main = do putStrLn ("Hoi! Je speelt regenwormen. Wat is je naam?")
          firstName <- getLine  
          putStrLn ("Beste "++ firstName ++ ", je speelt tegen twee computertegenstanders. Ze heten Lap en Top.")
          winnaar <- startSpel firstName
          putStrLn ("Het spel is afgelopen. De eindstand is " ++ winnaar)

startSpel :: String -> IO String
startSpel firstName = do putStrLn ("Beste "++ firstName ++ ", je speelt tegen twee computertegenstanders. Ze heten Lap en Top.")
                         let aantalTegenspelers = 2 -- (digitToInt n) -- voor zo lang ik nog niks geïmplementeerd heb om zelf aantal spelers te kunnen kiezen
                         let rijTegels = maakDeRijTegels
                         let spelers = deSpelers ( aantalTegenspelers) firstName  
                         winnaar <- spelSpelen rijTegels spelers 0 (aantalTegenspelers +1) -- dit getal betekent wie er gaat beginnen
                         return (winnaar)
New contributor
Elzine Burger is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.