исправь код, чтобы выполнялись условия
•	Общее количество появившихся в секунду линий должно соответствовать заданной частоте появления.
•	Если частота n линий в секунду, то генерируется n случайных временных промежутков в диапазоне от 0 до 1000 миллисекунд (одна секунда). Это определяет, в какой момент времени каждая линия начнёт своё движение. 
•	Например, если сгенерированы промежутки 200 мс, 700 мс и 400 мс, линии начнут двигаться в следующем порядке: первая линия через 200 мс от начала итерации, вторая через 400 мс от начала и третья - через 700 мс.


#include <iostream>
#include <vector>
#include <cstdlib>
#include <conio.h>
#include <thread>
#include <chrono>
#include <windows.h>
#include <limits>
#include <algorithm>

class Random {
public:
    static char getRandomCharacter() {
        const char characters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+[]{}|;':\",.<>?~";
        return characters[rand() % (sizeof(characters) - 1)];
    }

    static int getRandomColor() {
        return 1 + rand() % 15;
    }

    static int getRandomPosition(int limit) {
        return rand() % limit;
    }

    static int getRandomDelay() {
        return rand() % 1000; // Random delay in milliseconds (0-1000)
    }
};

class ConsoleUtils {
public:
    static void getConsoleSize(int& width, int& height) {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
        width = csbi.srWindow.Right - csbi.srWindow.Left + 1;
        height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    }

    static void hideCursor() {
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(hConsole, &cursorInfo);
        cursorInfo.bVisible = FALSE;
        SetConsoleCursorInfo(hConsole, &cursorInfo);
    }

    static void clearScreen() {
        system("cls");
    }
};

class Symbol {
public:
    Symbol(char character = ' ', int color = 10) : character(character), color(color) {}

    char getCharacter() const { return character; }
    void setCharacter(char character) { this->character = character; }

    int getColor() const { return color; }
    void setColor(int color) { this->color = color; }

private:
    char character;
    int color;
};

class Line {
public:
    Line(int length, bool epilepsyMode) : length(length), epilepsyMode(epilepsyMode) {
        lineColor = epilepsyMode ? Random::getRandomColor() : 10;
        for (int i = 0; i < length; ++i) {
            char randomChar = Random::getRandomCharacter();
            int color = epilepsyMode ? lineColor : 10;
            symbols.push_back(Symbol(randomChar, color));
        }
    }

    void move() {
        symbols[0] = Symbol(' ', 7); // Replacing the first symbol with a space
        for (int i = 1; i < length - 1; ++i) {
            symbols[i] = symbols[i + 1]; // Shifting symbols to the right
        }
        generateNewSymbol(length - 1); // Generating a new random symbol on the right
    }

    void draw(HANDLE hConsole, int position, int consoleWidth, int startPosition) const {
        COORD cursorPos;
        int startIndex = std::max(0, -position);
        int visibleLength = std::min(length - startIndex, consoleWidth - position);

        for (int i = startIndex; i < startIndex + visibleLength; ++i) {
            setColor(getColor(i));
            cursorPos.X = static_cast<SHORT>(position + i);
            cursorPos.Y = startPosition;
            SetConsoleCursorPosition(hConsole, cursorPos);
            std::cout << getCharacter(i);
        }
    }

private:
    int length;
    std::vector<Symbol> symbols;
    bool epilepsyMode;
    int lineColor;

    void generateNewSymbol(int index) {
        char newChar = Random::getRandomCharacter();
        int color = epilepsyMode ? lineColor : 10;
        symbols[index] = Symbol(newChar, color);
    }

    char getCharacter(int index) const {
        if (index >= 0 && index < symbols.size()) {
            return symbols[index].getCharacter();
        }
        return ' ';
    }

    int getColor(int index) const {
        if (index >= 0 && index < symbols.size()) {
            return symbols[index].getColor();
        }
        return 7;
    }

