Adivinhação
Introdução
Dando continuidade ao conhecimento do Rust
, vamos ao capítulo 2 do livro:
The Rust Programming Language
Ele propõem introduzir alguns conceitos comuns da linguagem, criando o jogo da adivinhação
Configurando o Projeto
Criei um novo projeto utilizando o Cargo
:
Começando o Jogo
Vou dividir em alguns passos para facilitar o passo a passo da criação do jogo.
Para compilar o programa utilizei o cargo build
e para executar cargo run
.
O primeiro passo é saber como fazer um input do usuário. Para isso, segue o código abaixo:
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | // Baseado no exemplo do próprio livo, com algumas modificações
use std::io; //Lib para tratar de I/O
fn main() {
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
println!("You guessed: {guess}"); //Mostra a entrada do usuário
}
|
Números Aleatórios
O Rust
não possui a geração de números aleatórios em sua biblioteca padrão. Com isso, usei o rand disponível no crate. Para isso, é necessário adicionar a biblioteca no arquivo Cargo.toml:
[dependencies]
rand = "0.8.3"
Agora utilize o comando cargo build
para instalar a dependência.
Voltando ao código, vamos adicionar biblioteca e a função que gera os números:
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | // Baseado no exemplo do próprio livro, com algumas modificações
use std::io; //Lib para tratar de I/O
use rand::Rng; //Lib para gerar números randômicos
fn main() {
// Gera um número inteiro de 0 a 100
let secret_number = rand::thread_rng().
gen_range(1..=100);
println!("The secret number is: {secret_number}");
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
println!("You guessed: {guess}"); //Mostra a entrada do usuário
}
|
Comparando
Uma vez que a entrada do usuário e o número randômico estão disponíveis, só resta fazer a comparação entre os dois e checar se é menor, maior ou igual.
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | // Baseado no exemplo do próprio livro, com algumas modificações
use std::io; //Lib para tratar de I/O
use rand::Rng; //Lib para gerar números randômicos
use std::cmp::Ordering; //Lib para fazer comparação
fn main() {
// Gera um número inteiro de 0 a 100
let secret_number = rand::thread_rng().
gen_range(1..=100);
println!("The secret number is: {secret_number}");
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
// Converte a entrada para inteiro
let guess: u32 = guess.trim().parse().
expect("\n\n>>>> Please type a integer number! <<<<\n\n");
println!("You guessed: {guess}"); //Mostra a entrada do usuário
// Compara e informa se o número é menor, maior ou igual
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
|
Tentando Novamente
Até agora o jogo só permite apenas uma tentativa (try hard
). Agora vou adicionar o loop para fazer várias tentativas.
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | // Baseado no exemplo do próprio livro, com algumas modificações
use std::io; //Lib para tratar de I/O
use rand::Rng; //Lib para gerar números randômicos
use std::cmp::Ordering; //Lib para fazer comparação
fn main() {
// Gera um número inteiro de 0 a 100
let secret_number = rand::thread_rng().
gen_range(1..=100);
println!("The secret number is: {secret_number}");
loop {
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
// Converte a entrada para inteiro
let guess: u32 = guess.trim().parse().
expect("\n\n>>>> Please type a integer number! <<<<\n\n");
println!("You guessed: {guess}"); //Mostra a entrada do usuário
// Compara e informa se o número é menor, maior ou igual
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
}
|
Ganhando
Mesmo digitando o número correto, o jogo ainda permite fazer uma nova tentativa. Vou adicionar um break quando o número digitado for o correto.
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | // Baseado no exemplo do próprio livro, com algumas modificações
use std::io; //Lib para tratar de I/O
use rand::Rng; //Lib para gerar números randômicos
use std::cmp::Ordering; //Lib para fazer comparação
fn main() {
// Gera um número inteiro de 0 a 100
let secret_number = rand::thread_rng().
gen_range(1..=100);
println!("The secret number is: {secret_number}");
loop {
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
// Converte a entrada para inteiro
let guess: u32 = guess.trim().parse().
expect("\n\n>>>> Please type a integer number! <<<<\n\n");
println!("You guessed: {guess}"); //Mostra a entrada do usuário
// Compara e informa se o número é menor, maior ou igual
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
|
Tratando Erros
Caso a entrada do usuário não seja exatamente um inteiro, ocorre um crash no jogo. Vou adicionar um tratamento para lidar com esse problema.
src/main.rs |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | // Baseado no exemplo do próprio livro, com algumas modificações
use std::io; //Lib para tratar de I/O
use rand::Rng; //Lib para gerar números randômicos
use std::cmp::Ordering; //Lib para fazer comparação
fn main() {
// Gera um número inteiro de 0 a 100
let secret_number = rand::thread_rng().
gen_range(1..=100);
println!("The secret number is: {secret_number}");
loop {
// Observe o termo "mut", pois essa variável
// será alterada com a entrada do usuário
let mut guess = String::new();
io::stdin()
.read_line(&mut guess) // Lê a entrada e atribui a variável "guess"
.expect("Failed to read line"); // Caso algo saia errado, mostra a mensagem
// Converte a entrada para inteiro
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("Entrada Inválido");
continue;
}
};
println!("You guessed: {guess}"); //Mostra a entrada do usuário
// Compara e informa se o número é menor, maior ou igual
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
|
Conclusão
Criar o jogo introduziu o conceito de match
, loop
, mut
e Crate
. Que são básicos na linguagem.