Hunger Gaming - Eat or Die
Jeśli nie jesz, umierasz. Jeśli jesz, żyjesz (aż umrzesz). Państwo będzie umrzeć, więc starają się umiera ostatnia.
Przegląd
Istnieje wyspa zamieszkana przez stado drapieżnych zwierząt. Kontrolujesz paczkę pięciu drapieżników. Twoim celem jest utrzymanie paczki przy życiu. Zrób to, jedząc zdobycz. Ofiara ma tendencję do uciekania przed drapieżnikami i próbowania pozostania w stadzie. Oczywiście twoja paczka będzie na tym samym polu, co każda inna paczka , więc konkurencja spróbuje je zjeść, zanim będziesz mógł. Nie pozwólcie, aby to was zniechęciło, bo będziecie głodować.
Jak grać
Utwórz i prześlij program wiersza poleceń do kierowania paczką. Otrzyma informacje o stanie z programu sterującego na STDIN i wyda polecenia na STDOUT. Format jest szczegółowo opisany poniżej. Każdy program zostanie wykonany tylko raz i musi pozostać uruchomiony, dopóki nie będzie miał już żadnych członków pakietu. Będziesz musiał czytać wprowadzane dane i szybko reagować. Limit czasu reakcji wynosi 200 ms dla każdej odpowiedzi. Jeśli do tego czasu nie odpowiesz, twoja paczka nie otrzyma nowych instrukcji dotyczących bieżącej tury.
Jeśli program nie może być uruchomiony przez kontroler, nie zostanie uznany za prawidłowy. Podaj ciąg wiersza polecenia, którego będę musiał użyć, aby uruchomić przesyłanie. Jeśli są jakieś specjalne instrukcje (dotyczące konfiguracji kompilatorów itp.), Dołącz je. Jeśli nie uda mi się go uruchomić, poproszę cię o pomoc w komentarzach. Jeśli nie odpowiesz, nie będę w stanie zaakceptować Twojego zgłoszenia.
Turniej odbędzie się na 64-bitowym systemie Linux. Należy o tym pamiętać, podając wszelkie niezbędne wskazówki.
Detale
Pozycja i kierunek każdego stworzenia ma postać pary liczb zmiennoprzecinkowych podwójnej precyzji (np.
double
) Reprezentujących odpowiednio ichx
iy
współrzędne.Każde stworzenie jest uważane za punkt. Oznacza to, że mogą się nakładać i zajmować to samo miejsce. Nie zostaniesz potrącony na bok i nie ma koncepcji kolizji z innymi stworzeniami.
Wyspa ma kwadrat, 500 jednostek w bok. Jeśli spróbujesz wyjść poza te granice, zostaniesz zaciśnięty na krawędzi. Początek
{0,0}
znajduje się w lewym górnym rogu, zex
wzrostem w prawo iy
wzrostem w dół. Ponownie mapa się nie zawija .Gra rozpoczyna się od 1500 + (packCount * 50) zwierząt drapieżnych. Zostaną zebrani w centrum wyspy, ale szybko zdecydują się ruszyć.
Paczki będą rozmieszczone w równomiernie rozmieszczonym okręgu na obwodzie. Kolejność paczek jest tasowana, więc nie licz na rozpoczęcie w określonej lokalizacji.
Zwierzęta drapieżne mogą zobaczyć wszystkie inne zwierzęta w promieniu 30 jednostek. Mogą się poruszać maksymalnie 6,0 jednostek na turę.
Drapieżniki mogą zobaczyć wszystkie inne zwierzęta w promieniu 50 jednostek. Mogą się one poruszać maksymalnie 6,1 jednostek na turę. Oznacza to, że mogą zobaczyć ofiarę, zanim zostaną zauważeni i (ledwo) ich wyprzedzić.
Drapieżniki żyją i umierają zgodnie z poziomem głodu . Zaczyna się od 1000 i zmniejsza o jedną w każdej turze. Jeśli po ruchu drapieżnik znajdzie się w odległości 1 jednostki ofiary, automatycznie go zje. To usuwa ofiarę i ustawia głód drapieżnika na 1000. Każdy drapieżnik może zjeść tylko jedną ofiarę na turę. Jeśli w zasięgu jest więcej niż jeden, zje to, do którego dojdzie pierwsza pętla (niekoniecznie najbliższa). Drapieżnik umiera, jeśli jego głód osiągnie zero.
Pakiety zaczynają się od pięciu członków . Co 5000 tur wszystkie paczki nadal w grze będą odradzać jednego nowego członka. Zostanie umieszczony w widocznym zasięgu innego członka paczki. Upewnij się, że twoje wpisy mogą obsłużyć więcej niż pięciu członków.
Co 1000 tur pojawi się więcej ofiar. Liczba nowych ofiar będzie liczbą żyjących drapieżników minus jeden.
Drapieżniki nie mogą atakować innych drapieżników. Jedzą zdobycz, kiedy ją łapią. Otóż to.
Kolejność w turze to:
- Wszystkie ofiary podejmują decyzje
- Wszystkie drapieżniki podejmują decyzje
- Wszystkie ofiary się ruszają
- Wszystkie drapieżniki poruszają się / jedzą
Kolejność, w jakiej każda paczka podejmuje decyzje / ruchy, będzie losowa w każdej turze.
Protokół (ogólne)
Cała komunikacja odbywa się w formacie łańcuchowym US-ASCII
. Liczby są konwertowane na ciągi znaków przy użyciu języka Java Double.toString()
lub Integer.toString()
. Twoje dane wyjściowe muszą być sformatowane, aby można je było odczytać w Javie Double.valueOf(String)
(nie będziesz wypisywać liczb całkowitych). Aby uzyskać szczegółowe informacje na temat możliwych do przeanalizowania formatów, zobacz dokumentację dotyczącąDouble
. Wszystkie pola w wierszu są oddzielone \t
znakiem standardowym , a znaki nowego wiersza są \n
. Cały ciąg zostanie zakończony bajtem zerowym \0
.
W poniższych przykładach używam <>
do zaznaczenia pól ze względu na czytelność. Nie są one obecne w rzeczywistych ciągach.
Protokół (wejście)
Łańcuch wejściowy ma różną długość, w zależności od liczby stworzeń widocznych dla twojej paczki. Może przekraczać 100 000 znaków, więc bądź na to przygotowany. Podstawowa konfiguracja to:
Wiersz 0: podstawowe informacje o grze.
turn
jest bieżącym numerem tury, a liczby to łączna liczba zdobyczy i drapieżników pozostawionych na polu. Sąinteger
w formie ciągów.<turn>\t<preyCount>\t<predatorCount>\n
Wiersz 1: Unikalne identyfikatory i poziomy głodu członków Twojej paczki. Nie są one podawane w tej samej kolejności dla każdego wejścia. Użyj unikalnych identyfikatorów do śledzenia poszczególnych członków, a nie w kolejności, w jakiej pojawiają się na wejściu. Ponownie są to
integer
ciągi znaków. W przypadku paczki dwóch byłoby to:<id[0]>\t<hunger[0]>\t<id[1]>\t<hunger[1]>\n
Wiersz 2: pozycje członków twojej paczki, w tej samej kolejności, jak podano w wierszu 1 . Są to
double
ciąg:<x[0]>\t<y[0]>\t<x[1]>\t<y[1]>\n
Poniższe wiersze pokazują widoczność każdego członka paczki, w tej samej kolejności, jak podano w wierszu 1 . Zostaną one podane jako dwie linie na członka.
Pierwszy dla każdego składa się z lokalizacji zdobyczy, którą widzi. Drugi to lokalizacje drapieżników, które widzi. Te lokalizacje nie są wyjątkowe jako całość. Na przykład, jeśli dwóch członków paczki może zobaczyć to samo zwierzę, będzie ono w łańcuchu obu członków. Uwzględnione zostaną również członkowie Twojej paczki . Jeśli chcesz je wykluczyć, możesz porównać lokalizacje z własnymi członkami. Wszystkie lokalizacje mają double
format ciągów.
Dla każdego żyjącego członka:
<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
Wreszcie ostatni znak będzie \0
na początku następnego wiersza.
Wyjątek: jeśli otrzymasz dane wejściowe dead\0
, twoja paczka jest martwa. Proszę zakończyć swój program z wdziękiem. Kontroler powinien zamknąć wszystkie żywe procesy, gdy są zamknięte, ale wolałbym, aby procesy zombie nie były wszędzie. W ramach grzeczności możesz wprowadzić limit czasu wprowadzania danych. Na przykład moja przykładowa klasa kończy się, jeśli nie otrzyma danych wejściowych przez 15 sekund.
Protokół (wynik)
Wyjście jest proste. Podasz parę double
wartości dla każdego członka pakietu na żywo. Reprezentują ruch, który chciałbyś, aby wykonali w tej turze. Na przykład, jeśli twoje stworzenie jest obecnie w pobliżu {100.0, 100.0}
i wydasz mu rozkaz {-1.0, 1.0}
, zostaną przeniesione do {99.0, 101.0}
. Wszystkie liczby będą w jednym wierszu, oddzielone tabulatorem.
Na przykład, jeśli żyłeś 3 członków paczki, byłaby to prawidłowa odpowiedź:
1.0\t-1.0\t2.0\t-2.0\t3.0\t-3.0\0
To byłoby przenieść stworzeń przez {1.0,-1.0}
, {2.0,-2.0}
i {3.0,-3.0}
. Kolejność jest taka sama jak otrzymana na wejściu. Nie zapomnij zakończenia \0
!
Jeśli podasz nieprawidłowe dane wejściowe, pojawią się złe wyniki. Jeśli jakikolwiek pojedynczy numer nie może zostać przetworzony na a double
, stanie się zero. Jeśli ciąg jako całość nie może zostać przeanalizowany, nie zostaną podane żadne nowe instrukcje, a cała paczka użyje wskazówek z poprzedniej tury.
Wszystkie kierunki zostaną zaciśnięte w maksymalnej odległości 6,1 jednostek. Jeśli chcesz, możesz poruszać się wolniej. Na przykład {1, 0}
przeniesie cię o jedną jednostkę. {6,8}
(odległość 10) przeniesie Cię tylko 6,1 jednostek i zmniejszy się do około {3.66, 4.88}
. Kierunek pozostaje stały.
Ważne: Program sterujący odczytuje zarówno STDOUT, jak i STDERR. Jeśli zgłosisz wyjątek i wydrukujesz do STDERR, jest bardzo mało prawdopodobne, że wiadomość będzie miała poprawną odpowiedź. Staraj się tego unikać.
Program sterujący / testowanie
Źródło kontrolera można znaleźć tutaj na bitbucket.org . Musisz go skompilować przed uruchomieniem. Główną klasą jest Game
, a wszystkie klasy znajdują się w domyślnym pakiecie. Aby uruchomić, dołącz polecenie każdej paczki jako osobny argument. Na przykład, jeśli chcesz uruchomić Java ChaserPack i Python LazyPack.py, możesz użyć:
java Game "java ChaserPack" "python LazyPack.py"
Na mapie zdobycz pojawia się na zielono, a drapieżniki na czerwono. Jednak którakolwiek paczka jest pierwszą paczką podaną jako argument, zamiast tego będzie miała kolor niebieski. Ma to na celu ich łatwiejsze rozróżnienie do celów testowych. Drapieżniki będą również migać na biało przez pięć klatek podczas jedzenia.
Gra będzie trwać, dopóki ostatni drapieżnik głoduje, pisząc na konsolę, gdy zdarzają się zdarzenia głodu lub wyginięcia. Po zakończeniu gry wynik będzie przyznawany za każdą paczkę. Jeśli nie chcesz widzieć zdarzeń głodu / wyginięcia, możesz użyć -silent
argumentu. Wtedy wyświetli tylko końcowy wynik. Musisz przekazać to jako pierwszy argument :
java Game -silent "java ChaserCat" "./someOtherPack"
Dołączony jest szkieletowy pakiet Java o nazwie GenericPack
. Obejmuje podstawowe niezbędne operacje wejścia / wyjścia. Jest tam, aby dać jasny przykład, jak parsować i odpowiadać. Jeśli chcesz dodać szablon w innym języku, daj mi znać.
Również jest drapieżnikiem na podstawie szablonu ChaserPack
. Nie zostanie uwzględniony w turnieju i jest uwzględniony tylko w celach testowych. Działa dość słabo z powodu celowej wady celowania. Jeśli nie możesz tego pokonać, próbuj dalej.
Poniżej znajduje się przykładowe uruchomienie programu sterującego (kliknij, aby zobaczyć wideo). Jakość wideo nie jest świetna (przepraszam), ale możesz poczuć, jak porusza się ofiara. ( uwaga: audio )
Punktacja
Zwycięzca zostanie wyłoniony na podstawie turnieju, zdobywając punkty w każdej rundzie.
Każda runda trwa do momentu śmierci wszystkich drapieżników. Każda paczka będzie punktowana na podstawie tego, kiedy jej ostatni członek zmarł z głodu. Następnie zostaną im przypisane punkty na podstawie zamówienia. Punkty będą gromadzone przez dziesięć rund, a zwycięzcą jest paczka z najwyższą sumą punktów.
Pierwsze miejsce w każdej rundzie otrzyma 100 punktów. Za każde kolejne miejsce nagroda zostanie zmniejszona o 20% (zaokrąglona w dół). Będzie to trwało, dopóki punkty nie osiągną zera (po 17 miejscu). Miejsca 18+ nie otrzymają punktów za rundę. Pakiety, które remisują, otrzymają równe punkty. Na przykład:
1st : 100
2nd : 80
3rd : 64 (T)
3rd : 64 (T)
4th : 51
...
17th: 1
18th: 0
19th: 0
Maksymalna możliwa liczba punktów w trakcie turnieju to 1000, od pierwszego miejsca wszystkie dziesięć razy.
Jeśli wiele programów zakończy turniej remisowy na pierwszym miejscu, odbędzie się kolejny turniej rundy dziesięciu z tylko zgłoszonymi pierwszymi miejscami . Będzie to trwało, dopóki nie pojawi się jeden zwycięzca.
Postaram się organizować turniej mniej więcej co tydzień lub w miarę pojawiania się nowych zgłoszeń.
Dodatkowe zasady (graj fair!)
Nie możesz czytać ani pisać do żadnych zasobów zewnętrznych. Ponieważ nie będziesz wywoływał wielokrotnie programu, wszystkie informacje o stanie mogą być przechowywane wewnętrznie.
Nie ingeruj w inne procesy / zgłoszenia. To nie nie znaczy nie próbować ukraść zdobycz, prześcignąć je, itd. Oznacza to, że nie przeszkadzają w prowadzeniu procesu. To zależy ode mnie.
Uczestnicy są ograniczeni do maksymalnie trzech zgłoszeń. Jeśli prześlesz więcej, zdobędę tylko pierwsze trzy przesłane. Jeśli chcesz je odwołać, usuń je.
Wpisy mogą nie istnieć wyłącznie w celu wspierania innych wpisów. Każdy powinien grać, aby wygrać na własną rękę.
Twój program może odradzać maksymalnie jeden proces potomny na raz ( całkowita liczba potomków, a nie bezpośredni). Tak czy inaczej, upewnij się, że nie przekroczysz limitu czasu. Nie możesz
Game
w żaden sposób wywoływać samej klasy.
Wyniki - 29 kwietnia 2014 r
Oto wyniki ostatniego dziesięcio-rundowego turnieju:
Clairvoyant : 1000
EcoCamels : 752
Netcats : 688
RubySpiders : 436
RubyVultures : 431
CivilizedBeasts : 382
LazyPack : 257
Pakiety przesłane przed 09:00 EDT 2014/04/29 są uwzględnione w tym biegu.
Możesz także wyświetlić szczegóły każdej rundy . Z jakiegoś powodu postanowiłem numerować rundy do tyłu, więc zaczyna się od „rundy 10”.
Aktualizacje
2014/04/23: FGreg zgłosił błąd związany z przekroczeniem limitu czasu (dzięki!). Zaimplementowano poprawkę, więc testerzy będą chcieli zaktualizować kod programu sterującego.