ICFPC 2020: день третий

    •     icfpc, programming

Это четвёртая часть моей серии отчётов об ICFPC 2020. Остальные части ищите здесь:

  1. предисловие;
  2. день первый;
  3. день второй;
  4. день третий (это то, что вы сейчас читаете);
  5. день четвёртый;
  6. итоги и выводы.

19-е июля, воскресенье, Z-30:17. Обратно в бой!

Перечитывая с утра командный чатик, обнаруживаю, что pink-snow написал ещё одну «вычислялку», в этот раз на Haskell. Она полностью следует псевдокоду организаторов и, что самое важное, работает. Теперь portnov и pink-snow выделяют её в отдельное приложение, а ForNeVeR модифицирует свой проект на C#, чтобы GUI при каждом клике вызывал Haskell и рисовал результат.

unclechu тем временем закончил работу над демодулятором и ушёл спать. Соперники заваливают Дискорд картинками из игры, и страсти накаляются: нам уже совсем-совсем пора добраться до туториалов, которые многие команды прошли ещё вчера.

В Z-30:17 ForNeVeR наконец получает первую картинку:

Первый результат `galaxy`: красная иконка галактики в центре, число
    1 в левом верхнем углу

Пообедав, он выкатывает новую версию GUI с масштабированием, и я отправляюсь исследовать Галактику — в смысле, galaxy.txt. После нескольких кликов по иконке галактики идёт десяток экранов, где нужно кликать в пересечение горизонтальной и вертикальной линий — некая калибровка. А потом отображается та самая картинка, которую недавно показали нам организаторы:

Галактика с обозначениями рас

У некоторых рас есть «игры», и я погружаюсь в угадывание правил одной из них; portnov и Akon32, похоже, увлечены тем же самым. Один из только что проснувшихся сокомандников недоумевает:

<xxx> теперь у нас приложение на шарпе, а не на х-ле или питоне?
<yyy> Шарповый фронтенд с хаскельным бэкендом
<zzz> Да, планируем каждые восемь часов переписывать.

ForNeVeR и mr146 заняты улучшением GUI, а pink-snow помогает им, впиливая в «вычислялку» поддерживающие фичи.

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

Решения первых уровней похожи на разные повороты и отражения «глайдера» из игры «Жизнь» Конвея. Следующие уровни решаются каким-то странным шаблоном, уже не похожим на «Жизнь». Чатик тем временем подгоняет:

<xxx> первые четыре уровня прошли, осталось ещё 8 или 9
<yyy> из туториала в игре? <_<
<zzz> нет :(
<zzz> В игру мы пока не залогинились
<xxx> да, тут капча
<xxx> инопланетная
<yyy> её нужно прокликать
<xxx> yyy: я так и делаю!

Из-за каких-то изменений в GUI и «вычислялке» появляется забавный баг: если дважды быстро кликнуть в GUI, то второй клик не будет проигнорирован. Вместо этого он будет применён после первого и, возможно, как-то повлияет на состояние игры. Мне флегматично советуют не кликать так быстро. Люблю нашу команду, такие отзывчивые люди, ух! ^_^

Тут mr146 подвозит в GUI возможность сохранять, загружать и править состояние вселенной, и играть становится совсем удобно: больше не нужно «прокликивать» экраны калибровки, а в случае ошибки в игре можно откатиться на предыдущий ход.

Z-24:00. Мы снова вспоминаем про IngvarJackal-а

Так и не решив девятый уровень, я ухожу обедать. Вернувшись, обнаруживаю, что организаторы опубликовали описание команд, которые нужно слать по HTTP для управления космическим кораблём. Тут я снова вспоминаю про IngvarJackal-а, который последние сутки в одиночку удерживает нас в районе 20-го места лидерборда.

Лидерборд в этом году формировался необычно: сутки, оставшиеся до конца соревнования, были разделены на несколько этапов. Очки за каждый этап суммировались и формировали итоговый рейтинг команды. Таким образом, нам нужно было уже сейчас зарабатывать баллы; выкатить решение в последний момент и попасть в середину рейтинга было бы практически невозможно. Поэтому я бросаю решать загадки galaxy.txt и присоединяюсь к IngvarJackal-у.

Игра на орбите происходит следующим образом: два корабля оказываются рядом с планетой. Один из них нападает, второй защищается. Игра длится 256 ходов (позже лимит подняли до 384-х). Задача атакующего — сбить защитника. Защитник, в свою очередь, просто пытается пережить нападение.

Сразу же после старта игры корабли начинают падать на планету, поэтому IngvarJackal первым делом научился поддерживать круговую орбиту. Это требовало постоянных затрат топлива, но, по крайней мере, давало нашему кораблю пожить хотя бы сотню ходов. Теперь IngvarJackal ставил эксперименты, пытаясь выяснить, как именно в этом мире устроена гравитация.

Я же взялся за пушки. Все корабли оборудованы лазерами, которые мгновенно поражают цели на любом расстоянии. Нужно заметить, что организаторы описали команду для выстрелов, но не объяснили, как именно выстрелы действуют на противника. По всей видимости, узнать это можно было только из туториалов, до которых мы всё никак не могли добраться.

Команда выстрела требует трёх параметров: идентификатора стреляющего корабля, координат цели, и ещё какого-то неизвестного параметра. В визуализаторе, предоставленном организаторами, было видно, что после координат идут три числа, а не один параметр.

Я принялся за эксперименты, и чего только не попробовал:

Всё эти эксперименты закончились одинаково — ошибкой.

У остальных членов команды дела тоже шли с переменным успехом:

Спустя почти шесть часов возни с командой выстрела мы с IngvarJackal наконец решили проверить алгоритм модуляции — и обнаружили, что команды кодируются неправильно! Мы должны передавать список команд, где каждая команда кодируется отдельным списком, но получается какая-то ерунда:

-- так должно быть
[4, 14, [[0, 1, [-1, 0]], [2, 1, [-16, -48], 4]]]
-- так кодируем
[4, 14, [[0, 1, [-1, 0]],  2, 1, [-16, -48], 4] ]

То есть второй элемент списка не добавляется в него, а конкатенируется с ним. При этом демодуляция неправильной кодировки возвращает правильный, исходный список! IngvarJackal писал демодулятор, но ничего не может подсказать по модулятору. portnov, писавший модулятор, делал это по коду mr146. В общем, бардак. portnov уходит спать, а я закатываю рукава и погружаюсь в науку о преобразовании «космолиспа» в нолики и единички…

Какой баг я найду? Успеем ли мы хоть чего-то достичь за последние 16 с лишним часов? Читайте в отчёте о последнем дне соревнования ;)

Drop me a line! (wonder where’s the comments form?)