Голодні ігри - їжте чи вмирайте
Якщо ви не їсте, ви помрете. Якщо ви їсте, ви живете (поки не помрете). Ви будете помирати, так що постарайтеся , щоб померти в минулому.
Огляд
Тут є острів, заселений стадом здобичних тварин. Ви керуєте зграєю з п'яти хижаків. Ваша мета - зберегти ваш пакет живим. Зробіть це, поїдаючи здобич. Здобич, як правило, перебігає від хижаків і намагається в іншому випадку триматися в зграї. Звичайно, ваш пакунок буде на тому ж полі, що і кожен інший пакет , тому змагання намагатимуться їх з'їсти, перш ніж зможете. Не дозволяйте цьому вас відштовхувати, інакше ви будете голодувати.
Як грати
Створіть та подайте програму командного рядка, щоб направити ваш пакет. Він буде отримувати інформацію про стан від програми управління на STDIN та виводити команди STDOUT. Формат детально викладений нижче. Кожна програма буде виконана лише один раз, і вона повинна працювати, доки в ній не буде більше членів пакету. Вам потрібно буде прочитати дані, як вони надходять, і швидко відповісти. Існує суворий час очікування в 200 мс для кожної відповіді. Якщо ви до цього часу не відповіли, ваш пакет не отримає нових інструкцій для поточної черги.
Якщо ваша програма не може бути запущена контролером, вона не вважатиметься дійсною. Будь ласка, включіть рядок командного рядка, який мені потрібно буде використовувати для запуску вашої роботи. Якщо є якісь спеціальні інструкції (до налаштування компіляторів тощо), будь ласка, включіть їх. Якщо я не можу працювати, я попрошу вас про допомогу в коментарях. Якщо ви не відповісте, я не зможу прийняти ваше подання.
Турнір відбудеться в 64-бітній системі Linux. Майте це на увазі, даючи будь-які необхідні вказівки.
Деталі
Положення та напрямок кожної істоти мають форму пари з двома точними числами з плаваючою точкою (наприклад
double
), що представляють їхx
таy
координати відповідно.Кожна істота вважається пунктом. Це означає, що вони можуть перекриватися і займати однаковий простір. Вас не відштовхнуть, і немає поняття зіткнення з іншими істотами.
Острів - площа, 500 одиниць в бік. Якщо ви спробуєте здійснити за межі цих меж, ви будете затиснуті на край. Походження
{0,0}
знаходиться вгорі зліва, зіx
збільшенням праворуч іy
збільшенням вниз. Знову-таки карта не загортається .Гра починається з 1500 здобич (packCount * 50) здобич тварин. Вони зберуться в центрі острова, але швидко вирішать почати рух.
Пачки будуть розташовані по рівномірно розташованому колу по периметру. Порядок упаковки перетасовується, тому не розраховуйте на запуск у певному місці.
Хижі тварини можуть бачити всіх інших тварин у радіусі 30 одиниць. Вони можуть рухатись максимум 6,0 одиниць за оборот.
Хижаки можуть бачити всіх інших тварин в радіусі 50 одиниць. Вони можуть рухатись максимум 6,1 одиниці за оборот. Це означає, що вони можуть побачити здобич, перш ніж їх побачать і (ледве) випередили їх.
Хижаки живуть і гинуть відповідно до рівня їх голоду . Він починається з 1000 , і зменшується на кожен поворот. Якщо після пересування хижак знаходиться в межах 1 одиниці здобичі, він автоматично з'їсть його. Це вилучає здобич і встановлює голод хижака до 1000. Кожен хижак може з'їдати лише одну здобич за оборот. Якщо в межах даного діапазону їх більше, він з'їсть той, до кого потрапить перша петля (не обов'язково найближча). Хижак гине, якщо його голод досягає нуля.
Пакети починаються з п'яти членів у кожному. Кожні 5000 оборотів, усі пакети, що залишаються в грі, породять одного нового учасника. Він буде розміщений у видимому діапазоні члена колеги. Переконайтеся, що ваші записи можуть обробляти більше п'яти членів.
Кожні 1000 оборотів породжуватиметься більше здобичі. Кількість нової здобичі буде кількістю живих хижаків мінус одна.
Хижаки не можуть атакувати інших хижаків. Вони їдять здобич, коли їх ловлять. Це воно.
Замовлення протягом черги:
- Усі здобичі приймають рішення
- Усі хижаки приймають рішення
- Усі здобичі рухаються
- Всі хижаки рухаються / їдять
Порядок, коли кожен пакет приймає свої рішення / кроки, буде рандомізований на кожному кроці.
Протокол (загальний)
Всі комунікації проводяться у рядковому форматі US-ASCII
. Числа перетворюються на рядки за допомогою Java Double.toString()
або Integer.toString()
. Вихід повинен бути відформатований таким чином, щоб він міг прочитати Java Double.valueOf(String)
(ви не будете виводити цілі числа). Детальніше про розбірливі формати див. У документації дляDouble
. Усі поля в рядку розділені стандартним \t
символом, а нові рядки - \n
. Весь рядок буде завершений буде нульовим байтом \0
.
У наведених нижче прикладах я використовую <>
для позначення полів для читабельності. Їх немає у власних рядках.
Протокол (введення)
Рядок введення змінюється по довжині, в залежності від того, скільки істот видно у вашій упаковці. Він може перевищувати 100 тис. Символів, тому будьте готові до цього. Основна установка:
Рядок 0: Основна інформація про гру.
turn
- поточний номер черги, і рахунки - це загальна кількість здобичі та хижаків, залишених на полі. Вони єinteger
в рядковій формі.<turn>\t<preyCount>\t<predatorCount>\n
Рядок 1: унікальні ідентифікаційні показники та голод членів вашої упаковки. Вони не задаються в одному порядку для кожного введення. Використовуйте унікальні ідентифікатори для відстеження окремих членів, а не в тому порядку, в якому вони відображаються на вході. Знову ж таки, це
integer
як струни. Для пачки з двох це:<id[0]>\t<hunger[0]>\t<id[1]>\t<hunger[1]>\n
Рядок 2: Позиція членів вашої упаковки в тому ж порядку, що і в рядку 1 . Вони є такими,
double
як рядок:<x[0]>\t<y[0]>\t<x[1]>\t<y[1]>\n
Наступні рядки - це видимість кожного учасника пакету в тому ж порядку, що і в рядку 1 . Вони будуть надані у вигляді двох рядків на кожного члена.
Перший для кожного складається з місць для здобичі, яку він може бачити. Друге - це місця для хижаків, які він може бачити. Ці місця не є унікальними в цілому. Наприклад, якщо двоє членів зграї можуть бачити одну тварину, це буде в рядку обох членів. Також будуть включені ваші власні члени пакету . Якщо ви хочете їх виключити, ви можете порівняти місця розташування з власними членами. Усі локації є у double
форматі рядка.
Для кожного живого члена:
<prey[0].x>\t<prey[0].y>\t<prey[1].x>\t<prey[1].y>\n
<predator[0].x>\t<predator[0].y>\t<predator[1].x>\t<predator[1].y>\n
Нарешті, останній символ буде \0
на початку наступного рядка.
Виняток: Якщо ви отримаєте вхід dead\0
, ваша упаковка мертва. Закінчіть програму витончено, будь ласка. Контролер повинен закривати всі живі процеси, коли він закритий, але я б краще не міг зомбі в усіх місцях. Як люб’язно, ви можете включити тайм-аут введення. Наприклад, мій клас прикладу закінчується, якщо він не отримує введення протягом 15 секунд.
Протокол (вихідний)
Вихід простий. Ви дасте пару double
значень для кожного члена живого пакету. Вони представляють рух, який ви хотіли б зайняти на цьому кроці. Наприклад, якщо ваша істота наразі знаходиться, {100.0, 100.0}
і ви даєте їм команду {-1.0, 1.0}
, вони перейдуть до {99.0, 101.0}
. Усі числа будуть в одному рядку, розділеному вкладкою.
Наприклад, якщо у вас були 3 члени пакету, це буде правильною відповіддю:
1.0\t-1.0\t2.0\t-2.0\t3.0\t-3.0\0
Це буде рухатися ваші істоти шляхом {1.0,-1.0}
, {2.0,-2.0}
і {3.0,-3.0}
. Порядок такий самий, як отриманий на вході. Не забувайте закінчення \0
!
Якщо ви дасте невірний внесок, наступні будуть погані результати. Якщо будь-яке одне число неможливо проаналізувати на a double
, воно стане нульовим. Якщо рядок у цілому неможливо проаналізувати, нові інструкції не даватимуться, і весь ваш пакет буде використовувати вказівки з попереднього ходу.
Усі напрямки будуть затиснуті на максимальну відстань 6,1 одиниці. Ви можете рухатись повільніше, ніж це, якщо хочете. Наприклад, {1, 0}
перемістить вам одну одиницю. {6,8}
(відстань 10) перемістить вас лише на 6,1 одиниці і зменшиться до приблизно {3.66, 4.88}
. Напрямок залишається постійним.
Важливо: Програма управління читає і ваш STDOUT, і STDERR. Якщо ви кинете виняток і друкуєте на STDERR, дуже малоймовірно, що повідомлення буде у формі дійсної відповіді. Намагайтеся уникати цього.
Програма контролю / тестування
Джерело для контролера можна знайти тут на bitbucket.org . Вам потрібно буде скомпілювати його перед запуском. Основний клас є Game
, і всі класи знаходяться в пакеті за замовчуванням. Для запуску додайте команду кожного пакета як окремий аргумент. Наприклад, якщо ви хочете запустити Java ChaserPack і Python LazyPack.py, ви можете використовувати:
java Game "java ChaserPack" "python LazyPack.py"
На карті здобич з’являється зеленим кольором, а хижаки - червоним. Однак, який би пакет був першим пакетом, поданим в якості аргументу, замість цього буде кольоровим кольором. Це покликане легше їх розрізнити для тестування. Хижаки також спалахнуть білим протягом п’яти кадрів, коли вони їдять.
Гра триватиме до тих пір, поки останній хижак не голодує, записуючи до консолі, як трапляються голодування чи вимирання. Після того, як гра завершена, за кожний пакет буде додано рахунок. Якщо ви не хочете бачити події голоду / вимирання, можете скористатися -silent
аргументом. Тоді він виведе лише остаточний рахунок. Ви повинні передати це як перший аргумент :
java Game -silent "java ChaserCat" "./someOtherPack"
У комплекті є пакет скелета Java з назвою GenericPack
. Він включає основні операції введення / виводу, необхідні. Саме там можна навести наочний приклад того, як розбирати та відповідати. Якщо ви хочете додати шаблон іншою мовою, дайте мені знати.
Також хижак на основі шаблону, ChaserPack
. Він не буде включений у турнір, а включений лише для тестування. Це дуже погано, через умисний недолік націлювання. Якщо ви не можете його перемогти, продовжуйте намагатися.
Нижче наведено приклад запуску програми управління (натисніть на відео). Якість відео не чудова (вибачте), але ви можете відчути, як рухається здобич. ( обережність: аудіо )
Оцінка балів
Переможець визначатиметься турніром, набираючи очки у кожному раунді.
Кожен раунд триває, поки всі хижаки не загинуть. Кожна пачка буде нараховуватися залежно від того, коли останній член помер від голоду. Потім їм будуть присвоєні бали на основі порядку. Бали накопичуватимуться за десять раундів, а переможець - пакет з найвищими загальними балами.
Перше місце за кожен тур отримає 100 балів. За кожне місце після цього винагорода буде зменшена на 20% (округлена вниз). Це триватиме доти, доки бали не досягне нуля (після 17-го місця). Місця 18+ не отримають балів за раунд. Пачки, які зв'язали, отримають рівні бали. Наприклад:
1st : 100
2nd : 80
3rd : 64 (T)
3rd : 64 (T)
4th : 51
...
17th: 1
18th: 0
19th: 0
Максимально можливий бал за час турніру - 1000, з першого місця за всі десять разів.
Якщо декілька програм завершать турнір, зв'язаний за перше місце, відбудеться ще десять туровий турнір з поданням лише заявок на перше місце . Це триватиме до тих пір, поки не з’явиться один переможець.
Я намагатимусь проводити турнір приблизно щотижня, або в міру надходження нових заявок.
Додаткові правила (грайте справедливо!)
Ви не можете читати чи писати будь-які зовнішні ресурси. Оскільки ви не збираєтеся більше разів визивати свою програму, будь-яка інформація про стан може зберігатися всередині країни.
Не втручайтеся в інші процеси / подання. Це не означає, що не намагайтеся вкрасти свою здобич, випередити їх і т. Д. Це означає, що не заважайте виконувати процес. Це на мій розсуд.
Учасники конкурсу обмежені максимум трьома записами. Якщо ви подасте більше, я наберу лише перші три подані. Якщо ви хочете відкликати його, видаліть його.
Записи можуть не існувати виключно для підкріплення інших записів. Кожен повинен грати, щоб виграти за власними заслугами.
Ваша програма може породити максимум один дочірній процес одночасно ( загальний нащадок, а не прямий). У будь-якому випадку, переконайтеся, що ви не переходите на час очікування. Ви не можете жодним чином викликати сам
Game
клас.
Результати - 29 квітня 2014 року
Ось результати останнього турніру з десяти турів:
Clairvoyant : 1000
EcoCamels : 752
Netcats : 688
RubySpiders : 436
RubyVultures : 431
CivilizedBeasts : 382
LazyPack : 257
Пакети, подані до 09:00 EDT 2014/04/29, включаються до цього циклу.
Ви також можете переглянути деталі для кожного раунду . Чомусь я вирішив нумерувати раунди назад, тому він починається з "раунду 10".
Оновлення
23.04.2014: FGreg повідомив про помилку, пов’язану з таймаутами (спасибі!). Виправлено виправлення, тому тестери хочуть оновити код програми управління.