Você está na página 1de 7

Programação Funcional UFOP DECOM 2014.

Aula prática 12

Números Aleatórios e Argumentos da Linha de Comando

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

2 Argumentos da linha de comando 2

3 Jogo: adivinha o número 2

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.

Exemplo: lançamento de dados


lancadados.hs
module Main (main) where

import System.Random (randomRIO)

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)

Exemplo de execução da aplicação

$ ./lancadados
Lancamento de dois dados
Faces obtidas: 3 e 5

Exemplo de execução da aplicação

$ ./lancadados
Lancamento de dois dados
Faces obtidas: 4 e 1

2 Argumentos da linha de comando

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.

Exemplo: argumentos do programa


args.hs
module Main (main) where

import System.Environment (getArgs, getProgName)

main =
do progName <- getProgName
putStrLn "The program name is:"
putStrLn progName
putStrLn ""
args <- getArgs
putStrLn "The arguments are:"
mapM putStrLn args

Exemplo de execução da aplicação

$ ./args a b c -o test
The program name is:
args

The arguments are:


a
b
c
-o
test

3 Jogo: adivinha o número


Ao executar as tarefas que se segem você estará escrevendo uma aplicação para jogar o jogo adivinhe
o número, como explicado a seguir.

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.

3. O jogador informa o seu palpite.


4. Se o palpite do jogador estiver incorreto:
• o programa exibe a mensagem Muito alto ou Muito baixo convenientemente para ajudar
o jogador a acertar o número nas próximas jogadas.
• o jogo continua com o programa solicitando o próximo palpite e analisando a resposta do
usuário.
5. Quando o jogador insere a resposta correta:
• o programa exibe a mensagem Parabéns, você adivinhou o número, e
• permite que o usuário escolha se quer jogar novamente, e joga novamente em caso afirmativo.

Exemplo de execução da aplicação

$ ./advinha
Adivinha o número v1.0
=========================================
Digite um número entre 1 e 1000: 444
Muito grande
Tente novamente

Digite um número entre 1 e 1000: 200


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 111


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 157


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 138


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 123


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 130


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 125


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 128


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 129


Parabéns, você acertou

Deseja jogar novamente? n

3
Tarefa 1

Em um arquivo adivinha.hs defina o módulo Main exportando a variável main.

Tarefa 2

Defina main como uma ação de E/S que, quando executada:


• configura o sistema para não realizar bufferização da saída de dados padrão, e
• exibe uma mensagem identificando o programa e sua versão

Exemplo de execução da aplicação

*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.

Exemplo de execução da aplicação

*Main> simOuNao "Quer jogar novamente?"


Quer jogar novamente? talvez
Quer jogar novamente? k
Quer jogar novamente? S
True

*Main> simOuNao "Você é inteligente?"


Você é inteligente? com certeza
Você é inteligente?
Você é inteligente? acho que sim
Você é inteligente? n
False

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

Exemplo de execução da aplicação

*Main> acertar 119


Digite um número entre 1 e 1000: 600
Muito grande
Tente novamente

Digite um número entre 1 e 1000: 23


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 119


Parabéns, você acertou

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)

– se sim, executa jogar recursivamente


– se não, não faz nada
Para gerar um número aleatório, utilize a função randomRIO do módulo
System.Random. A classe Random é formada pelos tipos para os quais pode-se gerar valores
aleatórios. Os tipos inteiros Int e Integer são instâncias desta classe.
A função randomRIO :: Random a => (a, a) -> IO a recebe um par de valores como
argumento e resulta em uma ação de E/S que, quando executada, gera e retorna um número
pseudo-aleatório no intervalo fechado definido pelo par.
Exemplo de execução da aplicação

*Main> jogar
Digite um número entre 1 e 1000: 509
Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 780


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 640


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 700


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 744


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 730


Muito grande
Tente novamente

Digite um número entre 1 e 1000: 720


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 725


Muito pequeno
Tente novamente

Digite um número entre 1 e 1000: 728


Parabéns, você acertou

Deseja jogar novamente? n

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.

Você também pode gostar