Руководство по разработке бота

От первого локального боя до загрузки версии на турнир. Условия участия и подсчёт результатов находятся в правилах.

С чего начать

  1. Скачайте комплект для Windows x64 или для Linux x64. Внутри движок, Python SDK и пример бота.
  2. Создайте виртуальное окружение Python 3.11 и установите зависимости из requirements.txt, если используете NumPy.
  3. Запустите пример против образца, затем измените MyBot.py и повторите бой.
  4. Откройте созданный реплей на сайте, проверьте решения бота по ходам.
  5. Соберите отдельный ZIP со своим ботом и загрузите его в профиль участника.

Архив для разработки с движком и архив для загрузки на сайт — разные файлы. В профиль загружается только код бота и его данные.

Что происходит в игре

В бою участвуют два или четыре игрока. У каждого в начале три корабля. Каждый ход бот получает карту с положениями кораблей и планет, выбирает команды для своих кораблей и отправляет их движку. Размеры турнирных карт — от 240 × 160 до 384 × 256; число планет и их расположение зависят от карты и seed.

  • Движение. Команда thrust задаёт скорость от 0 до 7 и угол в градусах. Корабль имеет радиус 0,5 и прочность 255. Столкновения опасны; метод navigate строит только один следующий ход, поэтому его вызывают заново каждый ход.
  • Планеты. К нейтральной или своей планете можно пристыковаться, если есть место и корабль находится достаточно близко. Стыковка занимает 5 ходов. Пристыкованные корабли производят новые корабли; у каждой планеты ограничено число стыковочных мест.
  • Бой. Оружие срабатывает автоматически по противнику в радиусе 5 и наносит 64 единицы урона. Для стрельбы отдельная команда не нужна.

Итоги и ограничение ходов описаны в правилах турнира. Числа выше взяты из закреплённого движка и его Python SDK; при изменении версии движка руководство потребуется сверить заново.

Структура Python-бота и SDK

Точка входа — MyBot.py. Объект hlt.Game подключает бота к движку; game.update_map() возвращает новое состояние перед каждым ходом. Через game_map.get_me().all_ships() доступны свои корабли, через game_map.all_planets() — планеты. У планеты есть is_owned() и is_full(); у корабля — can_dock(), dock(), undock(), thrust() и navigate().

Минимальный пример выбирает первую свободную нейтральную планету. Он показывает обмен с движком, но не претендует на сильную стратегию:

import hlt

game = hlt.Game("MyBot")
while True:
    game_map = game.update_map()
    commands = []
    targets = [p for p in game_map.all_planets()
               if not p.is_owned() and not p.is_full()]
    for ship in game_map.get_me().all_ships():
        if ship.docking_status != ship.DockingStatus.UNDOCKED or not targets:
            continue
        planet = targets[0]
        if ship.can_dock(planet):
            commands.append(ship.dock(planet))
        else:
            move = ship.navigate(ship.closest_point_to(planet), game_map,
                                 speed=hlt.constants.MAX_SPEED)
            if move:
                commands.append(move)
    game.send_command_queue(commands)

Несколько кораблей, направленных к одной планете, могут мешать друг другу или одновременно претендовать на последнее место. Улучшение выбора целей и предотвращение столкновений — уже задачи вашей стратегии.

Как бот общается с движком

Движок запускает каждый бот как отдельный процесс и обменивается с ним строками через стандартные потоки. При старте SDK читает номер игрока, размеры и первую карту, затем отправляет имя бота. На каждом следующем ходу update_map() читает очередную карту, а send_command_queue() отправляет команды и завершает строку.

SDK формирует команды движения t, стыковки d и отстыковки u. Обычно вручную разбирать строки не нужно: используйте объекты SDK. Не вызывайте print() для отладки: стандартный вывод занят игровым протоколом. Для сообщений используйте logging.

Локальный бой без Docker

Распакуйте комплект в папку с доступом на запись. На Windows и Linux нужен Python 3.11 x64. На macOS готовый комплект пока не проверен. В терминале, открытом в папке комплекта, выполните:

Windows:
py -3.11 -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt
.venv\Scripts\python.exe run_local.py MyBot.py

Linux:
python3.11 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python run_local.py MyBot.py

В requirements.txt закреплена NumPy 2.4.6 — единственный гарантированный сторонний пакет общей среды ботов. Если бот её не использует, установка для локального боя необязательна. Недостающие места в бою занимают образцовые боты. Для боя на четверых добавьте --players 4; можно передать два или четыре пути к ботам.

По умолчанию seed случаен, а движок выбирает размер карты. --size 288x192 фиксирует размер, --seed 1842 позволяет повторить расположение планет. Доступны размеры 240×160, 264×176, 288×192, 312×208, 336×224, 360×240 и 384×256; допустимый seed — от 1 до 4294967295. Скрипт выводит использованный seed и сохраняет файлы в отдельной папке runs/match-….

Как искать ошибки

  1. Сначала запустите бота против образца на одной карте с фиксированным seed. Повторяемый бой помогает понять, какая правка изменила поведение.
  2. Проверьте engine_stderr.txt и engine_stdout.json в папке боя. Если движок создал журнал ошибки бота, он лежит рядом с ними.
  3. Пишите диагностические сообщения через logging. Не выводите их через print(): лишняя строка может нарушить протокол.
  4. Откройте реплей и найдите ход, где корабль столкнулся, не пристыковался или выбрал неверную цель. Затем попробуйте другой seed и размер карты.

navigate() может вернуть None, если не нашёл путь за допустимое число поправок. Перед добавлением команды в очередь проверяйте результат.

Загрузка версии в турнир

Загрузите ZIP, в корне которого находится MyBot.py. Собственные модули и небольшие файлы данных допустимы. Не добавляйте папку hlt/ или файлы hlt.* в корень: турнир предоставляет проверенный SDK, а архив с попыткой его подмены отклоняется. Движок и локальный комплект в ZIP бота не входят.

Лимиты приёма: архив до 10 МБ, не более 200 записей и 100 файлов; один файл до 5 МБ, суммарный распакованный объём до 20 МБ. Сервис сначала проверяет архив и проводит пробный бой против образца. Ошибка бота отклоняет версию; обычное поражение не отклоняет. После успешной проверки версия становится активной. В профиле можно хранить до трёх проверенных версий и переключаться между ними.

Скачать образец ZIP для загрузки.

Реплеи и анализ боя

На странице завершённого турнирного боя доступны воспроизведение, показатели и скачивание .hlt. Локальный реплей можно открыть в браузере выбором файла или перетаскиванием; он не отправляется на сервер. Ограничение размера локального файла — 25 МБ.

Остановите воспроизведение на спорном ходе и сравните количество кораблей, занятых планет и положение флотов. Для воспроизведения исходной карты используйте seed и размер из сведений о бое.