Konkurs trwale otwarty - zaktualizowany 10 sierpnia 2017 r
Mimo że 5 czerwca 2017 roku ogłosiłem zwycięzcę (który zostanie zachowany jako najlepsza odpowiedź), będę przeglądał nowe boty i aktualizował wyniki.
Wyniki z 5 czerwca
Gratulacje dla użytkownika 1502040
Ponieważ nie ma remisów, pokazuję tylko% wygranych meczów.
Statistician2
- 95,7%
Fitter
- 89,1%
Nash
- 83,9%
Weigher
- 79,9%
ExpectedBayes
- 76,4%
AntiRepeater
- 72,1%
Yggdrasil
- 65,0%
AntiGreedy
- 64,1%
Reactor
- 59,9%
NotHungry
- 57,3%
NashBot
- 55,1%
Blodsocer
- 48,6%
BestOfBothWorlds
- 48,4%
GoodWinning
- 43,9%
Rockstar
- 40,5%
ArtsyChild
- 40,4%
Assassin
- 38,1 %
WeightedRandom
- 37,7%
Ensemble
- 37,4%
UseOpponents
- 36,4%
GreedyPsychologist
- 36,3%
TheMessenger
- 33,9%
Copycat
- 31,4%
Greedy
- 28,3%
SomewhatHungry
- 27,6%
AntiAntiGreedy
- 21,0%
Cycler
- 20,3%
Swap
- 19,8%
RandomBot
- 16,2%
Utworzyłem Arkusz Google z siatką wyników każdego parowania: https://docs.google.com/spreadsheets/d/1KrMvcvWMkK-h1Ee50w0gWLh_L6rCFOgLhTN_QlEXHyk/edit?usp=sharing
Dzięki dylematowi Petri mogłem poradzić sobie z tym Królem Wzgórza.
Gra
Gra jest prosta „Rock-Paper-Scissors” z niespodzianką: Punkty zdobywane z każdym wzrostem zwycięstwa podczas meczu (twoje R, P lub S są ładowane).
- Paper wygrywa Rock
- Nożyczki wygrywają papier
- Rock wygrywa nożyczkami
Zwycięzca otrzymuje tyle punktów, ile obciążenia w swojej grze.
Przegrany zwiększa o 1 obciążenie swojej gry.
W przypadku remisu każdy gracz zwiększa obciążenie swojej gry o 0,5.
Po 100 grach wygrywa ten, który ma więcej punktów.
np .: P1 ma obciążenia [10,11,12] (kamień, papier, nożyczki) i P2 [7,8,9]. P1 gra R, P2 gra P. P2 wygrywa i otrzymuje 8 punktów. Obciążenia P1 stają się [11,11,12], obciążenia P2 pozostają takie same.
Specyfikacja wyzwania
Twój program musi być napisany w języku Python (przepraszam, nie wiem, jak inaczej go obsłużyć). Masz utworzyć funkcję, która będzie traktować każdą z tych zmiennych jako argument przy każdym wykonaniu:
my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history
points
- Aktualne punkty (twoje i twojego przeciwnika)
loaded
- Tablica z ładunkami (w kolejności RPS) (twoja i twój przeciwnik)
history
- Łańcuch ze wszystkimi zagraniami, ostatnia postać to ostatnia gra (twoja i twój przeciwnik)
Musisz wrócić "R"
, "P"
albo "S"
. Jeśli zwrócisz coś innego, będzie to automatyczna przegrana meczu.
Zasady
Nie można zmieniać wbudowanych funkcji.
Testowanie
Będę na bieżąco aktualizować Gita za pomocą kodu i wszystkich botów kompilujących: https://github.com/Masclins/LoadedRPS
Osądzać
Zwycięzca zostanie wyłoniony przez wybór osoby, która wygra najwięcej meczów po 1000 pełnych rundach. Remisy zostaną zerwane przez remisy. Rozgrywanych jest 1000 meczów, a nie jeden, ponieważ spodziewam się dużo losowości. W ten sposób losowość byłaby mniej istotna.
Możesz przesłać do 5 botów.
Konkurs kończy się 4 lipca (to będzie ostatni dzień, w którym przyjmę odpowiedź), a 5 lipca opublikuję ostatnie stadiony (może postaram się zamieścić awans).
Ponieważ jest to mój pierwszy KOTH, jestem w 100% otwarty na zmiany w celu ulepszeń, takich jak liczba meczów rozegranych z każdym botem.
Edytowano do 1000 dopasowań, ponieważ widzę, że naprawdę wiąże się to z przypadkowością.
źródło
runcode
ibots
)?Odpowiedzi:
Statystyka(już nie gra)Przełącza między kilkoma prostymi strategiami opartymi na oczekiwanej wydajności w przeszłości
Statystyka 2
Nash
Oblicza przybliżoną równowagę Nasha na podstawie spadku gradientu.
źródło
Waga
Straciłem rozumowanie podczas eksperymentowania z kodem, ale podstawową ideą jest oszacowanie prawdopodobieństwa ruchu przeciwnika przez ostatnie 3 ruchy przy użyciu niektórych wag i pomnożenie ich przez inną wagę, która zależy od obciążeń. Myślałem, że też mogę jakoś użyć
my_loaded
, ale nie mogłem zdecydować, jak to zrobić, więc pominęłem.szatan
Prawdopodobnie zostanie zdyskwalifikowany, ponieważ jest to rodzaj oszustwa i przyjmuje pewne założenia dotyczące funkcji testowania (musi mieć funkcję przeciwnika w zmiennej na ramce stosu), ale technicznie nie łamie żadnych obecnych reguł - nie przedefiniuj lub przepisz wszystko. Po prostu używa czarnej magii, aby wykonać funkcję przeciwnika, aby zobaczyć, co zrobiła / zrobi tura. Nie radzi sobie z przypadkowością, ale deterministyczne boty nie mają szans na pokonanie Szatana.
źródło
my_loaded
możesz dodać wagę, która ceni ruch, który straciłby w stosunku do twojego ostatniego ruchu (ruchów). To tak, jakby zakładać, że przeciwnik zrobi coś podobnego do tego, co zrobiłeś, a zatem karać go za to, że będziesz nadal grał tak samo. Coś w stylu:for i, m in enumerate(reversed(my_history[-3:])): sc[(idx[m]+1)%3] += (K / (1 + i))
Monter
Ten bot ulepsza Wzór i łączy go z Ekonomistą (Wzór i Ekonomista nie będą już brać udziału)
Ulepszenie Wzorca polega na tym, że Bot szuka teraz dwóch dwóch rodzajów wzorów: Przeciwnik reagujący na jego ostatnią grę i przeciwnik reagujący na moją ostatnią grę. Następnie ocenia obie prognozy, aby zastosować tę, która najlepiej pasuje.
Na podstawie tego wzoru Bot ma teraz prawdopodobieństwo dla R, P i S. Biorąc to pod uwagę i oczekiwaną wartość każdej gry (tak jak zrobił to Ekonomista), Bot gra tę, która daje największą wartość.
Oto dwa stare kody
Wzór(nie gra już)Wzór próbuje znaleźć wzory na swoim przeciwniku. Wygląda na to, w co grał przeciwnik po ostatniej grze, którą wykonał (przykładając większą wagę do ostatnich gier). Dzięki temu odgaduje, co będzie grał przeciwnik, i gra przeciw temu.
Ekonomista(już nie gra)The Economist wykonuje następujące czynności: Odgaduje prawdopodobieństwo każdej gry przeciwnika, obserwując, w co grał w ostatnich 9 turach. Na tej podstawie oblicza oczekiwaną korzyść z każdej gry i idzie z tą, która ma najlepszą oczekiwaną wartość.
źródło
Yggdrasil
Nazywa się to „Yggdrasil”, ponieważ patrzy w przyszłość w drzewie gry. Ten bot nie wykonuje żadnej prognozy przeciwnika, po prostu stara się utrzymać przewagę statystyczną, jeśli ją otrzyma (poprzez zrównoważenie obecnych i przyszłych zysków). Oblicza w przybliżeniu idealną strategię mieszaną i zwraca ruch wybrany losowo z tymi wagami. Gdyby ten bot był doskonały (co nie jest, ponieważ funkcja wyceny stanu jest dość zła i nie wygląda daleko w przyszłość), nie byłoby możliwe pokonanie tego bota przez ponad 50% czasu. Nie wiem, jak dobrze ten bot poradzi sobie w praktyce.
źródło
Anti-Repeater
Podnosi papier w pierwszej turze, po czym zwraca to, co bije to, co przeciwnik zrobił najwięcej, wybierając papier w przypadku remisu.
Copycat
Wystarczy skopiować ostatni ruch przeciwnika.
Anti-Anti-Greedy
Wybiera cokolwiek, co przegrywa z najcięższym wyborem przeciwnika.
Nieco głodny
źródło
Posłaniec
Gwiazda rocka
Morderca
Wyjaśnienie
Teraz możesz myśleć, że te boty są całkowicie głupie.
nie do końca prawdą, są one w rzeczywistości oparte na pomyśle, zebranie ogromnej premii, a wróg popełnia błąd i dostaje się z nim do ściany.
teraz te boty grają bardzo podobnie do chciwych, są jednak prostsze i nie wybierają losowo, dopóki nie obciążą jednej broni, trzymają się wybranej broni.
Kolejna rzecz do zapamiętania: każdy z nich pobije chciwość mniej więcej w połowie czasu, losując jedną trzecią czasu i tracąc jedną szóstą czasu. kiedy wygrają, będą często wygrywać. dlaczego to?
Chciwy, dopóki nie przegra rundy, losowo wybierze broń. oznacza to, że jeśli nie wygra rundy, ponownie wybierze broń losowo, co może być znowu zwycięską. jeśli chciwy ciągnie lub przegrywa, trzyma się tej broni. jeśli chciwy wygrywa co najmniej jedną rundę, to wybiera tę samą broń co bot, chciwy wygrywa. jeśli chciwy wybierze przegrywającą broń w pewnym momencie, nasz bot wygra, ponieważ obciążenie naszej broni byłoby wyższe niż wynik chciwości.
Zakładając, że zachłanność nie zawsze wybiera zwycięską broń przypadkowo, oznacza to, że szanse są następujące:
1/3: {1/2 wygranej (w sumie 1/6). 1/2 straty (w sumie 1/6). }
1/3 losowania
1/3 wygranej
więc: 1/3 szansy na remis, 1/6 szansy na przegraną, 1/2 szansy na wygraną.
prawdopodobnie oznacza to, że musisz zrobić wiele gier w wielu rundach
mają one przede wszystkim na celu sprostanie wyzwaniu
źródło
Reaktor
Sprawia, że gra wygrałaby poprzednią rundę.
źródło
opp_history[len(opp_history)-1]
zopp_history[-1]
.Artsy Child
Ten bot zachowuje się jak dziecko bawiące się sztuką i rzemiosłem, zacznie od papieru i losowo użyje papieru lub nożyczek, ale nie będzie używać nożyczek po kamieniu lub nożyczkach, ponieważ musi używać nożyczek na papierze. Rzuci kamieniem w każdego, kto rzuci w nią kamieniem.
źródło
Oto trzy boty, które zbudowałem do testowania:
RandomBot
Chciwy
Po prostu wybiera najbardziej obciążoną opcję.
Antykoncepcja
Zakłada, że przeciwnik zagra chciwy i gra zwycięską alternatywą.
źródło
Nie głodny
Jest to dosłownie odwrotność Chciwego, wybiera opcję najniższych dostępnych punktów.
źródło
Użyj ulubionego przeciwnika
W pierwszej turze wybiera losowy przedmiot. Co drugą turę używa najczęstszego wyboru przeciwnika. Jeśli jest remis, domyślnie wybierany jest najwcześniejszy najczęściej wybierany wybór.
// Ukradłem stąd kod
Zwycięstwo jest dobre
Zwraca wybór zwycięzcy poprzedniej rundy. Jeśli poprzednia runda była remisowa, rekurencyjnie sprawdza rundę wcześniej. Jeśli były to tylko remisy lub pierwsza runda, zwraca losowy wybór.
źródło
Najlepsze z obu światów
Ten bot w zasadzie łączy Anti-Greedy i Greedy (stąd nazwa).
źródło
find
jest na smyczki.my_loaded
iopp_loaded
obie są listami.index
powinno być dobre dla tego, czego chcesz.NashBot
Losowo wybiera pomiędzy trzema opcjami w taki sposób, że przeciwnik statystycznie nie ma preferencji między ruchami w odniesieniu do tego, ile zdobędzie; innymi słowy, zarówno Chciwi, jak i Niegłodni powinni mieć taki sam średni oczekiwany wynik przeciwko niemu.
źródło
Oczekiwany
Edycja: Zaktualizowany ranking
To jest nowy najwyższy ranking po uwzględnieniu Expectedbayes:
Objaśnienia
(Uwaga: przesłanie 05.06.2017)
Ten bot próbuje zmaksymalizować oczekiwaną wartość następnego ruchu poprzez:
Prawdopodobieństwa są aktualizowane co dziesięć ruchów. Liczba przeszłych ruchów użytych do obliczenia prawdopodobieństw została ustawiona na 10 dla każdego bota (więc ogółem 20 funkcji). Prawdopodobnie jest to za dużo danych, ale nie próbowałem dalej sprawdzać.
Opiera się na bibliotece scikit do obliczania prawdopodobieństwa ruchu przeciwnika (mówię to w przypadku, gdy źle przeczytałem zasady i nie było to dozwolone).
Z łatwością wygrywa z botami, które zawsze dokonują tego samego wyboru. Zaskakujące jest to, że jest dość skuteczny przeciwko losowemu botowi ze wskaźnikiem wygranych 93% (uważam, że wynika to z faktu, że ogranicza liczbę punktów, które może zdobyć jego przeciwnik, jednocześnie maksymalizując własną liczbę możliwych punktów w każdej rundzie).
Zrobiłem szybką próbę z turą 100 i tylko ograniczoną liczbą botów, i oto, co otrzymałem z wynik_zrozumienia:
Co nie jest takie złe!
źródło
Cycler
0
źródło
Ensemble
Kilka konkurencyjnych algorytmów głosuje na najlepsze rozwiązanie.
Zamiana
Wykonuje losowy ruch, ale zrobił to bez powtarzania ostatniego ruchu.
źródło
blodsocer
towarzystwo
Naprawiłem to, więc mam nadzieję, że teraz powinno działać
Znowu coś pomieszałem, więc usunąłem i usunąłem. Robię dużo bałaganu.
źródło
if opp_history[1] == "S": return "R" elif opp_history[1] == "R": return "R" else: return "P"
jaki to rodzaj towarzystwa?elif min(opp_history.count(i) for i in "RPS")/max(opp_history.count(i) for i in "RPS") >0.8 and len(my_history)>30:
"RPS"[my_loaded.index(max(my_loaded))+len(my_history)%2]
ale wygląda to poza zasięgiem (podobnie jak dalsze linie).Ważony losowo
Podobnie jak RandomBot, ale wybiera tylko 2, aby rzucać za każdym razem, gdy jest wywoływany. Czasami pokona Rockstar lub Assassin, ale zwiększy wyniki drugiego (np. Jeśli pokonuje Rockstar, daje Assassinowi premię punktową).
źródło
Chciwy psycholog
Nazwano to, ponieważ domyślnie jest chciwe, ale jeśli nie może się zdecydować, przeciwstawia się temu, co zrobiłby przeciwnik, gdyby zastosował chciwą strategię. Jeśli nadal nie może się zdecydować, idzie losowo.
źródło