Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Падающие символы

#c_sharp #net


Требуется написать программу которая будет выводит цепочку падающих символов. Первый
снизу символ должен быть белый, второй зеленый, остальные темно-зеленые.
Проблема в том, что цепочку падающих символов вывел, а как смещать цепочку символов
вниз так и не понял. Если я правильно понял то, надо установить курсор в начало строки
и потом уже как-то смещать её вниз.

using System;
namespace Task1
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rand = new Random();
            int lenghtStr = rand.Next(1, 11);
            char[] column = new char[lenghtStr];
            for (int i = 0; i < lenghtStr; i++)
            {
                column[i] = (char)rand.Next('A', 'Z');
            }
            for (int i = 0; i < lenghtStr; i++)
            {
                if (i == (lenghtStr - 1))
                {
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine(column[i]);
                }
                else if (i == (lenghtStr - 2))
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(column[i]);
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    Console.WriteLine(column[i]);
                }
            }
            Console.SetCursorPosition(0, 0);
            Console.ReadKey();
        }
    }
}

    


Ответы

Ответ 1



Создадим такой класс Символа class Sign { //генератор будем использовать в этом классе и снаружи public static Random RandomGen = new Random(); /// /// Получение случайного знака /// /// private char GetSign() { int t = RandomGen.Next(10); if (t <= 2) return (char)('0' + RandomGen.Next(10)); else if (t <= 4) return (char)('a' + RandomGen.Next(27)); else if (t <= 6) return (char)('A' + RandomGen.Next(27)); else return (char)(RandomGen.Next(32, 255)); } /// /// Отображение случайного символа белого цвета /// /// позиция слева /// позиция от верха public void ShowWhiteSign(int left, int top) { Console.ForegroundColor = ConsoleColor.White; Console.SetCursorPosition(left, top); Console.Write(GetSign()); } /// /// Отображение случайного символа зеленого цвета /// /// позиция слева /// позиция от верха public void ShowGreenSign(int left, int top) { Console.ForegroundColor = ConsoleColor.Green; Console.SetCursorPosition(left, top); Console.Write(GetSign()); Console.ForegroundColor = ConsoleColor.White; } /// /// Отображение случайного символа темного зеленого цвета /// /// позиция слева /// позиция от верха public void ShowDarkGreenSign(int left, int top) { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.SetCursorPosition(left, top); Console.Write(GetSign()); Console.ForegroundColor = ConsoleColor.White; } /// /// Отображение пробела в нужном месте /// /// позиция слева /// позиция от верха public void ShowSpaceSign(int left, int top) { Console.SetCursorPosition(left, top); Console.Write(' '); } } Класс Отображателя такой class SignsShower { private int _heightWindow; private int _widthWindow; private int[] _widthPosSimple; private int[] _widthPosAddition; private readonly Sign _sign = new Sign(); //ctor public SignsShower() : this((Console.WindowWidth - 1), Console.WindowHeight) { } /// /// Отображатель символов /// /// ширина консольного окна минус 1 /// высота консольного окна public SignsShower(int windowWidth, int windowHeight) { Initialization(windowWidth, windowHeight); } private void Initialization(int windowWidth, int windowHeight) { //получаем высоту окна _heightWindow = windowHeight; int h1 = _heightWindow / 2; //половина высоты int h2 = _heightWindow / 4; //четверть высоты //ширина окна _widthWindow = windowWidth; //два массива размером в ширину окна _widthPosSimple = new int[_widthWindow]; _widthPosAddition = new int[_widthWindow]; //заполнение массивов случайными числами for (int i = 0; i < _widthWindow; i++) { _widthPosSimple[i] = Sign.RandomGen.Next(_heightWindow); int k = (i % 11 != 10) ? 2 : 1; int min = h2 * k; int max = h1 * k; _widthPosAddition[i] = Sign.RandomGen.Next(min, max); } } /// /// Отображение символов в случайных позициях с необх.цветом /// public void SignShow() { for (int i = 0; i < _widthWindow; i++) { if (_widthPosSimple[i] < 10) { //отображение темного символа _sign.ShowDarkGreenSign(i, _widthPosSimple[i]); } else if (_widthPosSimple[i] < 25) { //отображение зеленого символа _sign.ShowGreenSign(i, _widthPosSimple[i]); } else { //отображаем белый символ _sign.ShowWhiteSign(i, _widthPosSimple[i]); } //сдвигаем координату по высоте для отображения в след. цикле вызова SignShow() _widthPosSimple[i] = CheckNextHeightPosition(_widthPosSimple[i] + 1, _heightWindow); //пробельный символ int next = _widthPosSimple[i] - _widthPosAddition[i]; int nextPos = CheckNextHeightPosition(next, _heightWindow); _sign.ShowSpaceSign(i, nextPos); } } /// /// Проверка значения след.позиции /// /// значение след.положения по высоте /// общая допустимая высота /// private int CheckNextHeightPosition(int next, int height) { next = next % height; if (next < 0) { return next + height; } else { return next; } } } Теперь включим в работу эти классы так static void Main(string[] args) { //отображатель SignsShower signsShower = new SignsShower(); //готовим консоль Console.Clear(); Console.CursorVisible = false; //в бесконечном цикле с вычисляемой задержкой отображаем int ms = 0; while (true) { //засекаем время DateTime timeMark = DateTime.Now; //отображаем символы signsShower.SignShow(); //задержка ms = 10 - (int)((TimeSpan)(DateTime.Now - timeMark)).TotalMilliseconds; if (ms > 0) System.Threading.Thread.Sleep(ms); } } Не знаю, правильно ли я вас понял, но по крайней мере у вас теперь есть от чего плясать.

Ответ 2



Конечно моё решение не такое красивое и лаконичное как у @Bulson, но думаю оно всё таки тоже имеет право на существование. Захотелось придумать что-то своё, извращённое так скажем;) using System; using System.Threading; namespace Task1 { class Program { static object locker = new object(); static int Generate(int a, int b) // Метод генерирования рандомных чисел { Random rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); return rand.Next(a, b); } static void Matrix(object numberColumn) // метод вывода столбцов с символами, в качестве параметра принимает позицию строки курсора { while(true) { int lenghtColumn = 0; int position = 0; // Позиция столбца курсора const int maxLenght = 40; // максимальная длинна столбца Random rand = new Random(); int count = Generate(25, 39); //длинна столбца Thread.Sleep(555); for (int i = 0; i != maxLenght + count; i++) { lock (locker) { Console.ForegroundColor = ConsoleColor.Black; //Задаём чёрный цвет тексту for (int j = 0; j <= position; j++) // В цикле закрашиваем символы черным квадратом { Console.SetCursorPosition((int)numberColumn, j); // Устанавливаем позицию курсора Console.WriteLine("█"); // Так как мы поменяли цвет текста в консоли на чёрный, то квадрат не будет красным } if (lenghtColumn < count && position != 40) { ++lenghtColumn; } else if (position == maxLenght) { --lenghtColumn; } if (lenghtColumn >= 3) { for (int k = position - (lenghtColumn - 1); k <= position - 2; k++) { Console.SetCursorPosition((int)numberColumn, k); Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine((char)rand.Next('A', 'z')); } } if (lenghtColumn >= 2) { Console.SetCursorPosition((int)numberColumn, position - 1); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine((char)rand.Next('A', 'z')); } if (lenghtColumn >= 1) { Console.SetCursorPosition((int)numberColumn, position); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine((char)rand.Next('A', 'z')); if (position != maxLenght) position++; } } } } } static void Main(string[] args) { Console.SetWindowSize(100, 42); Thread t; for (int i = 0; i < 100; i++) { t = new Thread(Matrix); t.Start(i); } Console.ReadKey(); } } }

Комментариев нет:

Отправить комментарий