2011-07-22 8 views
7

Jestem nowy w Haskell, więc staram się stworzyć prostą grę tekstową dla dwóch graczy, aby pomóc mi się jej nauczyć.Problem z "Looping" IO w Haskell

Jednak natrafiłem na problem wykonywania IO w "pętli". O ile mi wiadomo, zmienne, które są ustawione z danych wprowadzonych przez użytkownika, nie mogą być używane, chyba że są ustawione w głównym. Jest to problem, ponieważ wywołanie rekurencyjne do main jest dla mnie bezużyteczne, ponieważ main nie przyjmuje żadnych argumentów. Idealnie, miałbym funkcję wywoływaną z głównego, która sama się nazywa, dopóki jeden gracz nie przegra. Ale wydaje się, że to nie działa, ponieważ użycie jakichkolwiek zmiennych ustawionych w tej funkcji przez dane wejściowe użytkownika powoduje błędy typu.

Struktura programu jest następujący:

* Gracz 1 wiersza dla nazwy i ustawić zmienną Gracz1.

* Podaj nazwę gracza 2 dla nazwy i ustaw zmienną player2.

* "Pętla": Alternatywna dla każdego gracza, z prośbą o polecenia, dopóki jeden gracz nie przegra.

Jaki byłby najlepszy sposób rozwiązania tego problemu?

Odpowiedz

22

Idealnie byłoby mieć funkcję wywoływaną z głównej, która nazywa się , dopóki jeden gracz nie przegra. Wydaje się jednak, że to nie działa, ponieważ użycie zmiennych zdefiniowanych w tej funkcji przez dane wejściowe użytkownika powoduje błędy typu .

Jest to całkowicie możliwe. Następnym razem prosimy o dołączenie kodu, abyśmy mogli pomóc Ci w nieporozumieniu. Oto przykładowy fragment kodu:

import System.IO 

Do obsługi problemów z buforowaniem.

main = do 
    hSetBuffering stdin NoBuffering 
    putStrLn "Gimma a name ye skervy dog!" 
    name1 <- getLine 
    putStrLn "Good, Good, now another, and make it snappy!" 
    name2 <- getLine 
    loop name1 name2 10 

Wskazówka main może wywołać inną funkcję (loop), który mieszka w monady IO. Ta druga funkcja jest całkowicie zdolna do uzyskania i działania na podstawie danych wprowadzanych przez użytkownika, wywoływania samego siebie i/lub przyjmowania argumentów.

loop :: String -> String -> Int -> IO() 
loop _ _ 0 = return() 
loop n1 n2 i = do 
    putStrLn $ "Ok Mr. " ++ n1 ++ " and Mrs. " ++ n2 ++ 
       " tis time to roll the dice!" 
    print i 
    putStrLn "Options: (k)eep looping, (i)ncrement loop counter by 10" 
    c <- getChar 
    putStr "\n" 
    case c of 
     'k' -> loop n1 n2 (i-1) 
     _ -> putStrLn "Blood and bloody ashes, we have to keep going?" >> 
       loop n1 n2 (i+10) 

I pętla po prostu robi proste, głupie zadanie z prośbą o wejście binarne (zwiększamy licznik czy nie), a także, pętle.

Jeśli to nie pomoże, być może możesz zamieścić nieco bardziej kompletne pytanie i kod. Będę edytować za pomocą zaktualizowanej odpowiedzi.

+1

+1 Arrrrrrrrrh! – Landei

6

Lub możesz użyć forever.

main = do 
    x <- getLine 
    foo 
    forever $ do 
    y <- getLine 
    baz 

Jeśli jesteś nowy w Haskell, proponuję przejść przez LJAAH dla dobrego wprowadzenia.