Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

lesiano

IO - dúvidas

Recommended Posts

lesiano

Ora bem, tenho aqui umas dúvidas na última parte do trabalho.

Passo a explicar:

i) Tenho uma função que retorna um tabuleiro com x colunas, e o x é um número dado pelo utilizador.

ii) Quero fazer uma função de jogada IO q a primeira vez que é chamada, pergunte ao user qts colunas quer e evoque a função do ponto i). A partir daí trabalha nesse tabuleiro até os users quererem. ( Não posso parar qd o tabuleiro estiver cheio pq eu trabalho com listas vazias e por isso o tabuleiro nunca fica cheio em linhas).

Portanto:

inictabpio :: IO()
inictabpio = do{
                putStrLn "\nInsira o numero de colunas que o tabuleiro tera de ter:";
                x <- getLine;
                (inictab x);  ???Aqui queria evocar a função inictab q recebe x e devolve um tab com x colunas
                return();   ???Não sei pq isto não funca. O q está mal?      
                }

jogario :: IO()
jogario = do{
            putStrLn "\nPara o primeiro utilizador, insira uma coluna para inserir peca:";
    y <- getLine;
            if (testajogada tab y 1) then (insereA tab y)
            else putStrln "Coluna cheia ou nao existente. Por favor seleccione outra coluna."; ???aqui queria evocar novamente a função jogario. É só chamá-la na linha seguinte? Não consigo testar pq a linha anterior dá erro
    putStrLn "\nPara o segundo utilizador, insira uma coluna para inserir peca:";
    y <- getLine;
            if (testajogada tab y 1) then (insereB tab y) ???tb dá erro, esta linha
    putStrLn "Pretendem terminar o jogo? s/n Qq valor diferente de s sera assumido como nao";
            resposta <- getLine;
            if (resposta=="s") then (calculapontos tab)
            else jogario
    }

Agr a ideia era fazer uma função que reunisse as duas. Mas ñ sei como fazer para a primeira vez que fosse chamada chamar a inictabpio e depois a da jogada e depois da primeira vez, chamar só a da jogada. Ideias?

No código há "?? ?" q são perguntas.

Share this post


Link to post
Share on other sites
Rui Carlos

Não estás a usar o resultado do inictab x, por isso, se essa função se limita a devolver o resultado, da forma que tens é o mesmo que não teres lá nada.

Aquele return penso que não é necesário.

No if parece-me que te falta o else.

Share this post


Link to post
Share on other sites
lesiano

Então como é que posso fazer isto?

Basicamente queria ter a jogada com IO. Mas a primeira vez que fosse chamada, criava o tabuleiro, que depois usava para ir fazendo as jogadas...

Share this post


Link to post
Share on other sites
Rui Carlos

Cria uma função que chama a função que inicia o tabuleiro, e depois crias outra função que faz as jogadas. Na função principal chamas a função que inicia o tabuleiro, e depois a que faz as jogadas.

Share this post


Link to post
Share on other sites
lesiano

jogario :: IO()
jogario = inictabparaio();

inictabparaio :: IO()
inictabparaio = do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter.";
    x <- getLine;
let tab = (inictab x);

