Skip to content

Latest commit

 

History

History
211 lines (181 loc) · 6.07 KB

File metadata and controls

211 lines (181 loc) · 6.07 KB

Problema

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();

Soluções

Solução 1

Enum dos Itens

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
    }
}    

Programa

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;
                    }
                }

            }

        }
    }
}