    void setColor(int color) const {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
    }
};

class AppManager {
public:
    AppManager() : speed(1), length(10), epilepsyMode(false), running(true), frequency(5) {
        srand(static_cast<unsigned int>(time(nullptr)));
        ConsoleUtils::getConsoleSize(consoleWidth, consoleHeight);
    }

    void start(int argc, char* argv[]) {
        if (argc == 4) {
            if (!parseCommandLineArgs(argv)) {
                return;
            }
        } else {
            configureSettings();
        }

        ConsoleUtils::hideCursor();

        system("cls");
        std::cout << "Matrix Simulation is starting..." << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));

        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

        while (running) {
            int startPosition = Random::getRandomPosition(consoleHeight - 1);

            // Generate delays for each line to appear in random moments within the second
            std::vector<int> delays;
            for (int i = 0; i < frequency; ++i) {
                delays.push_back(Random::getRandomDelay()); // Generate random delay for each line
            }

            // Sort delays in increasing order to simulate line appearance in different times
            std::sort(delays.begin(), delays.end());

            // Create lines based on sorted delays
            std::vector<Line> lines;
            for (int delay : delays) {
                std::this_thread::sleep_for(std::chrono::milliseconds(delay)); // Wait for the delay before creating the line
                lines.push_back(Line(length, epilepsyMode)); // Create new line
            }

            // Start moving the lines after they have appeared
            int position = -length; // Start position of lines
            auto startTime = std::chrono::steady_clock::now();
            while (position < consoleWidth) {
                for (auto& line : lines) {
                    line.draw(hConsole, position, consoleWidth, startPosition);
                    line.move();
                }

                // Wait for the next frame
                std::this_thread::sleep_for(std::chrono::milliseconds(1000 / speed));

                ++position;

                // Check for quit input
                if (_kbhit() && _getch() == 'q') {
                    running = false;
                    break;
                }
            }

            // Clear screen between iterations
            ConsoleUtils::clearScreen();
        }
    }

private:
    int speed;
    int length;
    bool epilepsyMode;
    bool running;
    int frequency;  // Number of lines that should appear per second
    int consoleWidth;
    int consoleHeight;

    void configureSettings() {
        std::cout << "Welcome to the Matrix Simulation!" << std::endl;
        std::cout << "Press 'q' anytime to quit the simulation." << std::endl;

        std::cout << "Enter speed (1 - 30): ";
        while (!(std::cin >> speed) || speed < 1 || speed > 30) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Invalid input. Please enter a number between 1 and 30: ";
        }

        std::cout << "Enter line length (1 - 30): ";
        while (!(std::cin >> length) || length < 1 || length > 30) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Invalid input. Please enter a number between 1 and 30: ";
        }

        std::cout << "Enter line frequency (1 - 30 lines per second): ";
        while (!(std::cin >> frequency) || frequency < 1 || frequency > 30) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Invalid input. Please enter a number between 1 and 30: ";
        }

        char input;
        std::cout << "Epilepsy mode (Y/N)? ";
        while (!(std::cin >> input) || (input != 'Y' && input != 'y' && input != 'N' && input != 'n')) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Invalid input. Please enter 'Y' for Yes or 'N' for No: ";
        }
        epilepsyMode = (input == 'Y' || input == 'y');
    }

    bool parseCommandLineArgs(char* argv[]) {
        try {
            speed = std::stoi(argv[1]);
            length = std::stoi(argv[2]);
            frequency = std::stoi(argv[3]);

            if (speed < 1 || speed > 30 || length < 1 || length > 30 || frequency < 1 || frequency > 30) {
                std::cout << "Error: Invalid arguments." << std::endl;
                return false;
            }
        } catch (...) {
            std::cout << "Error: Invalid arguments." << std::endl;
            return false;
        }

        return true;
    }
};

int main(int argc, char* argv[]) {
    AppManager app;
    app.start(argc, argv);
    return 0;
}