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.
źródło
Odpowiedzi:
Jasnowidz
Kod zaktualizowany, aby zmierzyć się z AbleDogs
Woo hoo! Nareszcie bije to Netcats! Rozszerzyłem istniejący kod (napisy do Geobitów!) Z niewielkimi modyfikacjami, aby stworzyć ten pakiet do przewidywania przyszłości. Nic nie przebije drapieżników, którzy wiedzą, dokąd przeniesie się zdobycz!
Z dwóch testów, które przeprowadziłem, moja paczka zawsze wygrywała z Netcats. Ale to nie zadziała tak dobrze, jeśli nie będzie innych paczek, ponieważ przewidywanie wciąż nie powiedzie się, jeśli w pobliżu będzie zbyt wiele innych ofiar.
Prawdopodobnie mogę zastosować sztuczkę CivilizedBeasts, aby znacznie zmniejszyć liczbę ofiar w ciągu pierwszych kilku tysięcy tur.
Od nazwy mojej paczki powinieneś wiedzieć, jakiej strategii używam = D
Edytuj :
Popraw szczególne przypadki, gdy poprzednia wersja utknęła w rogu.flock[ALIGN]
czynnik ofiaryPoliczyłem, ile ofiar zjada każda paczka, a oto wynik:
Moja paczka jest bardzo agresywna i większość z 916 liczy się, jak sądzę, dzięki kradzieży zdobyczy Netcats, podobnie jak RubySpiders.
CivilizedBeasts przegrywa niestety z powodu środkowego wielbłąda z EcoCamel.
A EcoCamel (z krytycznym poziomem głodu 500) jest dość wydajny, zjada tylko tyle, aby przetrwać do końca.
Również dzięki temu zaktualizowanemu jasnowidzowi gra osiąga zaledwie 10 000 tur.
Kod:
źródło
Netcats
Oto paczka na początek. Rozszerza
GenericPack
klasę zawartą w programie sterującym. Zostało ulepszone od czasu pierwotnego opublikowania i nie głodzi już rzadkiego stada.Netcaty używają formacji siatki w kształcie vee, aby uwięzić zdobycz w rogu, gdzie mogą ją zjeść w wolnym czasie. Siatka jest utworzona z jednym elementem „główkowym” pośrodku. Gdy głowa je, zamienia się miejscami z najbardziej głodnym członkiem paczki, ponieważ głowa jest zwykle pierwszą, która ma okazję zjeść.
Siatka zaczyna się raczej mała, ale rozszerza się, gdy stado staje się mniejsze, aby bardziej efektywnie trałować pole.
Jeśli nie widać żadnej ofiary, formacja staje się naiwnym wzorem poszukiwań obejmującym większość wyspy.
Gdy paczka spadnie do dwóch członków, sieć po prostu nie działa. W tym momencie każdy idzie swoją drogą, łapczywie jedząc najbliższą rzecz, jaką może znaleźć, i idąc w przeciwnym razie na wpół losowy spacer.
Ta wersja przetrwa znacznie lepiej niż naiwne Netcaty widoczne na filmie z linkiem do pytania.
źródło
Rubinowe Pająki
Ponieważ czasami mniej znaczy więcej, a wiele rozwiązań prawdopodobnie i tak spróbuje zaatakować ofiarę ...
Myślałem, że moja paczka może po prostu się rozdzielić i czekać, aż inni wykonają pracę.
Uwaga: W rzeczywistości nie działa, nie odczytuje danych wejściowych ani nie reaguje szybko. Mimo to, ponieważ działa dobrze z kontrolerem, mam nadzieję, że kwalifikuje się bez dalszych dostosowań.
źródło
CivilizedBeasts
Wreszcie czas pokazać moje bestie!
Moja rasa uważa, że polowanie jest nieco prymitywne, dlatego pracują razem w 4-osobowym zespole, dlatego porzucają swojego piątego sojusznika, ponieważ: mniej drapieżników = więcej ofiar dla siebie. Zasadniczo robią to, co robią ludzie, łapią zdobycz i dbają o swoje bydło;)
Moje piersi stają się dość trudne do przeżycia z mniej niż 200 ofiarami na turie + -12 000, mając w grze tylko wrogie Netcaty. Będziesz zadowolony z tej rasy, ponieważ naprawdę pochłania ogromne ilości zdobyczy z prędkością, jakiej żadna inna rasa nigdy nie może (nie tak, że szybkie i duże rzeźnie zapewniają zwycięstwo, ale ma to znaczący wpływ na (długi) czas trwania całej rundy).
źródło
Rubinowe Sępy
Oto paczka bardziej aktywnych pasożytów . Próbują otoczyć najbliższego poruszającego się drapieżnika , aby ukraść jego ofiarę . Są trochę uzależnieni od szczęścia, ponieważ nie mają sprytnego sposobu na wybranie, za kim podążać, ale zwykle biją ścigających, a czasem pająków .
Nie są jeszcze całkiem skończone, ponieważ opublikowałem to, aby przyspieszyć tempo :)
Mam nadzieję, że:
22 kwietnia 2014: Dodano nudę , dzięki czemu są mniej lepkie i pozwalają im samodzielnie polować na zdobycz i szukać drapieżników
źródło
ZłeEco WielbłądyEdycja: Mutacja # 2. Och, nie, spóźniłem się z wprowadzeniem przewidywania ruchu zdobyczy, aby jako pierwszy pokonać Netcats. OK, niech tak będzie.
Ta mutacja ma
$hunger_critical
zmienną (stałą). Zmiana jej na wartość powyżej 1000 powoduje, że Wielbłądy zawsze polują, tak jak jasnowidze. Następnie:Jeśli
$hunger_critical
jest ustawiony na np. 500 (jak poniżej), to moje Wielbłądy (po zobaczeniu okropności cywilizacji ) starają się zachowywać w sposób przyjazny dla środowiska (stąd zmieniły nazwę rasy), tzn. Zabijają tylko wtedy, gdy są głodne. Jeśli nie są głodni, patrolują krytyczne obszary wyspy - środek i rogi, aby zapobiec bezcelowemu rzeźnictwu przez innych łowców. Cóż, z centrum, mniej więcej działa. Ideą krążenia w rogach było odepchnięcie ofiary i utrudnienie życia Kotom i pasożytom. Cóż, to nie działa. Głupia zdobycz i tak idzie w kąty.Interesujące jest również to, że
flock[ALIGN]
drapieżniki mogą odgadnąć ten komponent, a moja implementacja różni się od implementacji justhalfa. Obawiam się, że istnieje jakiś drobny błąd w moimzdzierstwowykonania kodu Geobits', oglądanie / porównując polowania indywidualnego cameli vs jasnowidzów.A program jest trochę długi, przepraszam.
Edycja: Mutacja # 1. Wyspa okazuje się dość radioaktywna (co tłumaczy brak roślinności i niewytłumaczalną naturę „drapieżnych” stworzeń), więc oto pierwsza mutacja moich Wielbłądów. Każdy z nich może zostać łowcą solo, jeśli jest głodny lub jeśli nie ma wolnego kąta dla wszystkich. Hunter próbuje aktywnie ścigać pobliską zdobycz. Jeśli nie ma, patroluje w szerokim kręgu wokół centrum wyspy, a następnie goni najbliższe stworzenie, gdy je znajdzie. Niestety, kierunek zdobyczy staje się nieprzewidywalny, gdy jest blisko roju (warto to zbadać ...), więc pościg solo nie jest zbyt skuteczny. Ale jeśli się powiedzie, wielbłąd idzie do trawienia do najbliższego wolnego rogu (jeśli istnieje). Kiedy poziom głodu spadnie poniżej pewnego poziomu, każdy wielbłąd opuszcza swój róg (prawdopodobnie przeklinając Netcats („gdzie jest jedzenie?”) )) i samodzielnie rozpoczyna bezpłatny roaming. I tak dalej.
Ten sam dowcip dwa razy nie jest śmieszny, ale (1) musiałem gdzieś zacząć i jestem nowy w tych sprawach, (2) szczerze mówiąc, myślałem o taktach narożnych (a kto nie?) Oglądając Netcats przed Ruby Pająki pojawiły się na wyspie.
Czy słyszałeś kiedyś o wielbłądach mięsożernych? Biedne zwierzęta obudziły się pewnego dnia na zapomnianej przez Boga wyspie, by nie znaleźć trawy ani drzew, ale mnóstwo dziwnych zielonych, choć jadalnych, szybko poruszających się (dość irytujących) drobiazgów. Nie mając przyzwyczajeń związanych z polowaniem (mam nadzieję, że wkrótce zmutują), moje Wielbłądy opracowały bardzo zły plan przetrwania: dzielą się i idą każdy z 1 na 4 rogi, a piąty idzie do centrum (aby tam umrzeć jako pierwszy, ponieważ okazuje się). W miejscu docelowym cierpliwie czekają, wykonując rodzaj wielbłądziego tańca wojennego, a może po prostu starają się nie deptać już tam innych zwierząt, pająków i wszystkich ...
źródło
vec
nieruchomość jest w zasadzie tylko przemieszczenie z poprzedniego kolei do bieżącej turze. I jak powiedziałem, dopasowujemy wyniki z poprzedniej tury, aby dowiedzieć się, która ofiara idzie w którą stronę, nie możemy polegać na kolejności zdobyczy. Jest to możliwe, ponieważ ofiary zwykle (w typowym scenariuszu) zachowują wystarczającą odległość od siebie (> 12 jednostek), więc przez większość czasu możemy dopasować zdobycze w poprzedniej turze do obecnej tury.AbleDogs - PHP
Te miłe psy nauczyły się gryźć łydki ofiary, aby ocierać ją o ściany. Uwielbiają też wędrować po pastwisku w poszukiwaniu nowych ofiar. Wreszcie, nauczono ich, aby powstrzymywali się od jedzenia, chyba że naprawdę potrzebują kalorii.
Umieść kod w
AbleDogs
pliku i uruchom gophp AbleDogs
Uwagi ogólne
Liczy się gra końcowa. Możesz mieć najmądrzejszy algorytm polowania, jeśli nie zauważysz i nie złapiesz kilku ostatnich ofiar szybciej niż przeciwnik, przegrasz.
Jeśli twoje drapieżniki nie są w stanie złapać zdobyczy w pojedynkę (lub przynajmniej parami), wznosisz toast, gdy tylko gęstość zdobyczy spadnie wystarczająco nisko, aby polegać na ślepym szczęściu lub blokowaniu zdobyczy w rogach.
Predyktor ruchu zdobyczy jest zasadniczo obowiązkowy. Nie wyobrażam sobie pokonania programu opartego na predyktorach bez własnego predyktora.
Pogoń za ogonem
Najbardziej nieefektywnym sposobem złapania ofiary jest ściganie jej przez ogon. Zakładając, że pojedynczy drapieżnik goni pojedynczą ofiarę i nie ma żadnych wpływów zewnętrznych (ściany, inne ofiary itp.), Pościg za ogonem może trwać wiecznie. Jak tylko wejdziesz w promień widzenia jednostki 30, zdobycz ucieka z prędkością 6 dla twojego 6.1, więc zyskujesz 1 odległość na turę: w linii prostej potrzebujesz około 300 obrotów, aby go zdobyć.
Biorąc pod uwagę rozmiar areny, ofiara przemierzy najwyżej przekątną 500 jednostek kwadratowych, zanim uderzy w ścianę lub róg, co zajmie maksymalnie 117 obrotów.
Zwycięską strategią jest oczywiście znalezienie sposobu na spowolnienie zdobyczy, mianowicie poprzez umieszczenie przed sobą innego drapieżnika lub ściany / rogu.
Urządzenie prognozujące
Z prędkością zdobyczy 6, zdobycz może przenieść się na obszar 36 * pi jednostek do kwadratu. Przy promieniu łapania wynoszącym 1 ślepe przypuszczenie, gdzie będzie następna ofiara, ma szansę 1/36 * pi (około 1%) na odniesienie sukcesu. Oczywiście należy coś z tym zrobić!
Patrząc na kod silnika symulacji, widać, że dane wejściowe to:
Chociaż wszystkie pozycje są dostępne, poprzednie prędkości zdobyczy nie są. Jedynym sposobem obliczenia tych prędkości byłoby śledzenie każdej ofiary z jednego zakrętu do następnego, co jest prawie niemożliwe (chyba że zaimplementujesz bardzo inteligentny algorytm śledzenia ruchu). Dzięki temu predyktor może z łatwością odtworzyć wszystkie warunki obliczeń, z wyjątkiem wymaganego udziału prędkości.
W przypadku pojedynczej ofiary prędkość można śledzić bez większych problemów, co pozwala zbudować „idealny” predyktor do złapania ofiary odizolowanej od stada. To w zasadzie wszystko, czego potrzebujesz do gry końcowej, gdy ofiar jest zbyt mało, aby ze sobą współdziałać. Kiedy ofiary są obfite, a efekt stada jest wystarczająco silny, aby oszukać predyktora, sama gęstość ofiar zrekompensuje błędy (jeśli nie złapiesz tego, którego szukałeś, istnieje szansa, że dostaniesz jednego z jego najbliższych kumpli ).
Łapanie ofiar
Dzięki dokładnej wiedzy na temat obliczania prędkości zdobyczy możliwe jest „ukierunkowanie” danej zdobyczy w pożądanym kierunku poprzez dostosowanie położenia drapieżnika.
Pozwala to przypiąć zdobycz do ściany lub skierować ją w stronę innego członka paczki. Wypróbowałem kilka wyrafinowanych strategii, takich jak szczypanie ofiary między dwoma członkami stada. Niestety okazało się to mniej wydajne niż obecna procedura „pin and scan”, ponieważ utrzymywanie dwóch drapieżników zajętych ściganiem jednej ofiary pozostawia przeciwnikom zbyt wiele drapieżników swobodnych do wypatrywania pastwiska.
Kradzież ofiar
Jedną z cech zachowania ofiar jest to, że wpływ drapieżnika wzrasta proporcjonalnie do jego odległości od ofiary (pod warunkiem, że pozostaje on w promieniu widzenia ofiary). Im najbliższy drapieżnik trafi na zdobycz, najmniej ofiara będzie się od niego oddalać.
Oznacza to, że gdy dwóch drapieżników rywalizuje o zdobycie ofiary, najbliższy jest zobowiązany ją zdobyć jako pierwszy. Nawet super sprytny pretendent, który zdołałby ustawić się dokładnie przed osią chasera / ofiary, zasadniczo przestraszyłby ofiarę w szczęki pretendenta.
Aby ukraść ofiarę, potrzebna jest przynajmniej para drapieżników. Jeden pójdzie na zabójstwo, a pozostali pozostaną w promieniu widzenia ofiary, tak daleko od ofiary, jak to możliwe, aby zmaksymalizować wpływ i przyciągnąć zdobycz do łowcy.
Poza tym każda zmiana kierunku pozwoli rywali skrócić róg w kierunku ofiary, a trzymanie się za rywalem jest możliwe tylko wtedy, gdy „goader” był wystarczająco blisko ofiary na początku akcji.
Tak więc kradzież zdobyczy ma szansę powodzenia tylko wtedy, gdy początkowe pozycje „złodziei” są sprzyjające i można oszczędzić przynajmniej drugiego drapieżnika. Z mojego doświadczenia nie jest to warte złożoności.
Sugerowane zmiany
Aby pozwolić na bardziej złożone strategie, przeniesienie drapieżnika powyżej maksymalnej prędkości ofiary może kosztować punkty głodu proporcjonalne do przekroczenia prędkości. Załóżmy na przykład, że przejście do prędkości 6 jest bezpłatne, a każdy punkt prędkości powyżej 6 kosztuje 100 punktów głodu (przejście do 6,3 kosztuje 30 punktów głodu na turę, spalenie 1000 punktów głodu pozwoliłoby osiągnąć prędkość 16 na jedną turę - i umarłbyś, jeśli nie łapie zdobycz robiąc to!).
Zamiast zabijać przypadkowego drapieżnika, gdy więcej niż jeden jest wystarczająco blisko, aby zjeść ofiarę, sugeruję podzielenie zysku (na przykład 3 drapieżniki dostałyby po 333,33 punktów głodu). Pozwoliłoby to na bardziej interesujące strategie gry końcowej (cieniowanie wrogiego drapieżnika przydałoby się, jeśli na przykład uważasz, że masz więcej punktów głodu).
Specjalny kolor pierwszego opakowania jest raczej trudny do zauważenia. Sugeruję cyjan lub pomarańcz zamiast niebieskiego.
źródło
Lazy Pack Haskell
Do uruchomienia tego będziesz potrzebować platformy haskell . Następnie użyj
runhaskell
polecenia, aby go uruchomić. Moja paczka czeka na ofiarę, która do nich przyjedzie.źródło
-silent
opcji ...Nie jest to wpis, zawsze jestem zainteresowany dodaniem niestandardowego koloru dla każdego uczestniczącego wpisu w King-of-the-Hill ;)
Również proces jedzenia nie jest wizualizowany poprzez zmianę koloru, ale zmianę rozmiaru, dzięki czemu możemy zobaczyć wiele zdarzeń jedzenia w krótkim czasie.
Game.java
Predator.java
źródło