No description
Find a file
2026-08-11 14:38:16 +02:00
.woodpecker fix: content audit corrections + CI migration to woodpecker + MSRV 1.85 2026-08-11 09:49:11 +02:00
src initial content 2026-08-07 11:39:38 +02:00
tests initial content 2026-08-07 11:39:38 +02:00
.gitignore Initial commit 2026-08-07 09:38:55 +00:00
Cargo.lock initial content 2026-08-07 11:39:38 +02:00
Cargo.toml fix: content audit corrections + CI migration to woodpecker + MSRV 1.85 2026-08-11 09:49:11 +02:00
LICENSE Initial commit 2026-08-07 09:38:55 +00:00
README.md fix(007): pedagogical MINOR fixes (forward-refs, test strength, contract docs) 2026-08-11 14:38:16 +02:00

Lição 7: Decisões Táticas

Narrativa

O piloto toma decisões baseadas nas leituras dos sensores. "Se energia < 20%, recuar. Se não, avançar." Condicionais permitem que o mecha reaja ao ambiente.

Na cabine de batalha, cada segundo conta. Um piloto experiente avalia constantemente múltiplos fatores — energia restante, integridade dos escudos, distância do inimigo — e toma decisões instantâneas. Estas decisões táticas são o coração do combate efetivo. Sem a capacidade de avaliar condições e reagir adequadamente, mesmo o mecha mais avançado torna-se apenas uma máquina inerte.

A Academia Æther ensina que a verdadeira maestria vem não apenas da força bruta, mas da capacidade de escolher o momento certo para atacar, defender ou recuar. Cada decisão é um ramo no caminho da vitória.

Conceito

Em Rust, condicionais permitem que seu código execute diferentes caminhos baseados em condições booleanas. O if avalia uma condição e executa um bloco se for verdadeira:

if energia < 20 {
    println!("Recuar!");
}

O if-else fornece um caminho alternativo quando a condição é falsa:

if energia < 20 {
    println!("Recuar!");
} else {
    println!("Avançar!");
}

Para múltiplas condições, use if-else if-else:

if energia < 20 {
    println!("Crítico - Recuar!");
} else if energia < 50 {
    println!("Cuidado - Defender!");
} else {
    println!("Ótimo - Avançar!");
}

O match é uma alternativa poderosa para comparar um valor contra múltiplos padrões:

match nivel_alerta {
    1 => println!("Informação"),
    2 => println!("Atenção"),
    3 => println!("Perigo"),
    _ => println!("Desconhecido"),
}

Importante: Em Rust, if é uma expressão, não uma declaração. Isso significa que pode retornar um valor:

let estrategia = if energia > 50 { "ataque" } else { "defesa" };

Requisitos

  • Entrada: Leituras de sensores (energia, velocidade, níveis de alerta)
  • Processamento: Avaliar condições e decidir ações apropriadas
  • Saída: Decisões táticas como strings ou valores booleanos

Design de Dados

Esta lição trabalha com funções que recebem valores primitivos (inteiros e strings) e retornam decisões baseadas em condições:

// Avaliação de energia com if-else
pub fn avaliar_nivel_energia(energia: u32) -> &'static str;

// Decisão baseada em tipo e velocidade
pub fn decidir_manobra(tipo: &str, velocidade: i32) -> &'static str;

// Processamento de alerta com match
pub fn processar_alerta(nivel: u8) -> String;

// Avaliação booleana de ameaça
pub fn avaliar_valor_ameaca(inimigo_forca: i32, minha_forca: i32) -> bool;

// Determinação de modo com múltiplas condições
pub fn determinar_modo_combate(energia: u32, escudos: u32) -> &'static str;

As funções demonstram diferentes padrões de condicionais: if simples, if-else chains, match básico, e condições compostas.

Diagrama Conceitual

flowchart TD
    A[Leituras dos Sensores] --> B{Avaliação Condicional}
    B -->|if| C[Decisão Binária]
    B -->|if-else| D[Dois Caminhos]
    B -->|if-else if-else| E[Múltiplos Caminhos]
    B -->|match| F[Comparação por Padrões]
    C --> G[Ação Tática]
    D --> G
    E --> G
    F --> G

Funções e Módulos

//! Lição 7: Decisões Táticas
//!
//! Aprenda a tomar decisões baseadas em condições.

