Bomberman Codenjoy — как играть?

Игровой demo-сервер доступен так же в интернете 24/7 в целях ознакомления http://codenjoy.com/codenjoy-contest

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

По возникающим вопросам, пиши в skype:alexander.baglay или на почту apofig@gmail.com

В чем суть игры?

Надо написать своего бота для героя, который обыграет других ботов по очкам. Все играют на одном поле. Герой может передвигаться по свободным ячейкам во все четыре стороны.

Герой может также поставить бомбу. Бомба взорвется через 5 тиков (секунд). Взрывной волной бомбы можно зацепить обитателей поля. Все, кто был задет - исчезает. Подорваться можно и на своей, и на чужой бомбе.

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

Каждый разрушенный объект на поле (бомбермен, митчопер, разрушаемые стенки) тут же восстанавливается в другом месте. Если пострадал бомбермен, ему зачисляются штрафные очки -50*.

Бомбермен, от бомбы которого произошли разрушения на карте получит бонусные очки: за разрушаемую стенку +10*, за митчопера +100*, за другого бомбермена +1000*.

*Tочную сумму очков уточни у ведущего.

Очки суммируются. Побеждает игрок с большим числом очков (до условленного времени).

Итак, игрок регистрируется на сервере, указывая свой email

Далее необходимо подключиться из кода к серверу через вебсокеты. Это Maven проект и подойдет он для игры на JVM языках. Так же в архиве ты найдешь и сырцы для других языков. Как его запустить смотри в корне проекта в файле README.txt

Если ты не можешь найти свой язык - придется написать свой клиент (а после пошарить с нами на почту: apofig@gmail.com)

Адрес для подключения к игре на сервере http://codenjoy.com:

ws://codenjoy.com:80/codenjoy-contest/ws?user=3edq63tw0bq4w4iem7nb&code=12345678901234567890

Адрес для подключения к игре на сервере, развернутом в локальной сети:

ws://server_ip:8080/codenjoy-contest/ws?user=3edq63tw0bq4w4iem7nb&code=12345678901234567890

Тут 'user' - id игрока, a 'code' - твой security token, его ты можешь получить из адресной строки браузера после регистрации/логина

После подключения клиент будет регулярно (каждую секунду) получать строку символов — с закодированным состоянием поля. Формат таков

^board=(.*)$

с помощью этого regexp можно выкусить строку доски. Вот пример строки от сервера:

board=☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼ #   # #  #♥#  #  #  &        #☼☼♥☼♥☼♥☼#☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼#☼#☼♥☼#☼#☼☼#♥♥  ♥#   # #♥   # ♥#          ☼☼ ☼ ☼#☼ ☼♥☼ ☼ ☼#☼ ☼ ☼ ☼ ☼&☼ ☼ ☼ ☼☼     ♥          # #            ☼☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼♥☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼☼#       # #       ☺& 2  #  #  #☼☼#☼♥☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼☼#  # ♥#               # ♥   #  ☼☼ ☼ ☼#☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼☼   #♥ #      #                 ☼☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼☼     ## #     #   # #   ♥      ☼☼ ☼ ☼♥☼ ☼ ☼#☼ ☼#☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼☼       #♥       #      ## # ###☼☼ ☼ ☼ ☼#☼ ☼ ☼#☼ ☼ ☼#☼#☼&☼ ☼ ☼ ☼ ☼☼       #       #    ♣# #     ♥ ☼☼ ☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼☼        ## ## ♥             # #☼☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼☼                   &    ###  ##☼☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼☼                   ♥ ##        ☼☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼♥☼#☼ ☼ ☼ ☼☼     ##         &#         #   ☼☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼☼   #   #         #     # &     ☼☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼#☼ ☼☼  #                    ##   &  ☼☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼#☼ ☼☼ #    # &        #       #     ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼

Длинна строки равна площади поля. Если вставить символ переноса строки каждые sqrt(length(string)) символов, то получится читабельное изображение поля.

☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
☼ #   # #  #♥#  #  #  &        #☼
☼♥☼♥☼♥☼#☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼#☼#☼♥☼#☼#☼
☼#♥♥  ♥#   # #♥   # ♥#          ☼
☼ ☼ ☼#☼ ☼♥☼ ☼ ☼#☼ ☼ ☼ ☼ ☼&☼ ☼ ☼ ☼
☼     ♥          # #            ☼
☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼♥☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼
☼#       # #       ☺& 2  #  #  #☼
☼#☼♥☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼
☼#  # ♥#               # ♥   #  ☼
☼ ☼ ☼#☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼
☼   #♥ #      #                 ☼
☼ ☼ ☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼
☼     ## #     #   # #   ♥      ☼
☼ ☼ ☼♥☼ ☼ ☼#☼ ☼#☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼
☼       #♥       #      ## # ###☼
☼ ☼ ☼ ☼#☼ ☼ ☼#☼ ☼ ☼#☼#☼&☼ ☼ ☼ ☼ ☼
☼       #       #    ♣# #     ♥ ☼
☼ ☼ ☼ ☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼
☼        ## ## ♥             # #☼
☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼
☼                   &    ###  ##☼
☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼
☼                   ♥ ##        ☼
☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼♥☼#☼ ☼ ☼ ☼
☼     ##         &#         #   ☼
☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼
☼   #   #         #     # &     ☼
☼♥☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼ ☼#☼#☼ ☼
☼  #                    ##   &  ☼
☼ ☼ ☼ ☼ ☼ ☼#☼ ☼ ☼ ☼ ☼ ☼ ☼#☼ ☼#☼ ☼
☼ #    # &        #       #     ☼
☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼

Первый символ строки соответствует ячейке расположенной в левом верхнем углу и имеет координату [0, 32]. В этом примере — позиция бомбермена (символ ☺) — [19, 25]. Левый нижний угол имеет координату [0, 0].

Расшифровка символов на рисунке ниже

public enum Element {

    /// This is your Bomberman
    BOMBERMAN('☺'),             // так выглядит мой бомбер
    BOMB_BOMBERMAN('☻'),        // так выглядит мой бомбер, если он сидит на бомбе
    DEAD_BOMBERMAN('Ѡ'),        // ойкс! твой бомбер умер. Не волнуйся, он появится
                                // через секунду где-нибудь на поле, но вполне
                                // вероятно за это ты получишь штрафные очки.

    /// this is other players Bombermans
    OTHER_BOMBERMAN('♥'),       // а так выглядит бомбер противника
    OTHER_BOMB_BOMBERMAN('♠'),  // так, если бомбер противника сидит на бомбе
    OTHER_DEAD_BOMBERMAN('♣'),  // так, если бомбер противника подорвался.
                                // если это ты его подорвал - ты получишь бонусные очки.

    /// the bombs
    BOMB_TIMER_5('5'),          // после того как бомбер поставит бомбу таймер вкючится (всего 5 тиков)
    BOMB_TIMER_4('4'),          // эта бомба взорвется через 4 тика
    BOMB_TIMER_3('3'),          // эта - через 3
    BOMB_TIMER_2('2'),          // два
    BOMB_TIMER_1('1'),          // один
    BOOM('҉'),                  // Бам! Это то, как бомба взрывается. При этом все, что может быть разрушено - разрушится

    /// walls
    WALL('☼'),                  // неразрушаемые стены - им взрывы бомб не страшны
    DESTROYABLE_WALL('#'),      // а эта стенка может быть разрушена
    DESTROYED_WALL('H'),        // это как разрушенная стенка выглядит, она пропадет в следующую секунду
                                // если это ты сделал - ты получишь бонусные очки

    /// meatchoppers
    MEAT_CHOPPER('&'),          // этот малый бегает по полю в произвольном порядке
                                // если он дотроентся до бомбера - тот умрет
                                // лучше бы тебе учничтожить этот кусок.... мяса, за это ты получишь бонусные очки
    DEAD_MEAT_CHOPPER('x'),     // это взровравшийся митчопер

