Игра «Лифты» – это пошаговый симулятор управления несколькими лифтами в многоэтажном здании. Ходы нумеруются, начиная с 0, этажи пронумерованы, начиная с 1, лифты пронумерованы, начиная с 0. Лифты могут передвигаться с первого по последний этаж со скоростью 1 этаж за 1 ход, останавливаться на любом из этажей по маршруту движения и менять направление на любом ходу. Во время игры на этажах появляются клиенты (не более одного за ход) и программе, управляющей лифтами, поступает информация, куда они хотят поехать: вверх или вниз. Клиенты ждут лифт ограниченное количество ходов и, не дождавшись, разгневанные, идут пешком. Клиент считается обслуженным, если он доехал до своего этажа и вышел из лифта. Все остальные клиенты считаются необслуженными. За каждого обслуженного и необслуженного клиента программа участника получает штрафные очки (подробности в п.4). Цель игры – заработать как можно меньше штрафных очков.
Каждый лифт каждый ход выполняет одну из 5 команд, поступающих от программы участника:
Если лифт не в состоянии выполнить указание игрока, например, если игрок попытается переместить его с первого этажа вниз или с последнего вверх, то лифт воспримет команду «оставаться на месте».
Каждый лифт может останавливаться и открывать двери, при этом высаживая клиентов, для которых этот этаж является этажом назначения, и приглашая на посадку новых клиентов, которых устраивает направление движения, указанное лифтом. Клиенты заходят в лифт по очереди в порядке их (клиентов) появления. Если несколько лифтов одновременно открыли двери на одном и том же этаже, указав, что поедут в одном направлении, то клиенты заполняют их по очереди, в порядке возрастания номеров лифтов: сначала клиенты заходят в лифт с наименьшим номером, если он заполнился – в следующий лифт и т.д. Каждый зашедший в лифт клиент сообщает, до какого этажа он хочет ехать.
На старте игры все лифты находятся на первом этаже в закрытом состоянии.
Участник турнира должен предоставить своё решение жюри в виде одного файла с исходным текстом программы, написанным на одном из поддерживаемых языков программирования: C#, Java и C++. При компиляции решения жюри предполагает получить один .exe файл, если решение написано на языке C# или C++; либо серию из .class файлов (класс и его вложенные классы), если решение написано на языке Java.
Для взаимодействия тестирующей системы с программой участника используются стандартные потоки ввода/вывода (те, которые обычно связаны с клавиатурой и дисплеем). В начале каждой игры тестирующая система создаёт новый процесс, в котором запускает игрока; программа участника не должна завершать свою работу самостоятельно.
После старта программа участника начинает получать через стандартный поток ввода запросы. Все запросы устроены одинаково: в первой строке запроса содержится идентификатор запроса: «GetName», «SetParams» или «GetAction» (без кавычек). Начиная со второй строки идут данные, если это предполагается запросом.
Запрос GetName не содержит никаких дополнительных данных. Ответ на такой запрос должен состоять из строки, содержащей имя игрока. Имя игрока может содержать заглавные и строчные английские буквы, цифры и символы '_', '(', ')', '+', '-'. Длина имени не должна превышать 32. Запрос GetName будет вызван ровно 1 раз в самом начале игры.
Пример ответа на запрос GetName:VasyaIvanovSuperBot
При запросе SetParams во второй строке передаются основные параметры игры в виде 3 чисел: количество этажей, количество лифтов и полное время игры. Игроку не нужно отвечать на этот запрос. Запрос SetParams будет вызван ровно 1 раз перед первым вызовом запроса GetAction.
Пример запроса SetParams:SetParams
20 4 1500
Запрос GetAction – основной запрос в игре. Во второй строке запроса передаются 2 числа: номер хода и этаж нового заказа. Eсли в данный ход новый клиент не появился, то этаж нового заказа равен «-1», иначе следом через пробел идет направление, в котором новый клиент хочет ехать. Направление обозначается символом 'U' или 'D' – соответственно, вверх или вниз. В третьей строке идет одно число – количество лифтов, в которые на этом ходу кто-то зашёл. Далее в отдельной строке для каждого из этих лифтов даны номер этого лифта, количество зашедших в него клиентов и список этажей, на которые хотят ехать эти клиенты. В списке каждый этаж встречается столько раз, сколько клиентов желают попасть на него. В ответ на запрос GetAction игрок должен вывести отдельной строкой команды лифтам, указанные в п.2.
Пример запроса GetAction:GetAction
15 5 U
1
0 2 5 9
Пример ответа на запрос GetAction:DSuU
Параметры:
Константы:
Формула вычисления штрафных очков за каждого обслуженного клиента:
TotalTime – время с момента появления клиента, до момента приезда на свой этаж
Diff – количество этажей, которое надо проехать клиенту
Рассмотрим простой пример игры. Допустим, у нас есть 10-этажный дом с 2 лифтами, и на первом ходу на первом этаже появляется клиент, который хочет доехать до третьего этажа. В таблице приведена информация о том, какие параметры будут передаваться программе участника в ходе запросов GetAction («Номер хода», «Информация о новых заказах», «Информация о посадках в лифты»), и примеры команд, которые она может отдавать лифтам.
Номер хода | Этажи расположения и состояния лифтов | Информация о новых заказах | Информация о посадках в лифты | Команды лифтам |
---|---|---|---|---|
0 | 1 (закрыт), 1 (закрыт) | -1 | 0 | SS |
1 | 1 (закрыт), 1 (закрыт) | 1 U | 0 | uS |
2 | 1 (открыт), 1 (закрыт) | -1 | 1 0 1 3 | US |
3 | 2 (закрыт), 1 (закрыт) | -1 | 0 | US |
4 | 3 (закрыт), 1 (закрыт) | -1 | 0 | uS |
5 | 3 (открыт), 1 (закрыт) | -1 | 0 | SS |
На ходу №0 ничего не произошло. На ходу №1 на первом этаже появился клиент, который нажал кнопку вызова лифта «вверх». На ходу №2 он садится в открывшийся лифт №0, при этом сообщает, что хочет ехать на третий этаж. На ходу №5 клиент выходит на своем этаже.
В решении участника запрещено:
При нарушении этих правил к команде-участнику будут применены санкции вплоть до немедленной дисквалификации с игрового тура без права участия в основном туре Чемпионата Урала!
Кроме того, решение участника должно быть корректным. Это включает в себя следующее:
В время игрового тура участникам будет предоставлена система для локальной проверки и визуализации решений, 2 теста, а также несложные реализации программ-игроков на всех трех допустимых языках программирования (т.н. сэмпл-боты). Участники могут расширить функционал сэмпл-бота, либо написать полностью свое решение, используя сэмпл-бота как пример взаимодействия с проверяющей системой.
В ходе игрового тура будут произведены 2 промежуточные проверки решений, сданных участниками, на 2 первых системных тестах. Первая промежуточная проверка будет произведена через 40 минут после начала тура. Ее результаты появятся через 1 час 20 минут после начала тура. Вторая промежуточная проверка будет произведена через 1 час 40 минут после начала. Ее результаты появятся через 2 часа 20 минут после начала. Результаты, показанные участниками на промежуточных проверках, не учитываются при подведении итогов.
По окончании тура будет произведена проверка последних версий программ участников на нескольких системных тестах. По каждому тесту команды ранжируются по штрафным очкам, и им присуждаются баллы, согласно занятым местам и таблице:
Место | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Баллы | 60 | 54 | 48 | 43 | 40 | 38 | 36 | 34 | 32 | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 |
Место | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
Баллы | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
Победителем тура становится команда с максимальным количеством баллов. В случае равенства баллов смотрится количество побед на тестах, затем – количество вторых мест и т.д.