/// Avalia o nível de energia e retorna a ação recomendada
pub fn avaliar_nivel_energia(energia: u32) -> &'static str;

/// Decide a manobra baseada no tipo e velocidade
pub fn decidir_manobra(tipo: &str, velocidade: i32) -> &'static str;

/// Processa o nível de alerta e retorna mensagem
pub fn processar_alerta(nivel: u8) -> String;

/// Avalia se vale a pena atacar baseado nas forças
pub fn avaliar_valor_ameaca(inimigo_forca: i32, minha_forca: i32) -> bool;

/// Determina o modo de combate baseado em energia e escudos
pub fn determinar_modo_combate(energia: u32, escudos: u32) -> &'static str;

Exemplo do Conceito

// Exemplo if-else simples
let energia = 30;
if energia < 20 {
    println!("Recuar");
} else {
    println!("Avançar");
}

// Exemplo if-else if-else chain
let velocidade = 75;
if velocidade < 30 {
    println!("Lento");
} else if velocidade < 70 {
    println!("Médio");
} else {
    println!("Rápido");
}

// Exemplo match básico
let nivel = 2;
match nivel {
    1 => println!("Baixo"),
    2 => println!("Médio"),
    3 => println!("Alto"),
    _ => println!("Desconhecido"),
}

// if como expressão
let status = if energia > 50 { "Bom" } else { "Ruim" };

// Condição composta
if energia > 50 && escudos > 30 {
    println!("Pronto para combate");
}

Explicação:

  • Linha 2-6: Estrutura if-else básica com dois caminhos
  • Linha 9-15: Cadeia de if-else if-else para múltiplas condições
  • Linha 18-24: Match para comparar valor contra padrões
  • Linha 29: if como expressão que retorna valor
  • Linha 30-32: Condição composta com operador &&

Missão

  1. Implementar avaliar_nivel_energia: Retorne "Recuar" se energia < 20, senão "Avançar"
  2. Implementar decidir_manobra: Baseado no tipo ("ataque"/"defesa"/"evasiva") e velocidade, retorne a manobra adequada. Contrato verificado pelos testes:
    • ("ataque", 80)"Investida Rápida" (velocidade alta)
    • ("ataque", 50)"Ataque Padrão" (velocidade baixa)
    • ("defesa", 30)"Escudos Ativos"
    • O limiar entre "Investida Rápida" e "Ataque Padrão" fica entre 50 e 80 — escolha um valor nesse intervalo e seja consistente
  3. Implementar processar_alerta: Use match para converter nível (1-3) em mensagem descritiva
  4. Implementar avaliar_valor_ameaca: Retorne true se minha_forca for maior ou igual a inimigo_forca (minha_forca >= inimigo_forca)
  5. Implementar determinar_modo_combate: Combine energia e escudos para decidir entre "agressivo", "defensivo", ou "retirada". Contrato verificado pelos testes:
    • (80, 60)"Agressivo" (energia e escudos altos)
    • (40, 70)"Defensivo" (escudos altos, energia moderada)
    • (10, 10)"Retirada" (energia e escudos baixos)

Diagrama de Fluxo da Missão

flowchart TD
    A[Tarefa: Decisões Táticas] --> B[Implementar avaliar_nivel_energia]
    B --> C[Implementar decidir_manobra]
    C --> D[Implementar processar_alerta]
    D --> E[Implementar avaliar_valor_ameaca]
    E --> F[Implementar determinar_modo_combate]
    F --> G[Testes verificam]
    G --> H{Clippy limpo?}
    H -->|Sim| I[Concluído]
    H -->|Não| J[Corrigir warnings] --> G

Como Executar

# Executar testes
cargo test

# Verificar lint
cargo clippy -- -D warnings

# Formatar código
cargo fmt --check

Dicas

  • Lembre-se: Rust exige que todas as ramificações de um if retornem o mesmo tipo
  • Use match quando tiver múltiplos valores discretos para comparar
  • A condição de um if deve ser explicitamente booleana (não há coerção automática)
  • Para condições compostas, use && (E), || (OU), e ! (NÃO)
  • O padrão _ em match captura qualquer valor não coberto pelos outros casos
  • Prefira match sobre longas cadeias de if-else if quando comparar valores exatos