    /// perks
    /// Значения, таймауты, вероятность выпадения перков могут быть изменены администратором игры.
    /// Указаны значения по умолчанию.
    /// Действие перка истекает по таймауту (10 тиков) если не указано иначе в описании перка.

    BOMB_BLAST_RADIUS_INCREASE('+'), // увеличивает радиус взрыва бомбы (радиус +2 к текущему).
                                     // Действует только для новых бомб.

    BOMB_COUNT_INCREASE('c'), // Увеличивает количество доступных игроку бомб (+3 к текущему уровню по-умолчанию).

    BOMB_IMMUNE('i'), // Дает иммунитет от взрыва бомб.
    BOMB_REMOTE_CONTROL('r'), // Дистанционный взрыватель. Срабатывает при повторном действии. 3 взрывателя по умолчанию.

    /// a void
    NONE(' ');                 // свободная ячейка, куда ты можешь направить бомбера

Игра пошаговая, каждую секунду сервер посылает твоему клиенту (боту) состояние обновленного поля на текущий момент и ожидает ответа команды герою. За следующую секунду игрок должен успеть дать команду герою. Если не успел — герой стоит на месте.

Команд несколько: UP, DOWN, LEFT, RIGHT – приводят к движению героя в заданном направлении на 1 клетку; ACT - оставить бомбу на месте героя. Команды движения можно комбинировать с командой ACT, разделяя их через запятую. Порядок (LEFT, ACT) или (ACT, LEFT) - имеет значение, либо двигаемся влево и там ставим бомбу, либо ставим бомбу а затем тикаем влево. Если игрок будет использовать только одну команду ACT, то бомба установится под героем без его перемещения на поле.

Первая задача – написать websocket клиента, который подключится к серверу. Затем заставить героя слушаться команды. Таким образом, игрок подготовится к основной игре. Основная цель – вести осмысленную игру и победить.

Сейчас реализованы клиенты для игры для некоторых языков программирования (Java, Javascript, Objective-C, C++, Python, C#) Другие языки в процессе написания (спасибо игрокам-активистам!).

Слишком много форы клиентский код не дает играющим, поскольку в этом коде еще надо разобраться, но там реализована логика общения с сервером + некоторое высокоуровневое API для работы с доской (что уже приятно)

Point getBomberman()                          // позиция моего бомбера на доске
Collection<Point> getOtherBombermans()        // позиции всех остальных бомберов (противников) на доске
boolean isMyBombermanDead()                   // жив ли мой бомбер
boolean isAt(Point point, Element element)    // находится ли в позиции point заданный элемент?
boolean isAt(Point point, Collection<Element> elements)   // находится ли в позиции point что-нибудь из заданного набора
boolean isNear(Point point, Element element)  // есть ли вокруг клеточки с координатой point заданный элемент
boolean isBarrierAt(Point point)              // есть ли препятствие в клеточке point
int countNear(Point point, Element element)   // сколько элементов заданного типа есть вокруг клетки с point
Element getAt(Point point)                    // возвращает элемент в текущей клетке
int boardSize()                               // возвращает размер доски
Collection<Point> getBarriers()               // координаты всех объектов препятствующих движению
Collection<Point> getMeatChoppers()           // координаты всех чудиков которые могут убить бомбера
Collection<Point> getWalls()                  // координаты всех бетонных стен
Collection<Point> getDestroyableWalls()       // координаты всех кирпичных стен (их можно разрушать)
Collection<Point> getBombs()                  // координаты всех бомб
Collection<Point> getFutureBlasts()           // координаты потенциально опасных мест, где бомба может разорваться. 
                                                  // (бомба взрывается на N {решим перед началом игры} клеточек 
                                                  // в стороны: вверх, вниз, вправо, влево)
Тут:
Point       // координата x, y
Collection  // набор нескольких объектов
Element     // тип элемента на доске