Asymetryczny KOTH: Catch the Cat
AKTUALIZACJA : Pliki gist są aktualizowane (w tym nowe zgłoszenia), ponieważ plik Controller.java nie wychwytuje wyjątków (tylko błędy). Przechwytuje teraz błędy i wyjątki, a także je drukuje.
To wyzwanie składa się z dwóch wątków, to jest wątek łapacza, można znaleźć wątek kota tutaj .
Kontroler można pobrać tutaj .
Jest to asymetryczna KOTH: Każde poddanie jest albo kotem lub łapacza . Istnieją gry między każdą parą każdego kota i łapacza. Koty i łapacze mają osobne rankingi.
Łapacz
Na sześciokątnej siatce jest kot. Twoim zadaniem jest złapanie go tak szybko, jak to możliwe. W każdej turze możesz umieścić wiadro z wodą na jednej komórce siatki, aby kot nie mógł tam dotrzeć. Ale kot nie jest (może) głupi i za każdym razem, gdy umieścisz wiadro, kot przeniesie się do innej komórki siatki. Ponieważ siatka jest sześciokątna, kot może iść w 6 różnych kierunkach. Twoim celem jest otoczenie kota wiadrami z wodą, im szybciej, tym lepiej.
Kot
Wiesz, że łapacz chce cię złapać, umieszczając wokół ciebie wiadra z wodą. Oczywiście próbujesz uniknąć, ale ponieważ jesteś leniwym kotem (tak jak koty), robisz dokładnie jeden krok naraz. Oznacza to, że nie możesz pozostać w tym samym miejscu, co ty, ale musisz przenieść się do jednego z sześciu okolicznych miejsc. Ilekroć zobaczysz, że łapacz umieścił nowe wiadro z wodą, idziesz do innej komórki. Oczywiście starasz się unikać tak długo, jak to możliwe.
Krata
Siatka jest sześciokątna, ale ponieważ nie mamy heksagonalnych struktur danych, bierzemy 11 x 11
kwadratową tablicę 2d i naśladujemy sześciokątne „zachowanie”, które kot może poruszać się tylko w 6 kierunkach:
Topologia jest toroidalna, co oznacza, że jeśli wejdziesz na komórkę „na zewnątrz” tablicy, zostaniesz po prostu przeniesiony do odpowiedniej komórki po drugiej stronie tablicy.
Gra
Kot zaczyna od określonej pozycji na siatce. Łapacz może wykonać pierwszy ruch, następnie kot i jego łapacz wykonują naprzemienne ruchy, dopóki kot nie zostanie złapany. Liczba kroków to wynik tej gry. Kot stara się uzyskać jak najlepszy wynik, łapacz stara się uzyskać jak najniższy wynik. Średnia suma wszystkich gier, w których uczestniczyłeś, będzie wynikiem twojego zgłoszenia. Istnieją dwa osobne rankingi, jeden dla kota, drugi dla łapaczy.
Kontroler
Dany kontroler jest napisany w Javie. Jako łapacz lub kot, każdy z was musi w pełni zaimplementować klasę Java (istnieją już pewne prymitywne przykłady) i umieścić ją w players
pakiecie (i zaktualizować listę kotów / łapaczy w klasie Controller), ale można także napisać dodatkowe funkcje w tej klasie. Do kontrolera dołączone są dwa robocze przykłady prostych klas cat / catcher.
Pole to tablica 11 x 11
2D int
przechowująca wartości bieżących stanów komórek. Jeśli komórka jest pusta, ma wartość 0
, jeśli jest kot, ma wartość, -1
a jeśli jest wiadro, to jest 1
.
Istnieje kilka podanych funkcji, których możesz użyć: isValidMove()
/ isValidPosition()
służą do sprawdzania, czy twój ruch (kot) / pozycja (łapacz) jest prawidłowy.
Za każdym razem, gdy jest twoja kolej, twoja funkcja takeTurn()
jest wywoływana. Argument zawiera kopię bieżącej siatki i ma metody takie jak read(i,j)
czytanie komórki w (i,j)
, a także isValidMove()/ isValidPosition()
sprawdza poprawność odpowiedzi. To również zarządza zawijaniem topologii toroidalnej, co oznacza, że nawet jeśli siatka ma tylko 11 x 11, nadal możesz uzyskać dostęp do komórki (-5,13).
Metoda powinna zwrócić int
tablicę dwóch elementów, które reprezentują możliwe ruchy. W przypadku kotów {-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}
reprezentują one względną pozycję, w której kot chce iść, a łapacze zwracają bezwzględne współrzędne miejsca, w którym chcą umieścić wiadro {i,j}
.
Jeśli twoja metoda spowoduje nieprawidłowy ruch, Twoje zgłoszenie zostanie zdyskwalifikowane. Ruch uważa się za nieważny, jeśli w miejscu docelowym znajduje się już wiadro lub ruch jest niedozwolony / miejsce docelowe jest już zajęte (jako kot) lub jeśli istnieje już wiadro / kot (jako łapacz). Możesz to wcześniej sprawdzić za pomocą podanych funkcji.
Twoje zgłoszenie powinno działać dość szybko. Jeśli Twoja metoda trwa dłużej niż 200 ms dla każdego kroku, zostanie również zdyskwalifikowana. (Najlepiej znacznie mniej ...)
Programy mogą przechowywać informacje między krokami.
Zgłoszenia
- Możesz przesłać dowolną liczbę zgłoszeń.
- Nie zmieniaj znacząco przesłanych już zgłoszeń.
- Proszę o każde zgłoszenie w nowej odpowiedzi.
- Każde zgłoszenie powinno mieć swoją unikalną nazwę.
- Zgłoszenie powinno składać się z kodu twojej klasy oraz opisu, który mówi nam, jak działa zgłoszenie.
- Możesz napisać wiersz
<!-- language: lang-java -->
przed kodem źródłowym, aby uzyskać automatyczne podświetlanie składni.
Punktacja
Wszystkie koty będą rywalizować ze wszystkimi łapaczami tyle samo razy. Spróbuję często aktualizować bieżące wyniki, zwycięzcy zostaną wyłonieni, gdy aktywność spadnie.
To wyzwanie jest inspirowane starą grą flash
Dzięki @PhiNotPi za testowanie i udzielenie konstruktywnej opinii.
Aktualne wyniki (100 gier na parę)
Name Score Rank Author
RandCatcher 191674 8 flawr
StupidFill 214246 9 flawr
Achilles 76820 6 The E
Agamemnon 74844 5 The E
CloseCatcher 54920 4 randomra
ForwordCatcher 94246 7 MegaTom
Dijkstra 46500 2 TheNumberOne
HexCatcher 48832 3 randomra
ChoiceCatcher 43828 1 randomra
RandCat 77928 7 flawr
StupidRightCat 81794 6 flawr
SpiralCat 93868 5 CoolGuy
StraightCat 82452 9 CoolGuy
FreeCat 106304 3 randomra
RabidCat 77770 8 cain
Dijkstra's Cat 114670 1 TheNumberOne
MaxCat 97768 4 Manu
ChoiceCat 113356 2 randomra
PRINT_STEPS = true
bardziej szczegółowe ustawienia w plikuMyFrame.java
). Potem nagrałem to za pomocą LICEcap i zredagowałem za pomocą GIMP . Jeśli masz dodatkowe pytania, po prostu zapytaj!Odpowiedzi:
Achilles
Achilles nie jest zbyt bystry, ale jest bezwzględnie skuteczny. Najpierw powstrzymuje kota od używania owijania deski, a następnie dzieli deskę na dwie części. Następnie dzieli część deski, na którą kot jest w połowie, dopóki kot nie zostanie uwięziony.
Demonstracja RandCat vs Achilles
źródło
Agamemnon
Agamemnon dzieli obszar kota na pół pionową linią, aż kot ma tylko pasek o szerokości 2, w którym może się poruszać, w którym to momencie uwięził kota.
Agamemnon vs RandCat:
Ten łapacz jest konsekwentnie lepszy niż Achilles i myślę, że jest na tyle inny, że uzasadnia nową odpowiedź.
źródło
HexCatcher
Jeśli łapacz może wprowadzić kota do wnętrza dużego sześciokąta z 3 jednostkowymi bokami, w których narożniki sześciokąta są już zajęte przez wiadra, łapacz może zatrzymać kota w tym obszarze i złapać go. Sześciokąt wygląda następująco:
To właśnie próbuje osiągnąć HexCatcher. Mentalnie układa pole tymi dużymi sześciokątami w taki sposób, że każda komórka narożna jest częścią 3 dużych sześciokątów.
Jeśli istnieje szansa na utrzymanie kota w bieżącym obszarze, łącząc dwa rogi obok kota, bot to zrobi. (Np. Na zdjęciu, jeśli kot ma 7,5, wybieramy 7,6, nawet jeśli tylko komórki 6,6 i 8,5 są jeszcze zajęte.)
Jeśli poprzednie nie jest możliwe, wybieramy zagrać w rogu, który jest częścią obszaru, w którym znajduje się kot. Jeśli wszystkie takie rogi są już wybrane (jak na obrazku), wybieramy komórkę obok kota.
Możliwych jest wiele drobnych ulepszeń, takich jak lepsze radzenie sobie z zawijaniem (układanie się tam psuje) lub optymalne wykonywanie ostatnich kilku ruchów. Mógłbym zrobić niektóre z nich. Jeśli nie jest to dozwolone, dołączę go (poza konkurencją) dla zainteresowanych.
DijkstrasCat vs HexCatcher:
źródło
CloseCatcher
Wybiera jedną z pozycji, w której kot mógłby przejść w następnym kroku. Wybiera tę, która po 3 krokach dałaby kotom możliwie najwięcej ścieżek, gdyby się tam poruszał, a pole nie zmieniłoby się.
Kod jest prawie identyczny z moim wpisem Cat, FreeCat , który wybiera kierunek w bardzo podobny sposób.
SpiralCat vs CloseCatcher:
źródło
Dijkstra
Nie bardzo lubi koty (:
v{ >
FreeCat vs Dijkstra
(wymaga aktualizacji):Jak próbuje złapać kota:
Analizuje wszystkie kwadraty planszy i próbuje znaleźć kwadrat, który minimalizuje otwartość planszy i maksymalizuje, jak bardzo plansza jest wyciągnięta; w stosunku do kota. Otwartość i surowość planszy są obliczane przy użyciu modyfikacji jego słynnego algorytmu .
Otwartość:
Otwartość deski względem pozycji jest liczbą osiągalnych pozycji z tej pozycji.
Surowość:
Sztywność deski względem pozycji jest sumą odległości między dostępnymi pozycjami a pozycją.
Z ostatnią aktualizacją:
Teraz jest znacznie lepszy w łapaniu
FreeCat i własnego kotawszystkich kotów.Niestety, jest również znacznie gorszy w łapaniu szalonych, niechętnych do współpracy kotów. Można go poprawić, wykrywając, czy kot jest jednym z szalonych, a następnie działając jako CloseCatcher.Naprawiono błąd.
źródło
error: cannot infer type arguments for PriorityQueue<>
w tej liniiPriorityQueue<int[]> open = new PriorityQueue<>(new Comparator<int[]>() {
.int[]
między dwoma pustymi diamentami poPriorityQueue
.ForwordCatcher
Umieszcza wiadro przed kotem, a jeśli zostanie zabrane, umieszcza się z tyłu.
RabidCat vs ForwordCatcher:
źródło
ChoiceCatcher
Używa tego samego mechanizmu oceniania, co mój wpis ChoiceCat . Istnieje niewielka modyfikacja, która pomaga wybrać odpowiednie komórki na pierwszych kilku krokach, ponieważ ChoiceCat nie dba o kilka pierwszych segmentów, ponieważ nie widzi ich jako zagrożenia.
ChoiceCatcher wydaje się osiągać znacznie lepsze wyniki niż obecne łapacze.
ChoiceCat vs ChoiceCatcher:
źródło
RandCatcher
Zostało to wykonane tylko do testowania kontrolera i po prostu losowo umieszcza segmenty (bardzo nieefektywnie).
źródło
StupidFillCatcher
Zostało to wykonane tylko do testowania kontrolera. Po prostu wypełnia kolumnę po kolumnie, aż kot zostanie złapany.
źródło