Escolar Documentos
Profissional Documentos
Cultura Documentos
Aula prática 12
Resumo
A geração de números pseudo-aleatórios em aplicações em Haskell pode ser feita através de ações
de E/S. Nesta aula vamos aprender a desenvolver aplicações que usam números aleatórios. Vamos
também aprender a usar argumentos passados para um programa na linha de comando.
Estes tópicos serão usados na implementação do jogo adivinha o número.
Sumário
1 Valores aleatórios 1
1 Valores aleatórios
A biblioteca random, que define o módulo System.Random, lida com a tarefa comum de geração de
valores pseudo-aleatórios em Haskell.
Atavés da classe Random é possível obter valores aleatórios de uma variedade de tipos. Esta classe
fornece uma maneira de extrair valores de um gerador de números aleatórios. Por exemplo, a instância
Float da classe Random permite gerar valores aleatórios do tipo Float.
A geração de números aleatórios pode ser feita através da manipulação explícita de um gerador de
números aleatórios, ou através de um gerador global acessível através de ações de entrada e saída. Vamos
considerar apenas o segundo caso.
A classe Random define dois métodos para geração de números aleatórios usando o gerador global:
• randomIO:
randomIO :: Random a => IO a
randomIO é uma ação de E/S que, quando executada, extrai o próximo valor aleatório do tipo a do
gerador global de números aleatórios (disponível no sistema de computação), e retorna este valor.
A faixa de possíveis valores normalmente é:
– para tipos limitados: todo o tipo.
– para tipos fracionários: o intervalo semi-fechado [0, 1).
– para o tipo Integer: a faixa de Int.
• randomRIO:
randomRIO :: Random a => (a, a) -> IO a
Esta função recebe um par de valores (inf , sup) e resulta em uma ação de E/S que, quando exe-
cutada, extrai o próximo valor aleatório do tipo a, uniformemente distribuído no intervalo fechado
[inf , sup], do gerador global de números aleatórios (disponível no sistema de computação), e re-
torna este valor.
main :: IO ()
main =
do putStrLn "Lançamento de dois dados"
1
x <- randomRIO (1,6::Int)
y <- randomRIO (1,6::Int)
putStrLn ("Faces obtidas: " ++ show x ++ " e " ++ show y)
$ ./lancadados
Lancamento de dois dados
Faces obtidas: 3 e 5
$ ./lancadados
Lancamento de dois dados
Faces obtidas: 4 e 1
getArgs :: IO [String]
A ação de E/S getArgs (definida no módulo System.Environment), quando executada, retorna uma
lista formada pelos argumentos da linha de comando do programa.
getProgName :: IO String
A ação de E/S getProgName (definida no módulo System.Environment), quando executada, retorna o
nome do programa.
main =
do progName <- getProgName
putStrLn "The program name is:"
putStrLn progName
putStrLn ""
args <- getArgs
putStrLn "The arguments are:"
mapM putStrLn args
$ ./args a b c -o test
The program name is:
args
1. O programa escolhe um número a ser adivinhado pelo jogador (usuário) selecionando um número
inteiro aleatório no intervalo de 1 a 1000.
2
2. O programa exibe a mensagem Adivinhe um número entre 1 e 1000.
$ ./advinha
Adivinha o número v1.0
=========================================
Digite um número entre 1 e 1000: 444
Muito grande
Tente novamente
3
Tarefa 1
Tarefa 2
*Main> main
Adivinha o número v1.0
=========================================
Tarefa 3
Defina uma função simOuNao que recebe uma string e resulta em uma ação de E/S que, quando
executada:
• exibe a string na saída padrão (com o objetivo de fazer uma pergunta do tipo sim ou não ao
usuário)
• lê a resposta do usuário
• verifica se a resposta é
– s ou S, retornando verdadeiro
– n ou N, retornando falso
– qualquer outra coisa, chamando simOuNao novamente para que o usuário responda
corretamente.
Use uma expressão case.
Esta função deve ser usada em jogar (veja a tarefa 5) para verificar se o usuário deseja
continuar jogando ou não.
4
Tarefa 4
Defina uma função acertar que recebe um número a ser adivinhado e resulta em uma ação de
E/S que, quando executada:
• exibe uma mensagem solicitando um número entre 1 e 1000
• lê o número informado pelo usuário
• compara o número informado com o número a ser adivinhado:
– se forem iguais, exibe uma mensagem parabenizando o usuário por ter adivinhado o
número
– caso contrário
∗ exibe uma mensagem informando que o número é muito pequeno ou muito
grande, adequadamente
∗ exibe uma mensagem solicitando ao usuário uma nova tentativa
∗ faz uma nova tentativa através de uma chamada recursiva de acertar
A função acertar deverá ser usada na definição de jogar (veja a tarefa 5).
5
Tarefa 5
O programa deve permitir ao usuário jogar várias vezes, o que nos leva à necessidade do uso de
recursão.
Defina uma ação de E/S jogar que, quando executada
• gera um número inteiro aleatório entre 1 e 1000, inclusive
• interage com o usuário até que o usuário acerte o número (veja a tarefa 4)
• verifica se o usuário deseja jogar novamente (veja a tarefa 3)
*Main> jogar
Digite um número entre 1 e 1000: 509
Muito pequeno
Tente novamente
A ação jogar deve ser usada em main para que o usuário possa joagar o jogo.
6
Tarefa 6
Modifique o programa adivinha.hs de forma que o usuário possa especificar o intervalo a ser
utilizado para adivinhar o número através de dois argumentos na linha de comando.
Tarefa 7
Modifique o programa adivinha.hs para que seja exibida o número de tentativas feitas pelo
usuário.