jogadas :: IO()
jogadas = do{ ... 

Assim dá-me error on input "x".

Share this post


Link to post
Share on other sites
Rui Carlos

Estás a usar o ';' sem estar estar a usar {}.

Um exemplo de como podes fazer.

-- função que inicia um tabuleiro e chama a função responsável pelas jogadas
f1=do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter."
      x<-getLine;
      let tab=inictab x
      f2 tab

-- função que efectua as jogadas
f2 tab=do ... -- efectua uma jogada sobre o tabuleiro tab e coloca o resultado em novotab
          if terminar novotab -- verifica se é para parar de jogar
            then putStrLn "Fim"
            else f2 novotab

Share this post


Link to post
Share on other sites
lesiano

Rui tenho isto, então:

-- função que inicia um tabuleiro e chama a função responsável pelas jogadas
f1=do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter."
      x<-getLine;
      let tab=inictab x
      f2 tab

-- função que efectua as jogadas
f2 tab = do jogadas(tab) -- efectua uma jogada sobre o tabuleiro tab e coloca o resultado em novotab
            putStrLn "\nPretendem continuar a jogar?"
		c <- getLine
		if (c=="n") then menu
		else f2 tab

jogadas :: Tabuleiro -> IO() 
jogadas = do putStrLn "\nPara o primeiro utilizador, insira uma coluna para inserir peca:"
             y <- getLine
		 (insereA tab x)
		 if (y=="s") then menu
		 else do putStrLn "\nPara o segundo utilizador, insira uma coluna para inserir peca:"
                     y <- getLine
                     (insereB tab y)
				 jogadas

Mas não funciona, dá parse error in pattern na linha -> putStrLn "\nPretendem continuar a jogar?"

Share this post


Link to post
Share on other sites
Rui Carlos

Começa por corrigir a indentação disso (parece-me que é daí que vem o erro que te está a dar).

Depois, não estás a ir buscar os resultados das funções que alteram o tabuleiro (mais uma vez, é a mesma coisa que não as ter).

Share this post


Link to post
Share on other sites
lesiano

-- função que inicia um tabuleiro e chama a função responsável pelas jogadas
f1=do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter."
      x <- getLine
      let tab = inictab x
      f2 tab

-- função que efectua as jogadas
f2 tab = do {
            putStrLn "\nPara o primeiro utilizador, insira uma coluna para inserir peca:";
            x <- getLine;
		(insereA tab x);
            putStrLn "\nPara o segundo utilizador, insira uma coluna para inserir peca:";
            y <- getLine;
            (insereB tab y); -- efectua uma jogada sobre o tabuleiro tab e coloca o resultado em novotab
            putStrLn "\nPretendem continuar a jogar?";
	    c <- getLine;
	    if (c=="n") then menu
	                  else f2 tab;
		}

Agr dá-me erro nos getLines. Quer um inteiro.

Meti getInt mas ñ resolve, ñ conhece.

Share this post


Link to post
Share on other sites
lesiano

Já deu, essa parte;

Tenho isto, agr:

getInt :: IO Int
getInt = do line <- getLine
            return (read line :: Int)

-- função que inicia um tabuleiro e chama a função responsável pelas jogadas
f1=do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter."
      x <- getInt
      let tab = inictab x
      f2 tab

-- função que efectua as jogadas
f2 tab = do putStrLn "\nPara o primeiro utilizador, insira uma coluna para inserir peca:"
            x <- getInt
		let tab = (insereA tab x)
            putStrLn "\nPara o segundo utilizador, insira uma coluna para inserir peca:"
            y <- getInt
            let tab = (insereB tab y) -- efectua uma jogada sobre o tabuleiro tab e coloca o resultado em novotab
            putStrLn "\nPretendem continuar a jogar?"
	    c <- getLine
	    terminajogo c tab

terminajogo :: String -> Tabuleiro -> IO
terminajogo c tab = if (c=="s") then menu
                             else f2 tab

Agr diz q o do do f2 tem q acabar com uma expressão. Até já meti chavetas, mas não funciona.

Share this post


Link to post
Share on other sites
lesiano

Espera lá num do a indentação deve ser:

função = do x

.................y

.................z

Certo?

Ainda não percebi como é q se indenta correctamente.

Share this post


Link to post
Share on other sites
lesiano

Já percebi, no fim tinha um tab.  :wallbash:

Ok, já funciona tudo correctamente. Só preciso de mais uma coisa.

Como adicionar a uma string um valor de uma função?

Tipo em C seria printf("O valor do user 1 é %d", var);

E nisto?

Share this post


Link to post
Share on other sites
lesiano

contapontosio :: Tabuleiro -> IO()

contapontosio tab = do let pontosum = calculahvd tab 1

                      putStrLn "\nOs pontos do primeiro user são:"++(show pontosum)

Assim?

Não está a dar.

Share this post


Link to post
Share on other sites
Betovsky

O problema é que a função (++) associa à esquerda. Portanto o que tu tens é o mesmo que

contapontosio :: Tabuleiro -> IO()
contapontosio tab = do let pontosum = calculahvd tab 1
                       (putStrLn "\nOs pontos do primeiro user são:")++(show pontosum)

Ou seja "IO ()" ++ String....

Tens de dizer que queres concatenar primeiro as Strings

contapontosio :: Tabuleiro -> IO()
contapontosio tab = do let pontosum = calculahvd tab 1
                       putStrLn ("\nOs pontos do primeiro user são:"++(show pontosum))

-- Já agora uma linha com do e let fica feio, fica melhor (opinião pessoal)
contapontosio :: Tabuleiro -> IO()
contapontosio tab = putStrLn ("\nOs pontos do primeiro user são:"++ pontosum)
     where pontosum = show (calculahvd tab 1)
                       


"Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !"

Sign on a computer system consultant's desk

Share this post


Link to post
Share on other sites
lesiano

Boas Beto.

Obg, já tinha resolvido esse ponto, mas obg na msm.

Para acabar:

terminajogo :: String -> Tabuleiro -> IO()
terminajogo c tab = if (c=="n") then (contapontosio tab)
                             else f2 tab

Tenho aqui uma função q pode devolver uma função do tipo IO() ou outra do tipo String -> IO() e ele queixa-se disso msm. Como é q contorno isso? Obg.

Share this post


Link to post
Share on other sites
lesiano

Rui acabei por chegar a outra solução. E agr tenho um problema q para mim ñ faz qq sentido:

getInt :: IO Int
getInt = do line <- getLine
            return (read line :: Int)

-- função que inicia um tabuleiro e chama a função responsável pelas jogadas
f1 = do putStrLn "Insira o numero de colunas que o tabuleiro tera de ter."
        x <- getInt
        let tab = inictab x
        f2 tab

-- função que efectua as jogadas
f2 :: Tabuleiro -> IO()
f2 tab = do putStrLn "\nPara o primeiro utilizador, insira uma coluna para inserir peca:"
            j <- getInt
            if (testajogada tab j 1) then do let tab = (insereA tab j)
                                             putStrLn "\nPara o segundo utilizador, insira uma coluna para inserir peca:"
                                             y <- getInt
                                             let tabe = (insereB tab y)
                                             terminajogo tabe
                                      else menu

terminajogo :: Tabuleiro -> IO()
terminajogo tab = do putStrLn "\nPretendem continuar a jogar?"
                     c <- getLine
                     if (c=="n") then (contapontosio tab)
                      else f2 tab

contapontosio :: Tabuleiro -> IO()
contapontosio tab = do let pontosum = (calculahvd tab 1)
                       putStrLn ("O primeiro user tem" ++ (show pontosum) ++ "pontos.")
                       let pontosdois = (calculahvd tab 2)
                       putStrLn ("O segundo user tem" ++ (show pontosdois) ++ "pontos.")
                       menu

O programa corre todo certinho, mas qd chega à função f2 outra vez dá erro. Isto é, corre todo até chegar à função "terminajogo". Depois daí vai outra vez para f2 e eu dou-lhe um valor para inserir e ele pura e simplesmente pára! De certeza q o problema está na forma como eu passo o tabuleiro, mas para mim só esta forma faz sentido. Onde é q estou a errar?

Obg.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.