Правила
В качестве задания предлагается разработать бота для игры Bomberman, в которой необходимо расчистить игровое поле от кирпичных стен с помощью бомб. Ваша цель - набрать больше очков, чем ваши соперники. Игра заканчивается, когда достигнуто максимальное количество тиков.
Игровое поле представляет из себя квадрат 450x450, окруженный неразрушаемыми препятствиями. В игре одновременно участвует 4 игрока, каждый начинает в своём углу. Время в игре дискретно и делиться на тики. Каждая игра состоит из 1500 тиков. В игровом поле расположены препятствия двух типов: кирпичные(разрушаемые) и бетонные(неразрушаемые). Разрушать препятствия можно с помощью бомб. Каждая бомба взрывается через 50 тиков после размещения и взрывает ближайшие препятствия на расстоянии, ограниченном мощностью бомбы. Изначально каждый игрок может иметь максимум 1 бомбу в один момент времени, и каждая бомба имеет мощность 1. Количество бомб и их мощность увеличивается с помощью бонусов, которые выпадают при разрушении блоков.
Изначально у игрока есть 3 жизни. Если взрыв бомбы захватывает персонажа, то тот становится неактивным в течение 30 тиков и неуязвимым в течение следующих 30 тиков, а также теряет 1 жизнь. Если у него жизни заканчиваются, то он перестаёт совершать действия до конца игры.
Начисление очков
Игрокам начисляются очки за следующие события:
- Разрушение стены — 12 очков
- Подрыв персонажа соперника — 240 очков
- Подрыв своего персонажа — -60 очков
- Поднятие бонуса — 6 очков
Если какое-то событие произошло из-за действий k пользователей одновременно, то каждый игрок получит 1/k-тую от указанных очков.
Управление
В начале каждого тика вызывается метод getAction вашего класса для того, чтобы получить действие вашей стратегии на следующий тик. В качестве аргументов в него передаются два параметра: Player и World. Первый параметр содержит информация о персонаже, которым управляет игрок: его координаты, количество бомб, их мощность и т.д. Второй параметр содержит описание текущего состояния игрового мира.
Для того, чтобы совершить движение, необходимо установить поля speedX и speedY. Они зададут, на сколько единиц изменятся координаты к следующему тику. В случае, если скорость превышает ограничение World.PLAYER_MAX_SPEED = 10 единиц за тик, она будет уменьшена так, чтобы это ограничение выполнялось. Если во время движения на пути персонажа встретится препятствие, то движение будет остановлено. Бомбы, которых касался персонаж в момент их размещения, препятствиями не считаются, пока персонаж не перестанет с ними соприкасаться. По всем остальным бомбам перемещаться нельзя
Для размещения бомбы необходимо в поле drop установить значение true. Бомба будет размещена в конце текущего тика в позиции с координатами (15+30i, 15+30j), где i и j - целые числа, ближайшей к координатам игрока. Новые бомбы считаются препятствием только со следующего тика.
Игровой мир
Игровой мир состоит из персонажей, препятствий, бомб, взрывов и бонусов. Их списки можно получить, выполнив методы getPlayers(), getObstacles(), getBombs(), getExplosions(), getBonuses() у объекта world.
Все объекты игрового мира имеют тип type, координат центра (x,y) и размеры size. Для круглых объектов size является диаметром, а для квадратных — длиной стороны.
Персонаж
Игровой персонаж описывается классом Player. Каждый персонаж в игровом мире — окружность с диаметром 20. Класс состоит из следующих полей:
- playerId — уникальный номер игрока. Сохраняется во всех бомбах и взрывах, которые принадлежат игроку;
- livesLeft — количество жизней у игрока;
- score — количество очков, которые набрал игрок;
- stunDuration — количество тиков, которые игрок оглушен;
- immuneDuration — количество тиков, которые игрок неуязвим;
- bombsPower — мощность бомб игрока;
- bombsCount — максимальное количество бомб, которые игрок может разместить на поле;
- bombsLeft — количество бомб, которые ещё может разместить игрок сейчас;
Препятствие
Препятствия в игре представлены в виде объектов типа Obstacle. Препятствия бывают разрушаемыми (BrickWall) и неразрушаемыми (ConcreteWall). Геометрически они представляют собой квадраты со сторонами, параллельными осям координат, с длиной 30. Содержимое препятствия храниться в поле contents. Препятствие может быть или пустым, или иметь содержать какой-то бонус. Игровое поле со всех сторон окружено неразрушимыми стенами.
Бомба
Бомбы представляют из себя окружности с диаметром 28. Проходить по бомбам можно только в случае, если при размещении игрок касался её и только пока он с неё не сошел. Сила бомбы определяется в момент взрыва как bombsPower игрока, разместившего её. Когда происходит взрыв, бомба удаляется с поля, а вместо неё размещаются объекты в четырёх направлениях от центра. Взрывы распространяются до тех пор, пока их не будет размещено количество, равное мощности бомбы, или пока они не пересекуться со стеной.
Размещать несколько бомб в одних и тех же координатах нельзя. Если несколько игроков размещают бомбы одновременно в одних и тех же координатах, будет размещена бомба первого игрока в порядке хода на текущий тик. Порядок хода определяется случайным образом в начале каждого тика.
Класс Bomb состоит из следующих полей:
- timeout — количество тиков до взрыва, уменьшается на 1 в начале каждого тика и при достижении 0 бомба взрывается;
- owner — игрок, разместивший бомбу;
- walkableFor — список тех, кто сейчас может перемещаться по бомбе;
Взрыв
Взрывы описываются классом Explosion.Взрыв представляет из себя квадраты со стороной 28. Класс состоит из двух следующих полей:
- timeout — количество тиков до исчезновения, уменьшается на 1 в начале каждого тика и при достижении 0 исчезает;
- creators — набор игроков, из-за взрыва которых появился этот взрыв;
Взрывы обрабатываются следующим образом: в начале каждого тика проверяется, какие объекты касаются взрывов:
- Если игрок, и он не является неуязвимым, то он считается подорванным.
- Если бомба, то она взрывается.
- Если разрушаемое препятствие, то оно удаляется из игры.
- Если бонус, и его неуязвимость истекла, то он удаляется из игры
Бонус
Бонусы представляют из себя квадратом с размером 28. Для их описания используется класс Bonus. В первые 11 тиков бонусы невозможно разрышить взрывами. Бонусы бывают 2 типов: увеличиивающими мощность (BonusPower) и количество бомб(BonusBomb) у поднявшего их игрока. Бонусы поднимаются автоматически в начале каждого тика, когда игрок соприкасается с ними. Если несколько игроков одновременно поднимают бонус, то он достанется тому, кто начнёт ходить первым на текущий тик. Порядок хода определяется случайным образом в начале каждого тика. Класс состоит из двух следующих полей:
- bonusType — тип бонуса;
- immuneDuration — количество тиков, которое этот бонус нельзя подорвать.
Класс с правилами
Для получения доступа к игровым постоянным используется класс Rules. Текущие правила можно получить в классе MyStrategy с помощью вызова getRules(). В этом классе описаны количество игроков, размеры игрового поля и объектов, количество жизней, количество очков, которые получает игрок и т.д.
Отправка стратегии
Для того, чтобы прислать стратегию, необходимо отправить в систему файл с классом MyStrategy, который реализует вашу стратегию, или ZIP-архив содержимого папки src, в котором находятся все классы, входящие в вашу стратегию. При отправке ZIP-архива, не обязательно присылать файлы из папок model и utils, потому что они будут автоматически заменены на стандартные.
Присланная стратегия должна удовлетворять следующим ограничениям:
- Размер присланного файла не превышает 5 Mb
- Размер исходного кода не превышает 20 Mb
Во время выполнения к программе выдвигаются следующие требования:
- Время работы обработки каждого тика не превосходит 2 секунды
- Суммарное время работы не превосходит 2 минуты
- Приложение занимает не больше 256 Mb памяти
При нарушении этих условий стратегия будет считаться упавшей и будет остановлена.