вторник, 8 января 2019 г.

PiTanks Online

Нам очень нравятся игры для программистов, такие как например Colobot и Ceebot. Писать код, загружать его в своего бота и запускать его для выполнения миссий - что может быть интереснее? Поддержка сетевого режима, когда другие игроки запускают своих прокачанных кодом ботов против твоего? Несомненно. Однако еще более интересным нам показалось самим разработать игру для программистов и поиграть в нее с друзьями.
Серверный игровой движок, многопоточность, асинхронный обмен данными, объекты и классы - все это мы приправим поддержкой дополненной реальности с использованием машинного зрения c OpenCV.


Приставка Pi в названии проекта "PiTanks Online" однозначно намекает на то, что в качестве серверной платформы мы использовали Raspberry Pi. Игровое поле в нашем проекте нарисовано от руки на листе бумаги.


На него смотрит веб-камера, установленная на подставке, собранной из LEGO Technic. В качестве рисованного поля может использоваться также маркерная доска.


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

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

Наши примеры ботов имеют следующие наборы "команд":
  • forward() - бот смещается на 1 единицу дистанции вперед (в сторону, в которую он в данный момент развернут)
  • backward() - бот смещается на 1 единицу дистанции назад
  • right() - бот поворачивается на месте на 1 градус вправо
  • left() - бот поворачивается на месте на 1 градус влево
  • radar(a) - запросить данные с радара по направлению a (угла в градусах 0..359 от текущего направления бота). Функция возвращает кортеж из символа, обозначающего объект, который обнаружил радар (t - живой бот противника, w - стена или мертвый бот противника, n - "ничего нет") и числа - расстояния до обнаруженного объекта (0 в случае объекта "ничего нет") 
  • fire() - бот производит выстрел, снаряд летит по направлению разворота бота
  • energy() - возвращает количество доступных очков действий. Очки действий тратятся на движение, стрельбу и работу радара. Пополняются каждую секунду. Введены, чтобы никто из игроков не мог получить приоритета в обработке его бота сервером. 
  • exit() - отключиться от сервера, выйти из боя
Каждая из функций forward, backward, left и right возвращает True или False давая понять боту, была ли отработана команда. Это может быть удобным, например для понимания не застрял ли бот при маневре, упершись в препятствие.

При желании можно не использовать готовые функции из примеров, а написать свои. Например, доработать функции поворота возможностью принимать параметр "угол поворота", а функции движения - параметр "дистанция". Логику управления ботом в целом можно накрутить довольно сложную. Вполне адекватно работают, например, ПИД-регуляторы по дальномерам ботов, можно использовать элементы SLAM для локализации на карте.

Написанный на Python бот может работать не только на ПК, подходит практически любое устройство с интерпретатором этого языка, например LEGO EV3, ESP8266 или смартфон:


Исходный код сервера и примеры ботов доступны по ссылке.


Самое популярное