Tarefa 6 - Minecraft

Prazo de entrega recomendado:

Você realizará operações em mapas de minecraft criados a partir de uma seed. Para isso, precisará alocar matrizes dinamicamente, armazenar dados nessas matrizes e manipulá-las através da passagem por referência para funções.


Pedro é um adolescente de 16 anos que, como qualquer outro adolescente nessa idade, só pensa em uma coisa: Minecraft. Acontece que as aulas de Pedro voltaram e agora ele não possui mais tanto tempo para minerar no seu mundo quadrado. Ele está cansado de criar novos mundos no jogo e não encontrar muitos materiais, ou precisar de muito tempo de mineração para encontrar uma boa quantidade, o que não é divertido para quem tem pouco tempo para jogar.

Os mundos de Minecraft são gerados a partir de uma seed (semente). O jogo cria um mundo novo para cada seed escolhida pelo jogador e também permite que o mesmo mundo seja replicado apenas utilizando a mesma seed. Pedro sabe que você conhece a forma como os mundos são gerados e pede sua ajuda. Ele deseja que você faça um programa chamado minecraft.c que, dadas a seed e as dimensões do mundo, diga quanto de cada material será possível encontrar nele e qual o tempo estimado para toda a mineração. Com isso, ele pretende escolher melhor o mundo antes de jogar.

Como os mundos são gerados?

No Minecraft os mundos são tridimensionais com largura $m$ (eixo-$x$) e profundidade $n$ (eixo-$z$) variáveis e altura fixa de 256 blocos (eixo-$y$). Apesar de um mundo sempre possuir 256 blocos de altura, isso não significa que todos esses blocos estão ocupados, afinal o jogador precisa de espaço para construir e explorar. Nessa tarefa, dada uma seed $s$, considere que o mundo é criado como mostrado a seguir.

Primeiramente, o jogo calcula a altitude de cada coordenada. A altitude de uma coordenada $(x, z)$ representa o bloco mais alto dessa coordenada e é dada por $H(x,z)$, como na fórmula a seguir:

$$ H(x, z) = (s \times (202 + x + z) + 12345 + x + z) \mod 256. $$

Em seguida, para cada coordenada $(x,z)$, começando pela altitude mínima $y = 0$ até a altitude máxima $y = 255$, o jogo calcula o tipo de cada bloco $M(x, y, z)$, seguindo a fórmula:

$$ M(x, y, z) = \begin{cases} 21,& \text{se } y > H(x, z) \\\ (s \times (202 + x + y + z) + x + y + z) \mod 33,& \text{caso contrário}.\end{cases} $$

Observe que todos os blocos acima da altitude recebem o valor $21$, que corresponde ao bloco vazio. Os tipos dos blocos devem ser interpretados como na tabela a seguir:

Valor de $M(x, y, z)$ Tipo do Bloco
0 Diamante
1 ou 2 Ouro
3 a 5 Ferro
6 a 11 Pedra
12 a 20 Terra
21 a 23 Bloco Vazio
24 a 28 Água
29 a 32 Lava

Note que também é possível existir blocos vazios abaixo da terra, como na caverna da imagem a seguir:

Entrada

A primeira linha contém dois inteiros $m$ e $n$ indicando as dimensões de largura e profundidade do mundo. A linha seguinte contém um inteiro $s$ correspondente à seed do mundo criado. Por fim, a terceira linha contém um número real indicando o tempo médio em segundos necessário para a mineração de cada bloco.

Exemplo de entrada

3 3
123123
1.5

Saída

A saída deve ser formada por $5$ linhas. A primeira deve ser um inteiro indicando a quantidade de blocos a serem minerados no mapa (isto é, blocos que não são vazios, de água ou lava) e a segunda um valor real com duas casas decimais indicando quantos segundos seriam necessários para minerar todo o mapa. As três linhas seguintes devem indicar quantos blocos de diamante, ouro e ferro, respectivamente, existem no mapa.

Exemplo de saída

Total de Blocos: 1311
Tempo total: 1966.50s
Diamantes: 58
Ouros: 123
Ferros: 197

Critérios

É obrigatório utilizar alocação dinâmica de matrizes nessa tarefa e implementar as funções do arquivo minecraft.h. Você também pode criar novas funções se julgar necessário.

Lembre-se de desalocar toda a memória alocada dinamicamente na tarefa. Dica: use o valgrind para identificar blocos de memória que permaneceram alocados ao final da execução.

Correção

Esta tarefa será corrigida automaticamente sempre que você realizar um git push. Depois de terminada a tarefa, deve-se utilizar o botão na interface de notas para solicitar a correção de um monitor.

Turma AB: O peso desta tarefa é 2.

Turma E: Você deverá apresentar esta tarefa a um monitor PED. Para isso, você deve procurar atendimento em algum horário com monitor PED e digitar apresentar 6 no canal fila-apresentar.