37 - Escreve um programa que crie aleatoriamente um mundo de jogo tile-based
2D e o mostre no ecrã. O tamanho do mundo, x
e y
, deve ser indicado sob a
forma de argumentos na linha de comandos. Cada célula (quadrado ou posição) do
mundo de jogo pode ter, cumulativamente e com a probabilidade indicada, os
seguintes items:
- Comida - 1,0%
- Armas - 0,5%
- Inimigo - 0,5%
- Armadilha - 0,3%
Os items devem ser representados com enumerable flags (opções enumeráveis),
assim como as suas combinações. Espaços vazios devem ser representados com um
espaço, e as várias combinações de items devem ser representados com o caracter
ASCII obtido pela soma do valor ASCII do espaço (0x20) com o valor numérico do
item ou combinação de items enumerados. Por exemplo, a comida é representada
com o carácter !
(ASCII 0x21), e a combinação de inimigo e armadilha é
representada com o carácter ,
(ASCII 0x2C).
Nota 1: A tabela ASCII pode ser consultada aqui.
Nota 2: Pode facilitar a resolução do problema fazer debugging imprimindo
no ecrã os conteúdos detalhados de cada posição do mundo de jogo, por exemplo
para a posição (5,3) pode ser impresso (5,3) contem 'Comida, Inimigo', caráter %
.
Nota 3: Podem ser obtidos números aleatórios entre 0 e 1 usando o método NextDouble da classe Random (namespace System) da seguinte forma:
// Criar objecto do tipo Random
Random rng = new Random();
// Obter double entre 0 e 1
double probability = rng.NextDouble();
using System;
namespace exercicio_37
{
/// <summary>
/// Items possíveis de colocar na criação do mapa
/// </summary>
[Flags]
enum Items
{
Food = 1 << 0,
Weapon = 1 << 1,
Enemy = 1 << 2,
Trap = 1 << 3
}
}
using System;
namespace exercicio_37
{
/// <summary>
/// Class principal que contem o programa
/// </summary>
class Program
{
/// <summary>
/// Método principal do programa
/// </summary>
/// <param name="args">
/// argumentos passados ao programa
/// </param>
static void Main(string[] args)
{
// Variaveis necessárias ao main()
Items[,] board;
int x, y;
if (args.Length < 2)
{
Console.WriteLine("You have to Run the program " +
"with 2 arguments x, y");
return;
}
// Guardar dimensões do mapa a ser criado
x = Convert.ToInt32(args[0]);
y = Convert.ToInt32(args[1]);
// Criar matriz de Items
board = new Items[x, y];
// Gerar números e colocar items nas células
GenerateItems(board);
// Desenhar o mapa
DrawBoard(board);
}
/// <summary>
/// Imprime o mapa gerado a partir da matriz _board_
/// </summary>
/// <param name="board">
/// Matriz bidimensional do tipo Items
/// </param>
private static void DrawBoard(Items[,] board)
{
// Número total de células a imprimir
int rows;
int cols;
char c;
rows = board.GetLength(0);
cols = board.GetLength(1);
// Desenhar topo
DrawLine(cols);
// Desenhar conteúdo do mapa
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
c = (char)(0x20 + board[i, j]);
if (j == 0)
Console.Write($"|{c}|");
else
Console.Write($"{c}|");
}
Console.WriteLine();
}
// Desenhar fundo
DrawLine(cols);
}
/// <summary>
/// Desenha uma linha na consola
/// </summary>
/// <param name="cols">
/// Número de caractéres que se quer ocupar
/// </param>
private static void DrawLine(int cols)
{
for (int i = 0; i < cols; i++)
if (i == 0)
Console.Write(" — ");
else
Console.Write("— ");
Console.WriteLine();
}
/// <summary>
/// Gera os items a partir da enum Items e coloca-os no mapa
/// </summary>
/// <param name="board">
/// Matriz do tipo Items representativa do mapa 2D
/// </param>
private static void GenerateItems(Items[,] board)
{
// Inicializar objeto do tipo Random
Random rng = new Random();
// Variavel para guardar probabilidade
double probability;
for (int i = 0; i < board.GetLength(0); i++)
{
for (int j = 0; j < board.GetLength(1); j++)
{
// Gerar numero entre 0 e 1
probability = rng.NextDouble();
// Escolher item através da probabilidade
if (probability < 0.01)
{
board[i, j] |= Items.Food;
}
probability = rng.NextDouble();
if (probability < 0.005)
{
board[i, j] |= Items.Weapon;
}
probability = rng.NextDouble();
if (probability < 0.005)
{
board[i, j] |= Items.Enemy;
}
probability = rng.NextDouble();
if (probability < 0.003)
{
board[i, j] |= Items.Trap;
}
}
}
}
}
}