No description
Find a file
2026-08-31 11:20:48 +02:00
.woodpecker chore: migrate CI to .woodpecker/{push,branch}.yml 2026-08-31 11:20:48 +02:00
src fix(032): make escanear_primeiro_alvo test set consistent and document contract 2026-08-31 11:20:48 +02:00
tests fix(032): make escanear_primeiro_alvo test set consistent and document contract 2026-08-31 11:20:48 +02:00
.gitignore Initial commit 2026-08-31 09:18:35 +00:00
Cargo.lock initial content 2026-08-31 11:20:40 +02:00
Cargo.toml chore: declare MSRV 1.85 (edition 2024) 2026-08-31 11:20:48 +02:00
LICENSE chore: add AGPL-3.0 license and standard .gitignore 2026-08-31 11:20:48 +02:00
README.md fix(032): make escanear_primeiro_alvo test set consistent and document contract 2026-08-31 11:20:48 +02:00

Lição 32: Manobras Avançadas (Controle de Fluxo Avançado)

1. Narrativa

No campo de batalha, o mecha Æther enfrenta situações que exigem decisões complexas — escanear alvos gastando energia, executar sequências de combate com limites de recursos, localizar sistemas danificados em matrizes de diagnóstico. Manobras avançadas combinam loops, match guards e early returns para responder a cenários dinâmicos.

2. Conceito

Controle de fluxo avançado combina múltiplos mecanismos de Rust:

  • Loops com estado: for + variáveis mutáveis para rastreamento
  • Early returns: return antecipado dentro de loops
  • Match guards: match com cláusulas if para padrões condicionais
  • Continue: Pular iterações que não atendem critérios
  • Loops aninhados: Percorrer estruturas 2D com for dentro de for

3. Requisitos

  • Implementar funções com loops que rastreiam estado mutável
  • Usar early returns dentro de loops
  • Aplicar match guards para classificação condicional
  • Percorrer estruturas aninhadas (Vec<Vec>)

4. Design de Dados

Cada alvo é representado apenas pela energia necessária para escaneá-lo (um i32 numa fatia &[i32]). O scanner carrega um orçamento de energia energia_scanner (também i32). Um alvo é escaneável quando a energia que ele exige respeita o orçamento: energias[i] <= energia_scanner. A função escanear_primeiro_alvo devolve o índice do primeiro alvo escaneável ou None.

graph LR
    A["&[i32] energias"] --> B["Loop: alvo atual energias[i]"]
    B --> C{"energias[i] <= energia_scanner?"}
    C -->|Sim| D["Early return Some(i)"]
    C -->|Não| E["i = i + 1"]
    E --> B
    F["Fim da fatia"] --> G["Return None"]
    H["&[Vec<bool>] diagnosticos"] --> I["Loop aninhado i, j"]
    I --> J["Return Some(i, j) se !status"]

5. Diagrama de Fluxo

flowchart TD
    A[Início] --> B[Percorrer elementos]
    B --> C{Condição de parada?}
    C -->|Energia esgotada| D["Return None"]
    C -->|Alvo encontrado| E["Return Some(i)"]
    C -->|Continuar| F{Condição de skip?}
    F -->|Sim| G[continue]
    F -->|Não| H[Processar elemento]
    G --> B
    H --> I{Limite atingido?}
    I -->|Sim| J["Return limite"]
    I -->|Não| K[Acumular e continuar]
    K --> B

6. Funções

Função Descrição
escanear_primeiro_alvo Devolve o índice do primeiro alvo cuja energia <= energia_scanner, ou None se nenhum for escaneável com o orçamento informado
executar_sequencia_combate Executa turnos de combate respeitando energia mínima
localizar_sistema_danificado Encontra primeiro sistema offline em matriz 2D
classificar_ameaca Classifica ameaça com match guards (tipo + distância + velocidade)
detectar_sinal_valido Verifica se algum sinal está na faixa de frequência
executar_manobra_evasiva Executa passos evasivos com limite de deslocamento

7. Exemplo

fn classificar_ameaca(tipo: &str, distancia: i32, velocidade: i32) -> &'static str {
    // Só "míssil", "laser" e "melee" são tipos válidos; qualquer outro tipo
    // é desconhecido, independente da distância/velocidade.
    if !matches!(tipo, "míssil" | "laser" | "melee") {
        return "desconhecida";
    }
    if distancia < 200 && velocidade > 500 {
        "crítica"
    } else if distancia > 400 {
        "baixa"
    } else {
        "alta"
    }
}

8. Missão

  1. Implementar escanear_primeiro_alvo(energias: &[i32], energia_scanner: i32) -> Option<usize>: percorrer a fatia e devolver Some(i) para o primeiro índice em que energias[i] <= energia_scanner (energia do alvo respeita o orçamento do scanner), ou None se nenhum alvo for escaneável. Use loop + early return.
  2. Implementar executar_sequencia_combate com loops aninhados + continue
  3. Implementar localizar_sistema_danificado com loops aninhados + early return de tupla
  4. Implementar classificar_ameaca com match guards e condições compostas
  5. Implementar detectar_sinal_valido com .any() e verificação de faixa
  6. Implementar executar_manobra_evasiva com acumulação e limite

9. Como Executar

cargo build
cargo test
cargo clippy -- -D warnings
cargo fmt --check

10. Dicas

  • Match guards permitem condições arbitrárias após if no braço do match
  • Early returns em loops são mais legíveis que flags booleanas
  • continue pula para a próxima iteração — mais limpo que else profundo
  • Loops aninhados com .enumerate() dão acesso ao índice e ao valor simultaneamente