Давайте будемо танковій війні!
Частково натхненний Destroy Them With Lazers
Об'єктивна
Ваше завдання - контролювати танк. Рухайтеся навколо та стріляйте в інші танки та перешкоди на 2D полі бою. Останній танк стане переможцем!
Формат карти
Ваш танк буде знаходитися на полі 2D , засноване на nпо nсітці одиничних квадратів. Я вирішу, що nґрунтується на кількості подань. Кожен квадрат може містити лише один із:
- Танк
- Дерево
- Скеля
- Стіна
- Нічого
Всі перешкоди та танки повністю заповнюють їхні простори, і вони блокують усі постріли, які в них потрапляють, не пошкоджуючи речі далі.
Ось приклад поля з #= резервуаром; 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)). Крім того, кожен бак відновлює 1 lifeза оборот.
Повороти
Буде проведено деяку кількість раундів (я вирішу, як тільки я матиму подання). На початку кожного раунду карта буде генерована випадковим чином, а резервуари будуть розміщені на ній у випадкових порожніх місцях. Під час кожного раунду кожному танку буде надано поворот у будь-якому довільному порядку. Після того, як кожен танк отримав поворот, вони будуть надані повороти знову в тому ж порядку. Раунд триває, поки не залишиться лише один танк. Цей танк буде переможцем, і вони отримають 1 бал. Потім гра перейде до наступного раунду.
Після проходження всіх раундів я опублікую бали за цим питанням.
Під час повороту танка це може зробити одне з наступних
- Перемістіть до 3 пробілів в одному напрямку - горизонтально або вертикально. Якщо танк заблокований перешкодою чи іншим резервуаром, він буде переміщений наскільки це можливо, не проходячи через перешкоду чи танк.
- Стріляйте в деякому напрямку, представленому кутом з плаваючою точкою в градусах. Вісь x локального простору вашого танка (горизонтально зліва направо, також на схід або
TurnAction.Direction.EAST) дорівнює 0deg, а кути збільшуються проти годинникової стрілки. Постріли неточні, а фактичний кут пострілу може бути на 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іyfloats? Чи не повинні вони бутиints?