Давайте устроим танковую войну!
Частично вдохновлен Destroy Them With Lazers
Задача
Ваша задача - управлять танком. Передвигайтесь и стреляйте в другие танки и препятствия на поле битвы 2D. Последний стоящий танк станет победителем!
Формат карты
Ваш танк будет находиться на поле 2D , основанное на n
по n
сетке единичных квадратов. Я буду решать, что n
основано на количестве представлений. Каждый квадрат может содержать только одно из:
- Бак
- Дерево
- Скала
- Стена
- Ничего
Все препятствия и танки полностью заполняют свои пространства, и они блокируют все выстрелы, которые бьют по ним, от повреждения вещей дальше вниз.
Вот пример поля с #
= tank; T
= дерево; R
= рок; W
= стенки; .
= ничего сn
= 10
.....#....
..T....R..
WWW...WWWW
W......T..
T...R...Ww
W...W.....
W....W...T
WWWWWW...R
W.........
WWWWWWRT..
Координаты в формате x, y
гдеx
увеличивается слева направо и y
увеличивается снизу вверх. Нижнее левое пространство имеет координату 0, 0
. Каждый танк может двигаться в любое пустое пространство и стрелять в любом направлении.
Динамика карт
Ваш танк не просто должен стрелять в другие танки! Если что-то снимает на карте, вещи могут случиться.
- Если в стену стреляют, она будет разрушена после некоторого количества выстрелов, в диапазоне от 1 до 4
- Если в дерево выстрелить, оно будет немедленно уничтожено
- Если выстрелить в скалу, выстрел пройдет над ней и повредит следующую вещь, в которую он попадет
Как только что-то уничтожено, его больше нет на карте (оно будет заменено ничем). Если выстрел уничтожает препятствие, он будет заблокирован и не повредит ничему дальше на своем пути.
Танковая динамика
Каждый танк начинается с life
= 100. Каждый выстрел в танк будет уменьшаться на 20-30 в life
зависимости от расстояния. Это можно рассчитать с помощью delta_life=-30+(shot_distance*10/diagonal_map_length)
(где diagonal_map_length
есть (n-1)*sqrt(2)
). Дополнительно каждый танк регенерирует 1life
за ход.
Повороты
Будет проведено некоторое количество раундов (я решу, как только у меня будет представление). В начале каждого раунда карта будет генерироваться случайным образом, и танки будут размещаться на ней в случайных пустых местах. В течение каждого раунда каждому танку предоставляется ход в любом произвольном порядке. После того, как каждый танк получил ход, им снова будут даны ходы в том же порядке. Раунд продолжается, пока не останется только один танк. Этот танк станет победителем, и они получат 1 очко. Затем игра перейдет к следующему раунду.
После того, как все раунды пройдены, я опубликую результаты по этому вопросу.
Во время хода танка он может выполнить одно из следующих действий:
- Перемещение до 3 мест в одном направлении, по горизонтали или вертикали. Если танк заблокирован препятствием или другим танком, он будет перемещен как можно дальше, не проходя через препятствие или танк.
- Снимайте в некотором направлении, представленном углом с плавающей точкой в градусах. Ось x локального пространства вашего танка (горизонтально слева направо, или восток или
TurnAction.Direction.EAST
) равна 0 градусов, а углы увеличиваются против часовой стрелки. Снимки неточные, и фактический угол выстрела может быть на 5 градусов больше или меньше выбранного вами угла. - Ничего не делать.
Повороты не ограничены во времени, но это не значит, что вы можете намеренно тратить время, чтобы повесить трубку.
Материалы / протокол
Каждая представленная программа будет контролировать один танк на поле. Управляющая программа на Java, поэтому ваши программы должны быть на Java на данный момент (возможно, я когда-нибудь напишу оболочку для других языков, или вы могли бы написать свой).
Ваши программы будут реализовывать Tank
интерфейс, который имеет следующие методы:
public interface Tank {
// Called when the tank is placed on the battlefield.
public void onSpawn(Battlefield field, MapPoint position);
// Called to get an action for the tank on each turn.
public TurnAction onTurn(Battlefield field, MapPoint position, float health);
// Called with feedback after a turn is executed.
// newPosition and hit will be populated if applicable.
public void turnFeedback(MapPoint newPosition, FieldObjectType hit);
// Called when the tank is destroyed, either by another tank,
// or because the tank won. The won parameter indicates this.
public void onDestroyed(Battlefield field, boolean won);
// Return a unique name for your tank here.
public String getName();
}
Battlefield
Класс содержит 2D массива объектов ( Battlefield.FIELD_SIZE
по Battlefield.FIELD_SIZE
) , который представляет вещи на поле боя. Battlefield.getObjectTypeAt(...)
будет дать FieldObjectType
для объекта по указанным координатам (один из FieldObjectType.ROCK
, FieldObjectType.TREE
, FieldObjectType.TANK
, FieldObjectType.WALL
, или FieldObjectType.NOTHING
). Если вы попытаетесь вывести объект из зоны действия карты (координаты <0 или> = Battlefield.FIELD_SIZE
), тогда IllegalArgumentException
будет выброшено.
MapPoint
класс для указания точек на карте. Используйте MapPoint.getX()
и MapPoint.getY()
для доступа к координатам.
EDIT: Некоторые методы утилиты были добавлены: MapPoint.distanceTo(MapPoint)
, MapPoint.angleBetween(MapPoint)
, Battlefield.find(FieldObjectType)
, и TurnAction.createShootActionRadians(double)
как это было предложено Wasmoo .
Более подробную информацию можно найти в javadocs, см. Раздел ниже.
Все классы (публичный API) находятся под пакетом zove.ppcg.tankwar
.
Программа управления
Полный исходный код и javadocs управляющей программы и танка API можно найти в моем репозитории GitHub: https://github.com/Hungary-Dude/TankWarControl
Не стесняйтесь отправлять запросы и / или комментарии, если вы видите ошибку или хотите улучшить.
Я написал две программы-образца танков RandomMoveTank
и RandomShootTank
(название говорит само за себя).
Чтобы запустить свой танк, добавьте свой полностью определенный (имя пакета + имя класса) класс танка в tanks.list
(один класс на линию), отредактируйте настройки по мере необходимости в zove.ppcg.tankwar.Control
(задержка включения, показывать или нет графическое представление поля и т. Д.), и бегиzove.ppcg.tankwar.Control
. Убедитесь, что в списке есть как минимум 2 танка, или результаты не определены. (При необходимости используйте емкости для образцов).
Ваши программы будут запускаться на моей машине под этой управляющей программой. Я добавлю ссылку на источник, как только напишу его. Не стесняйтесь предлагать правки для источника.
правила
- Ваши материалы должны соответствовать приведенным выше правилам.
- Ваши программы могут не иметь доступа к файловой системе, сети или пытаться каким-либо образом атаковать мою машину
- Ваши программы могут не пытаться использовать мою контрольную программу для обмана
- Нет троллинга (например, намеренно заставляя вашу программу тратить время, чтобы все повесить)
- Вы можете иметь более одного представления
- Попробуйте быть креативным с представлениями!
- Я оставляю за собой право разрешать или не разрешать программы произвольно
Удачи!
ОБНОВЛЕНИЕ: После исправления ошибки телепортации на стену и осуществления регенерации, я выполнил текущие представления для 100 раундов сBattlefield.FIELD_SIZE = 30
ОБНОВЛЕНИЕ 2: я добавил новое представление, RunTank, после того, как дурачился с Groovy ...
Обновленные результаты:
+-----------------+----+
| RandomMoveTank | 0 |
| RandomShootTank | 0 |
| Bouncing Tank | 4 |
| Richard-A Tank | 9 |
| Shoot Closest | 19 |
| HunterKiller 2 | 22 |
| RunTank | 23 |
| Dodge Tank | 24 |
+-----------------+----+
В настоящее время танки восстанавливают 1 жизнь за ход. Это должно быть увеличено?
источник
MapPoint
«Sx
иy
floats
? Не должны ли они бытьints
?Ответы:
Охотник убийца
Этот умный охотник попытается найти безопасную позицию, где он может метко стрелять ровно в одну цель. (И, таким образом, только одна цель может стрелять в нее)
Лучше всего работает, когда есть много укрытия.
Вот и все. Я провел
источник
Этот прямой танк находит ближайший вражеский танк и стреляет в него. Было бы неплохо, если бы
find
,distance
иangle
были встроены, и если быcreateShootAction
принят двойной в радианах (то есть результатangle
)Изменить: класс переписан, чтобы включить новые служебные методы
источник
Would be nice if find, distance, and angle were built in, and if createShootAction accepted a double in radians (i.e. the result of angle)
- Отличная идея, я добавлю это.Я не очень хорош в этом, но я подумал, что все равно попробую, ну знаешь, потренируйся и все такое.
Мой танк случайным образом решит двигаться или стрелять. Когда он решает стрелять, он пытается выстрелить по ближайшей доступной цели.
Полный код, включая управляющую программу, можно найти здесь .
источник
Direction.getRandom()
Dodge Tank
Этот танк будет стрелять в ближайший танк. Время от времени, в зависимости от состояния здоровья и времени последнего перемещения, он будет пытаться двигаться перпендикулярно ближайшему резервуару, пытаясь уклониться от лазеров.
источник
Это было намного сложнее, чем я думал ..
Это моя запись в groovy, вам нужно установить groovy и скомпилировать ее
Чтобы вызвать его, вам нужно добавить $ GROOVY_HOME / Groovy / Groovy-2.3.4 / lib / groovy-2.3.4.jar (или любую другую версию) в путь к классам.
Я мог бы отправить вам скомпилированный файл .class и библиотеку, если вы не хотите его устанавливать.
Кажется, есть ситуация, когда танки не видят этого, я не знаю, предназначено ли это. Это вызвало тупики при тестировании.
В любом случае вот RunTank: смелый RunTank продвигается в противоположном направлении от ближайшего резервуара, если это ближайший резервуар к ближайшему резервуару или если в пределах FIELD_SIZE / 3 находится более одного резервуара. Надеюсь, это имеет смысл, я пьян :)
У меня есть одно предложение: добавить цвета в аквариум и метод для его реализации. Также метки были бы хороши в GUI :)
источник
def RandomMoveTank() {}
- это должно быть там? (Я не знаю, отличный)Это вариант Shoot-Closest, в котором каждый второй ход он движется в направлении, пока не перестанет. Стреляет каждый второй ход.
У него есть удобная утилита,
path
которую можно использовать для идентификации всех точек (и, следовательно, объектов) между двумя точками.источник