Vesna-Soft AI Challenge User Manual

==========================================================

Привет!

Сегодня мы будем программировать ботов, задача которых — соревноваться друг с другом на игровом мире

Итак, вам предстоит научится управлять танком и выстроить вашу стратегию таким образом, чтобы превзойти соперника на поле боя.

Если бы вы управляли танком вручную, то у вас был бы джойстик с кнопками:

Мы дадим вашей программе “виртуальный” программистский джойстик, и она будет много раз в секунду виртуально нажимать на кнопки такого “джойстика” (просто формирование структуры данных), и его команды будут отсылаться на центральный сервер.

Сервер же будет просчитывать всю физику, двигать танки, и периодически высылать вам новое “состояние” мира - большой массив, содержащий координаты всех объектов на карте и много другой полезной информации.

Для быстрого старта вам нужно выбрать свой путь:

А чтобы вам немного упростить реализацию стратегии боя - мы вам предоставим функции, которые решают некоторые математические задачи, а в каких случаях их применять - уже придется решать вам самим.


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

Спецификация протокола

Есть 2 стороны: клиент (игроки) и сервер. Общение между клиентом и сервером: JSON в кодировке UTF-8 внутри WebSockets.

Хорошая новость: это все уже реализовано за вас и вам нужно будет всего лишь реализовать логику поведения бота. Подробно об этом написано в отдельных документах для Java и JavaScript , ссылки на которые вы можете найти выше.

Клиент может слать 2 вида сообщений:

Сервер шлет 1 вид сообщений:

Сообщение Map одинаковое для всех клиентов (дальше будет понятно почему) и шлется 10 раз в секунду.

Структура сообщений

Authorize (клиент -> сервер)

{"user": "John",                    // будет виден остальным игрокам
 "pass": "personal-password",       // выбирается игроком
 "mode": "player"}                  // опциональный параметр
                                    // если не указан, значение "player"
                                    // "player" - игрок (выдать ему танк)

Значения user и pass определются клиентом. Сервер запоминает пару user/pass и переходит к игровому раунду. При повторном подключении, сервер проверяет пару user/pass и, если пароль не совпадает, то отключает клиента (закрывает WebSocket).

Input (клиент -> сервер)

Представьте, что это команды от геймпада, которым мог бы управлять человек.

{"move-xy":     [1.0, -1.0],// куда двигаться. [0,0] - стоять
 "gun-xy":      [1.0,  0.5],// куда смотрит пушка
 "fire":        true}       // true -- сделать выстрел (в следующем тике)

Map (сервер -> клиенты)

["tick":    3,                  // тик игры, увеличивается на 1 с каждым
 "size":    [800, 400],         // ширина и высота в метрах
 "objects": [                   // ... обновлением (10 раз в секунду)
   {"id":          "dffdf",       // уникальный идентификатор объекта
    "type"        "player",     // всегда "player"
    "user":         "John",
    "сreated":       1,         // тик создания объекта
    "xy":    [100.0, 200.0]     // где находится игрок
    "health-max":      800,     // начальное значение брони
    "health":          800,     // текущее значение брони
    "move-xy" : [1.0, 0.0],     // куда едет танк
    "move-speed-max": 50.0,     // максимальная скорость танка
    "move-speed":     50.0,     // текущая скорость, для простоты: 0 или 50
    "gun-xy":   [0.5, 0.5],     // куда смотрит пушка
    "gun-damage":      100,
    "gun-reload-max":    5,     // время перезарядки в тиках
    "gun-reload":        0,     // перезарядка: 0 - готов стрелять 5 - только что выстрелил (в этом же тике),
                                //... уменьшается на 1 каждый тик (до 0)
    "body-radius":    20.0,     // радиус танка (круглый как тарелка)
   }, {
    "type":       "player",     // следующий игрок
    "user":         "Kate",
    ...
   }, {
    "id":              1,       // уникальный идентификатор обьекта
    "type":        "shell",     // снаряд
    "user":         "John",     // кто выпустил снаряд
    "сreated":       1,         // тик создания объекта
    "xy":   [100.0, 150.0],     // где находится
    "move-xy": [0.3, 0.75],     // куда летит
    "move-speed":   2000.0,     // как быстро
    "damage":          100,      // сколько урона причинит при коллизии
    "body-radius":       1,     // радиус снаряда
   }, {
     "id":               1,     // уникальный идентификатор объекта
     "type":       'bonus',     // бонус
     "bonus":       'heal',     // тип бонуса: 'heal' - восстанавливает броню,
                                // 'damage-boost' - увеличивает урон
     "xy":  [120.0, 180.0],     // где находится
     "body-radius":     20,     // радиус бонуса
     "created":         175     // тик, на котором был создан бонус
   }
]]

Примечание: сервер всегда шлёт клиентам векторы (x,y) единичной длины. Клиент может слать неединичные векторы - сервер приводит их к единичным/нормализированным (т.е. векторы длинной 1).

Организация процесса проведения хакатона

Начало хакатона

Раунды