Trilhas
/
Rust
Rust
/
Exercícios
/
Jogo embarcado de baixo consumo
Jogo embarcado de baixo consumo

Jogo embarcado de baixo consumo

Exercício de aprendizagem

Introdução

Tuplas são uma forma leve de agrupar um conjunto fixo de dados de tipos arbitrários. Uma tupla não tem um nome específico; dar nome a uma estrutura de dados a transforma em uma struct. Os campos de uma tupla não têm nomes; eles são acessados por meio de desestruturação ou por posição.

Sintaxe

Criação

Tuplas são sempre criadas com uma expressão de tupla:

// pointless but legal
let unit = ();
// single element
let single_element = ("note the comma",);
// two element
let two_element = (123, "elements can be of differing types");

Tuplas podem ter um número arbitrário de elementos.

Acesso por desestruturação

É possível acessar os elementos de uma tupla por desestruturação. Isso significa apenas atribuir nomes de variáveis aos elementos individuais da tupla, consumindo-a.

let (elem1, _elem2) = two_element;
assert_eq!(elem1, 123);

Acesso por posição

Também é possível acessar os elementos de uma tupla por índice posicional numérico. A indexação, como sempre, começa em 0.

let notation = single_element.0;
assert_eq!(notation, "note the comma");

Structs de tupla

Você também vai trabalhar com structs de tupla. Assim como structs normais, elas são tipos nomeados; diferente de structs normais, elas têm campos anônimos. A sintaxe delas é muito parecida com a sintaxe normal de tupla. É legal usar tanto desestruturação quanto acesso posicional.

struct TupleStruct(u8, i32);
let my_tuple_struct = TupleStruct(123, -321);
let neg = my_tuple_struct.1;
let TupleStruct(byte, _) = my_tuple_struct;
assert_eq!(neg, -321);
assert_eq!(byte, 123);

Visibilidade dos campos

Todos os campos de tuplas anônimas são sempre públicos. No entanto, os campos de structs de tupla têm visibilidade individual, que por padrão é privada, assim como os campos de structs padrão. Você pode tornar os campos públicos com o modificador pub, assim como em uma struct padrão.

// fails due to private fields
mod tuple { pub struct TupleStruct(u8, i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }
// succeeds: fields are public
mod tuple { pub struct TupleStruct(pub u8, pub i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }

Instruções

Você está trabalhando em um jogo voltado para um sistema embarcado de baixo consumo e precisa escrever várias funções utilitárias que serão usadas por outras partes do jogo.

1. Calcule o quociente e o resto de uma divisão

O quociente é o resultado de uma divisão.

fn divmod(dividend: i16, divisor: i16) -> (i16, i16)

Exemplo:

assert_eq!(divmod(10, 3), (3, 1));

2. Escolha itens em posições pares de um iterador

Isso vai ajudar a viabilizar uma otimização do buffer da tela, promete seu chefe.

Iteradores são itens que expõem os métodos definidos pela trait Iterator. Essa documentação é bastante extensa, porque oferecem muitos métodos; aqui estão as propriedades mais relevantes:

  • Um iterador é um fluxo de itens de tamanho arbitrário
  • Eles têm um método enumerate que retorna uma tupla (i, val) para cada valor
  • Eles têm um método filter que usa uma closure para determinar se deve produzir um elemento do iterador
  • Eles têm um método map que usa uma closure para modificar elementos do iterador

Como sua função pode rodar em qualquer tipo de iterador, ela usa impl para indicar que se trata de uma instância de trait e não de um item simples. Do mesmo modo, a sintaxe <Item=T> significa apenas que não importa que tipo de item o iterador produz; sua função pode produzir os elementos pares de qualquer iterador.

fn evens<T>(iter: impl Iterator<Item=T>) -> impl Iterator<Item=T>

Exemplos:

let mut even_ints = evens(0_u8..);
assert_eq!(even_ints.next(), Some(0));
assert_eq!(even_ints.next(), Some(2));
assert_eq!(even_ints.next(), Some(4));
assert_eq!(even_ints.next(), Some(6));
let mut evens_from_odds = evens(1_i16..);
assert_eq!(evens_from_odds.next(), Some(1));
assert_eq!(evens_from_odds.next(), Some(3));
assert_eq!(evens_from_odds.next(), Some(5));
assert_eq!(evens_from_odds.next(), Some(7));

3. Calcule a distância de Manhattan de uma posição até a origem

Para facilitar o mapeamento, você tem uma struct de tupla Position:

struct Position(i16, i16);

Você precisa implementar um método manhattan em Position que retorna a distância de Manhattan dessa posição até a origem (Position(0, 0)).

impl Position {
    fn manhattan(&self) -> i16
}

Exemplo:

assert_eq!(Position(3, 4).manhattan(), 7);
Editar via GitHub O link abre em uma nova janela ou aba
Rust Exercism

Tudo pronto para começar Jogo embarcado de baixo consumo?

Crie sua conta no Exercism para aprender e dominar Rust com 99 exercícios e mentoria humana de verdade, tudo de graça.