Kierowca testowy • Dyskusja o wyzwaniu • Prześlij poszukiwacza przygód
( Źródło obrazu )
Kilku rywalizujących poszukiwaczy przygód napada na ruiny w poszukiwaniu skarbu, ale mogą nosić tylko tyle rzeczy naraz i mają swoje granice wytrzymałości. Chcą zdobyć najcenniejszy skarb i wydostać się, zanim staną się zbyt zmęczeni, aby kontynuować. Próbują stać się jak najbogatszymi ze swoich grabieży shenaniganów.
Rozgrywka
Każdy poszukiwacz przygód zaczyna w pierwszym pokoju lochu z 1000 punktami wytrzymałości i 50 kg miejsca w plecaku.
Gra działa w systemie turowym, a wszyscy gracze rozpatrują swoje tury jednocześnie. W każdej turze możesz wykonać jedną z następujących czynności:
- Przejdź do następnego pokoju.
- Przejdź do poprzedniego pokoju.
- Licytuj wytrzymałość, aby zdobyć skarb.
- Upuść skarb.
Przemieszczanie się między pokojami wymaga 10 punktów wytrzymałości plus 1 za każde 5 kg aktualnie w plecaku, zaokrąglone w górę. Na przykład poszukiwacz przygód niosący 3 kg skarbu wymaga 11 punktów wytrzymałości, a jeden niosący 47 kg wymaga 20 punktów wytrzymałości.
Upuszczenie skarbu wymaga 1 wytrzymałości bez względu na upuszczony skarb.
Po wyjściu z ruin gracz nie będzie podejmował więcej tur.
Jeśli gracz nie może wykonać żadnej z tych akcji (z powodu braku wytrzymałości lub braku skarbów), jego poszukiwacz przygód umiera z wyczerpania, rozlewając posiadany skarb do aktualnie zajmowanego pokoju. Podobnie, jeśli gracz podejmie próbę wykonania nieprawidłowej akcji, jego poszukiwacz przygód zostanie zamiast tego zabity przez pułapkę, co spowoduje takie samo rozlanie skarbu.
Licytacja
Minimalna oferta dla skarbu to 1 wytrzymałość na 1 kg ważonego skarbu. Możesz także licytować dodatkowe punkty wytrzymałości, aby zwiększyć prawdopodobieństwo zdobycia skarbu. Wytrzymałość, która została licytowana, jest zużywana bez względu na wynik.
W przypadku, gdy wielu graczy licytuje ten sam skarb, gracz, który licytuje najwięcej, otrzymuje skarb. Jeśli więcej niż jeden gracz złoży najwyższą ofertę, żaden z nich nie otrzyma skarbu.
Warunek wygranej
Gracz z największą całkowitą wartością skarbów jest zwycięzcą. W mało prawdopodobnym przypadku remisu, krawaty przechodzą do najmniejszej całkowitej wagi, następnie najmniejszej liczby skarbów, a następnie wartości najcenniejszego skarbu, drugiego najcenniejszego, trzeciego ... aż do zerwania remisu. W niemal niemożliwym przypadku, gdy w tym momencie nadal jest remis, kierowca testowy mówi „spieprzyć”, a zwycięzca zostaje w ten sposób ustalony arbitralnie.
W kontekście turnieju gracze zostaną sklasyfikowani z pierwszym miejscem, które otrzyma 10 punktów, drugim miejscem z 9 punktami, trzecim miejscem z 8 punktami itp., Z martwymi graczami i poszukiwaczami przygód bez skarbów, którzy zdobędą 0 punktów.
O ruinach
- Każdy pokój początkowo zawiera między i skarbów. (Gdzie jest numerem pokoju)
- Istnieje dowolnie wiele pokoi, ograniczonych jedynie wytrzymałością poszukiwaczy przygód i chęcią eksploracji.
- Każdy skarb będzie miał wartość pieniężną (w pełnych $) i wagę (w pełnych kg).
- Skarby wydają się być bardziej cenne i obfite, gdy schodzisz głębiej w ruiny.
- Szczegółowe formuły generowania skarbów są następujące: (używając notacji dla rzutów kostką)
- Masa jest najpierw generowana przy użyciu wzoru (minimum 1)
- Wartość skarbu jest następnie generowana przez (gdzie jest numerem pokoju, a jest wagą)
Informacje widoczne dla graczy
W każdej turze gracze otrzymują następujące informacje:
- Numer pokoju, w którym aktualnie przebywają. Jest to indeks 1, więc koncepcyjnie wyjście znajduje się w „pokoju 0”
- Lista skarbów znajdujących się obecnie w pokoju
- Lista innych graczy, którzy również znajdują się obecnie w pokoju.
- Twój aktualny spis skarbów
- Twój obecny poziom wytrzymałości
Kodowanie
Sterownik testowy można znaleźć tutaj .
Powinieneś zaimplementować podklasę tej Adventurer
klasy:
class Adventurer:
def __init__(self, name, random):
self.name = name
self.random = random
def get_action(self, state):
raise NotImplementedError()
def enter_ruins(self):
pass
Musisz tylko zastąpić get_action
metodę. enter_ruins
jest uruchamiany przed rozpoczęciem gry i jest szansą na przygotowanie czegokolwiek, co chcesz mieć w grze. Nie musisz przesłonić __init__
i naprawdę nie powinieneś . Jeśli Twoje __init__
awarie zostaną zdyskwalifikowane.
get_action
otrzymuje pojedynczy argument namedtuple
zawierający następujące pola (w tej kolejności, jeśli wolisz destrukcję):
room
: numer pokoju, w którym aktualnie się znajdujesztreasures
: lista skarbów w pokojuplayers
: lista innych graczy w pokoju. W ten sposób otrzymujesz tylko nazwę gracza, więc nie wiesz, który bot kontroluje go, ani jaki jest jego ekwipunek / wytrzymałość.inventory
: lista skarbów w twoim plecakustamina
: twój obecny poziom wytrzymałości
Ten obiekt zapewnia dodatkowo dwie właściwości narzędzia:
carry_weight
: całkowita waga wszystkich skarbów, które nosisztotal_value
: całkowita wartość wszystkich skarbów, które nosisz
Te treasures
i inventory
wykazy zawierają namedtuple
S z tych atrybutów:
name
: nazwa skarbu (do celów kosmetycznych)value
: wartość pieniężna skarbu w $.weight
: waga skarbu w kg
get_action
powinien zwrócić jedną z następujących wartości / wzorców:
'next'
lub'previous'
przejść do następnych / poprzednich pokoi'take', <treasure index>, <bid>
(tak, jako krotka, choć każda sekwencja również technicznie będzie działała), aby licytować skarb pod danym indeksem na liście skarbów w pokoju. Oba argumenty powinny być liczbami całkowitymi. Pływaki będą zaokrąglane w dół.'drop', <inventory index>
upuścić przenoszony skarb znaleziony przy danym indeksie. Indeks powinien (naturalnie) być liczbą całkowitą.
Inne ograniczenia
- Możesz użyć tylko przypadkowej instancji podanej podczas inicjalizacji dla pseudolosowości.
- Cokolwiek innego, co mogłoby wprowadzić behawioralny niedeterminizm, jest niedozwolone. Chodzi tutaj o to, aby boty zachowywały się identycznie, gdy otrzymają to samo ziarno, aby pomóc w testowaniu nowych botów (i potencjalnie błędów w sterowniku testowym). Tylko promieniowanie kosmiczne powinno powodować wszelkie odchylenia / niedeterminizm.
- Należy pamiętać, że kody skrótu są losowe w Pythonie 3, więc używanie
hash
do podejmowania jakichkolwiek decyzji jest niedozwolone.dict
s są w porządku, nawet jeśli używamy kolejności iteracji dla decyzji, ponieważ kolejność jest gwarantowana spójna od Pythona 3.6.
- Nie możesz ominąć sterownika testowego za pomocą
ctypes
hacków lubinspect
stosu voodoo (lub innej metody). Istnieje kilka imponująco przerażających rzeczy, które możesz zrobić z tymi modułami. Proszę nie.- Każdy bot jest dobrze izolowany w piaskownicy dzięki obronnym kopiom i naturalnej niezmienności
namedtuple
s, ale istnieją pewne nie do naprawienia luki / exploity. - Inne funkcje
inspect
ictypes
mogą być używane, o ile żadne z nich nie jest używane do obchodzenia funkcji kontrolera. - Żadna metoda przechwytywania instancji innych botów w bieżącej grze jest niedozwolona.
- Każdy bot jest dobrze izolowany w piaskownicy dzięki obronnym kopiom i naturalnej niezmienności
- Boty powinny działać solo i nie mogą w żaden sposób koordynować się z innymi botami w jakimkolwiek celu. Obejmuje to tworzenie dwóch botów o różnych celach, z których jeden poświęca się dla sukcesu drugiego. Gdy jest więcej niż 10 konkurentów, tak naprawdę nie ma gwarancji, że oba boty będą w tej samej grze, a nazwy poszukiwaczy przygód nie dadzą żadnych wskazówek co do klasy bota, więc tego typu strategie są ograniczone.
- Obecnie nie ma ścisłego ograniczenia czasu wykonania, jednak zastrzegam sobie prawo do ograniczenia go w przyszłości, jeśli turnieje zaczną trwać zbyt długo. Bądź rozsądny i staraj się utrzymywać przetwarzanie tury poniżej 100 ms , ponieważ nie przewiduję potrzeby ograniczenia go poniżej tego progu. (Turnieje potrwają około 2 godzin, jeśli wszystkie boty zajmą około 100 ms na turę.)
- Twoja klasa botów musi mieć unikalną nazwę spośród wszystkich zgłoszeń.
- Możesz nic nie pamiętać między grami. (Możesz jednak pamiętać rzeczy między turami )
- Nie edytuj sys.modules. Wszystko poza zmiennymi instancji należy traktować jako stałą.
- Nie możesz modyfikować kodu żadnego bota programowo, w tym własnego.
- Obejmuje to usunięcie i przywrócenie kodu. Ma to na celu usprawnienie debugowania i turniejów.
- Każdy kod powodujący awarię kontrolera zostanie natychmiast zdyskwalifikowany. Chociaż wychwyconych zostanie większość wyjątków, niektóre z nich mogą się prześlizgnąć, a segfaultów nie da się złapać. (Tak, możesz segfault w Pythonie dzięki
ctypes
)
Zgłoszenia
Aby ułatwić usuwanie odpowiedzi, wskaż nazwę bota u góry odpowiedzi za pomocą a #Header1
i upewnij się, że twoja odpowiedź zawiera co najmniej jeden blok kodu (użyty zostanie tylko pierwszy blok w odpowiedzi). Nie musisz dołączać żadnych importów ani dokumentów, ponieważ zostaną one automatycznie dodane przez skrobak.
Będę bardziej skłonny głosować nad odpowiedziami szczegółowymi i zrozumiałymi wyjaśnieniami. Inni mogą zachowywać się tak samo.
Z grubsza mówiąc, twoja odpowiedź powinna być sformatowana mniej więcej tak:
# Name of Bot
Optional blurb
#imports go here
class BotName(Adventurer):
#implementation
Explanation of bot algorithm, credits, etc...
(renderowane jako)
Nazwa bota
Opcjonalny napis
#imports go here class BotName(Adventurer): #implementation
Objaśnienie algorytmu bota, kredytów itp.
Lokalne uruchamianie sterownika testowego
Będziesz potrzebował Pythona w wersji 3.7+ i zalecam także instalację tabulate
za pomocą pip. Skrobanie tej strony w celu przesłania dodatkowo wymaga lxml
i requests
. Aby uzyskać najlepsze wyniki, należy również użyć terminala z obsługą znaków zmiany koloru ANSI. Informacje na temat konfiguracji w systemie Windows 10 można znaleźć tutaj .
Dodaj bota do pliku w podkatalogu w tym samym katalogu co ruins.py
( ruins_bots
domyślnie) i pamiętaj o dodaniu from __main__ import Adventurer
go na górze modułu. Jest to dodawane do modułów, gdy skrobak pobiera twoje zgłoszenie, i chociaż jest zdecydowanie zhackowane, jest to najprostszy sposób na upewnienie się, że bot ma właściwy dostęp Adventurer
.
Wszystkie boty w tym katalogu będą ładowane dynamicznie w czasie wykonywania, więc dalsze zmiany nie są konieczne.
Zawody
Zwycięzca zostanie wyłoniony w serii gier z maksymalnie 10 botami w każdej grze. Jeśli zgłoszeń jest więcej niż 10, 10 najlepszych botów zostanie określonych poprzez systematyczne dzielenie ich na grupy po 10, aż każdy bot rozegra (dokładnie) 20 gier. 10 najlepszych botów zostanie wybranych z tej grupy z wynikami resetowania i będzie grać w gry, dopóki bot z pierwszego miejsca nie osiągnie 50-punktowej przewagi nad botem z drugiego miejsca lub do momentu rozegrania 500 gier.
Dopóki nie będzie co najmniej 10 zgłoszeń, puste miejsca zostaną wypełnione „Pijakami”, które wędrują losowo przez ruiny i zabierają (a czasami upuszczają) losowe skarby, dopóki nie wyczerpią się ich wytrzymałość i nie będą musiały płynąć do wyjścia.
Turnieje będą uruchamiane co tydzień, jeśli pojawią się nowe zgłoszenia. To jest otwarte wyzwanie KOTH bez określonej daty zakończenia.
Tabela liderów
Z biegu 4 maja 2019 o 16:25 MDT: (2019-05-04 4:25 -6: 00)
Seed: K48XMESC
Bot Class | Score | Mean Score
--------------+---------+--------------
BountyHunter | 898 | 7.301
Scoundrel | 847 | 6.886
Accountant | 773 | 6.285
Ponderer | 730 | 5.935
Artyventurer | 707 | 5.748
PlanAhead | 698 | 5.675
Sprinter | 683 | 5.553
Accomodator | 661 | 5.374
Memorizer | 459 | 3.732
Backwards | 296 | 2.407
Aktualizacja - 15 kwietnia: kilka aktualizacji / objaśnień do reguł
Aktualizacja - 17 kwietnia: zakaz kilku ważnych przypadków nikczemnych działań, takich jak modyfikowanie kodu innych botów.
Aktualizacja - 4 maja: Nagroda przyznana Sleafarowi za absolutne zniszczenie wstecz. Gratulacje!
pip
zainstalowany i włączony PATH
(co jest domyślne w przypadku nowszych instalacji AFAIK), to z systemu Windows można uruchomić pip install modulename
w wierszu polecenia. W innych okolicznościach (o których nie wiem) przejdź do pip , wyszukaj potrzebny moduł i wybierz opcję.