Программа должна печатать ромб одним из значков (* или + или #)

612
09 сентября 2018, 00:30

Компилятор никакой ошибки не выдает, но массив не печатает. Что не так?

Вот код:

using System;
using System.Collections.Generic;
namespace PROJECT2
{
   class MainClass
{
    public static void Main (string[] args)
    {
        Console.WriteLine ("Введите 1, чтобы ромб был напечатан символом '*', ");
        Console.WriteLine ();
        Console.WriteLine ("Введите 2, чтобы ромб был напечатан символом '+', ");
        Console.WriteLine ();
        Console.WriteLine ("Введите 3, чтобы ромб был напечатан символом '#'. ");
        int inputNum = Convert.ToInt32 (Console.ReadLine ());
        List<string> forRhombus = new List<string> ();

        switch (inputNum) 
        {
        case 1:
            string a = "*";
            Console.WriteLine ("Введите нечетную длину стороны ромба от 5 до 15: ");
            int lenght1 = Convert.ToInt32 (Console.ReadLine ());
            int p = 1;
            if ((lenght1 >= 5) && (lenght1 <= 15))
            {   
                for (int x = 0; x < lenght1; x++)
                {
                    forRhombus.Add (" ");
                }
                if (lenght1 % 2 != 0)
                {   
                    for (int y = 0; y < lenght1; y++)
                    {
                        if (y == lenght1 / 2.0 + 0.5) 
                        {   
                            forRhombus [y] = a;
                            Console.WriteLine (forRhombus);
                        }
                        if ((p < y) && (p < lenght1)) 
                        {
                            forRhombus [y + p] = a;
                            forRhombus [y - p] = a;
                            p += 1;
                        }   
                        Console.WriteLine (forRhombus);
                    }
                }   
            }
            break;

        case 2:
            string b = "+";
            Console.WriteLine ("Введите нечетную длину стороны ромба от 5 до 15: ");
            int lenght2 = Convert.ToInt32 (Console.ReadLine ());
            break;
        case 3:
            string c = "#";
            Console.WriteLine ("Введите нечетную длину стороны ромба от 5 до 15: ");
            int lenght3 = Convert.ToInt32 (Console.ReadLine ());
            break;
        }      
    }
}
Answer 1

Разбивайте свой код на функции (методы), которые выполняют одну функцию. В вашем варианте можно разбить так:

  • основной метод Main();
  • метод с меню;
  • метод с созданием ромба;
  • метод с выводом ромба.

Некоторые замечания по вашему коду:

  • для переноса каретки (вывод в консоли с новой строки) можно использовать специальный символ \n, а не дублировать лишний раз WriteLine(). Например: Console.WriteLine("\n <- Новая строка -> \n");
  • для таких простых задач как запись и чтение данных по индексу, расточительно использовать коллекции, уж тем более с типом string (я про List<string> forRhombus), куда правильнее будет использовать массив char;
  • так как ромб, хоть и из символов, является каким-никаким рисунком, то есть имеет высоту и ширину, то логичнее и проще для понимания использовать двумерный массив (матрицу, char[,]), а не одномерный, хотя можно и его. Вариант с одномерным массивом приведён ниже.
  • Convert.ToInt32(Console.ReadLine()) действительно преобразует строку с числом в тип int. Ну а если пользователь введёт букву или вообще ничего не введёт? Приложение крашнется, так как символ не удалось преобразовать в число. Для таких случаев обычно используется метод Int32.TryParse(String, Int32), который возвращает true при успешном преобразовании строки в число и false в противном случае. Также второй параметр является out-параметром, что очень удобно. Изучите этот момент, он сильно поможет при работе с пользовательскими данными, которые вводятся от руки;
  • для вывода массива или списка понадобится написать собственный метод с циклом (или использование анонимных методов и LINQ, но пока не лезьте в эти сложные темы), так что ваш вариант Console.WriteLine(forRhombus) просто не будет работать;
  • не забывайте про секцию default в операторе switch() - это важно.

Моя реализация рисования ромба основывается на том, что у ромба все углы равны и необходимо нарисовать его закрашенным, а не только контур. Ниже приведён метод, принимающий размер стороны ромба, символ для ромба и для заднего фона, который возвращает одномерный массив:

private static char[] GetFillRhombus(int size, char foreground, char background = ' ')
{
    if (size > 1)
    {
        char[] map = new char[Convert.ToInt32(Math.Pow((size * 2 - 1), 2))];
        // Заполнение всего массива задним фоном
        for (int i = 0; i < map.Length; i++)
        {
            map[i] = background;
        }
        // Заполнение верхней части ромба с серединой
        for (int i = 1; i < size * 2; i += 2)
        {
            int startPosition = size * i - i;
            for (int j = startPosition; j < startPosition + i; j++)
            {
                map[j] = foreground;
            }
        }
        // Заполнение нижней части ромба без середины
        for (int i = 0, j = size - 2 - i; j >= 0; i++, j--)
        {
            int middlePosition = (size + i) * (size * 2) - (i + 1);
            for (int k = middlePosition - j; k < middlePosition + j + 1; k++)
            {
                map[k] = foreground;
            }
        }
        return map;
    }
    return null;
}

Далее этот массив надо вывести пользователю на экран:

private static void PrintRhombus(char[] map)
{
    if (map != null)
    {
        int size = Convert.ToInt32(Math.Sqrt(map.Length));
        for (int i = 0, j = 0; i < map.Length; i++, j++)
        {
            Console.Write(map[i]);
            if (j == size - 1)
            {
                j = -1;
                Console.WriteLine("");
            }
        }
    }
}

Использование сводится к 1-2 строчкам кода:

static void Main(string[] args)
{
    char[] rhombus = GetFillRhombus(20, '#', '.');
    PrintRhombus(rhombus);
    Console.ReadKey();
}

Результат, ромб со стороной в 20 символов:

READ ALSO
Помогите со скриптом в Unity

Помогите со скриптом в Unity

Как сделать так, чтобы по нажатию мышкой (тапом) несколько раз, персонаж ускорялсяНапример, на денди была игра Hyper Sports (Прыжки в длину, бег на 100 м и тд)

194
Как отправить атрибуты используя WSDL Zimbra

Как отправить атрибуты используя WSDL Zimbra

Всем привет, создаю почту, но никак не понимаю как туда добавить атрибуты типо displayname,sn и givennameЗапрос через браузер выглядит так

217
Идентификация nullable типа

Идентификация nullable типа

Есть функция, принимающая object argВ самой функции требуется получить тип переданного объекта

190
Отдельный роутинг для /api в SPA

Отдельный роутинг для /api в SPA

Хочу написать AspNet Core SPA

195