# 🦀 Projeto: Jogo de Adivinhação em Rust
> [!INFO] Objetivo
> Aprender os fundamentos de Rust através da construção de um jogo interativo: manipulação de entradas (IO), variáveis, mutabilidade, crates externas e controle de fluxo com _Pattern Matching_.
**:: Referência ::** [The Rust Programming Language - Chapter 2](https://doc.rust-lang.org/book/ch02-00-guessing-game-tutorial.html)
---
## 🛠️ 1. Preparação do Ambiente
Para iniciar o projeto, utilizamos o **Cargo**, o gerenciador de pacotes e sistema de build do Rust:
Shell
```
# Cria um novo projeto baseado em binário
$ cargo new guessing_game
$ cd guessing_game
# Adiciona a dependência necessária para números aleatórios
$ cargo add rand
```
O comando `cargo run` será seu melhor amigo aqui: ele compila e executa o projeto em um único passo, ideal para o ciclo de desenvolvimento iterativo.
---
## 💻 2. Implementação e Lógica
O código abaixo utiliza o conceito de **Shadowing** (sobrescrever uma variável com outra de tipo diferente) e o poderoso **Pattern Matching** do Rust.
```rust
/// Jogo de Adivinhação
/// Demonstra conceitos de: Input/Output, Variáveis Mutáveis,
/// Geração de números aleatórios e Comparação (Ordering).
use rand::Rng; // Trait necessário para usar geradores de números
use std::cmp::Ordering;
use std::io::{self, Write}; // Importa IO e Write para manipulação de terminal
fn main() {
println!("--- Jogo de Adivinhação ---");
println!("Tente adivinhar o número secreto entre 1 e 100!");
// Gera o número secreto no intervalo [1, 100]
// Utilizamos 'thread_rng' para obter um gerador local à thread atual
let numero_secreto = rand::thread_rng().gen_range(1..=100);
// Início do laço principal do jogo
loop {
print!("\nDigite o seu chute: ");
io::stdout().flush().unwrap(); // Garante que o texto apareça antes da entrada
let mut chute = String::new();
// Captura a entrada do usuário
io::stdin()
.read_line(&mut chute)
.expect("Erro ao ler a linha de comando");
// Shadowing: Transformamos a String 'chute' em um 'u32' (inteiro positivo)
// Usamos match em vez de expect para evitar que o programa quebre com entradas inválidas
let chute: u32 = match chute.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("⚠️ Por favor, digite apenas números!");
continue;
}
};
println!("Você chutou: {}", chute);
// Lógica de Comparação utilizando Pattern Matching
match chute.cmp(&numero_secreto) {
Ordering::Less => println!("Muito baixo! 📉"),
Ordering::Greater => println!("Muito alto! 📈"),
Ordering::Equal => {
println!("🎉 Parabéns! Você acertou o número secreto: {}", numero_secreto);
break; // Sai do loop e encerra o jogo
}
}
}
}
```
---
## 🧠 3. Conceitos-Chave Aprendidos
|**Conceito**|**Descrição**|
|---|---|
|**`let mut`**|Em Rust, variáveis são imutáveis por padrão. O `mut` permite que o valor seja alterado.|
|**`Shadowing`**|Permite declarar uma nova variável com o mesmo nome da anterior, útil para converter tipos (String → Inteiro).|
|**`match`**|Uma estrutura de controle que garante que você tratou todos os caminhos possíveis (_exhaustive checking_).|
|**`Crates`**|Pacotes de terceiros (como o `rand`) que expandem as funcionalidades da biblioteca padrão do Rust.|
|**`Result`**|O tipo de retorno de funções que podem falhar (`Ok` ou `Err`), forçando o desenvolvedor a tratar erros.|