Ответы пользователя по тегу Алгоритмы
  • Как сделать эффект бесконечного холста?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Можно представить, что у гуглокарт - бесконечный холст. Но это не гигантская картинка, это куча маленьких картинок. Просто потом нужно дорисовать нужные кусочки после скролла.
    1. Делаем двумерный массив картинок (или список списков картинок, чтобы количество можно было легко изменять). Размер картинок может быть любым, как больше размера канваса, так и меньше. Например, размер одной картинки 100x100
    2. Помещаем картинки на холст. Например, размер холста 500x500, то помещаем 25 картинок из массива. Возможно, дополнить по краям ещё по одной картинке, то есть, сделать размер холста 600x600 (или даже 700x700), но показывать только центр
    3. Отключить стандартные скроллбары холста, а скролл сделать самому - перетаскиванием мышки (можно - правой кнопкой, или настроить и скролл мышки). Потому что скроллбар показывает, где сейчас находится окно просмотра в общем документе, а в бесконечном холсте это не имеет смысла
    4. При прокрутке холста проверять, дошли ли до части, где нет картинки, тогда убрать дальний ряд или столбец и дорисовать новый ряд или столбец из массива.
    5. При дорисовке картинок из массива, сменить скролл холста - вернуть холст в центр, как раз там будут нужные картинки после удаления ряда картинок
    Ответ написан
    Комментировать
  • Алгоритм равномерного распределения заявок?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    foreach (var newOrder in newOrders)
    {
        // ищем минимальное количество заявок среди всех менеджеров
        var minOrdersCount = managers.Min(m => m.Orders.Count);
        // ищем менеджера с найденным количеством (если несколько - берём первого)
        var manager = managers.First(m => m.Orders.Count == minOrdersCount);
        // даём заявку менее занятому менеджеру
        manager.Orders.Add(newOrder);
    }

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

    Вот алгоритм посложнее, в нём поисков по всем менеджерам происходит меньше (особенно, когда большое количество новых заявок):
    class Manager
    {
        public string Name { get; private set; }
        public List<int> Orders { get; private set; }
    
        public Manager(string name, int ordersCount = 0)
        {
            Name = name;
            Orders = ordersCount > 0
                ? Enumerable.Range(1, ordersCount).ToList()
                : new List<int>();
        }
    }
    
    static void Main(string[] args)
    {
        var managers = new Manager[]
        {
            new Manager("Лена", 1), 
            new Manager("Оля", 10), 
            new Manager("Иван", 35), 
            new Manager("Сергей", 75), 
        };
        var newOrders = Enumerable.Range(1, 35).ToList();
        var newOrdersCount = newOrders.Count;
        var ordersAssigned = 0;
    
        while (ordersAssigned < newOrdersCount)
        {
            var ordersCounts = managers.Select(m => m.Orders.Count).OrderBy(count => count).Distinct().ToArray();
            var addingOrdersCount = ordersCounts.Length > 1 ? ordersCounts[1] - ordersCounts[0] : ordersCounts.First();
            var managersWithMinOrders = managers.Where(m => m.Orders.Count == ordersCounts[0]).ToArray();
            // нашли менеджеров с минимальным количеством заявок
            if (managersWithMinOrders.Length * addingOrdersCount < newOrdersCount)
            { // заполняем самых незанятых менеджеров до того же уровня занятости
              // т.е. добавляем Лене (10 - 1) = 9 заявок
                foreach (var manager in managersWithMinOrders)
                {
                    for (int i = 0; i < addingOrdersCount; i++)
                    {
                        manager.Orders.Add(newOrders[ordersAssigned]);
                        ordersAssigned++;
                    }
                }
            }
            else
            {
                // незанятых менеджеров нет, заполняем оставшиеся заявки по менеджерам по очереди
                while (ordersAssigned < newOrdersCount)
                {
                    var managerIndex = ordersAssigned % managersWithMinOrders.Length;
                    managersWithMinOrders[managerIndex].Orders.Add(newOrders[ordersAssigned]);
                    ordersAssigned++;
                }
            }
        }
    
        foreach (var manager in managers)
        {
            Console.WriteLine("{0}: {1} заявок", manager.Name, manager.Orders.Count);
        }
        Console.ReadKey();
    }
    Ответ написан
    1 комментарий
  • Как организовать синхронизацию игрового мира между клиентом и сервером?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Посмотрите вопрос https://toster.ru/q/142555, в нём есть некоторые моменты, которые вам пригодятся. Я там привожу несколько ссылок "на почитать".

    А решение вашей задачи будет очень сильно зависеть от количества игроков в одной локации. Если их мало (скажем, меньше пары десятков), то каждая такая локация, скорее всего, будет независимой от других, и задача синхронизации станет сильно проще - меньше объектов будут требовать синхронизации. И на одном сервере поместится несколько таких локаций.

    Если игроков много (сотня и больше), то архитектура очень сильно усложнится. Настолько, что начинать учиться на таком проекте нет никакого смысла. Почитайте про это тот вопрос, что я привёл выше.

    Какая планируется технология на сервере и на клиенте? (язык программирования, платформа)
    Ответ написан
    3 комментария
  • Как выбрать фамилию из текста?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вам нужно переделать формы, в которые пользователь вводит данные. Не давайте ему заполнять всё одним текстом, дайте несколько полей для ввода - Фамилия, Имя, Отчество, Адрес, Комментарий.
    Никаким автоматическим способом нельзя во 100% случаев вытащить данные из произвольно написанной строки. Вы ведь даже не будете уверены, что пользователь все данные вписал. А если сделать отдельные поля для ввода, то вы сможете отдельно проверять их, отдельно хранить. А пользователи уже привыкли вводить все данные отдельно - так сделано почти везде на сайтах, по причинам, указанным выше.
    Ответ написан
    Комментировать