tło
Gra Morra jest prostą grą. W „oryginalnej” wersji kilku graczy jednocześnie wyrzuca z rąk liczbę 0-5, zgadując całkowitą sumę rąk wszystkich. Wersja, której użyję tutaj, została zmodyfikowana w celu zwiększenia potencjału nietrywialnej strategii i została opisana poniżej:
- Jest dwóch graczy.
- Podobnie jak w papierowych nożyczkach, gracze poruszają się jednocześnie.
- W każdej turze każdy gracz wybiera liczbę 0-5, a także zgaduje wybór przeciwnika 0-5. Oznacza to, że w każdej turze wyprowadzane są dwie liczby. Aby wyjaśnić, dane wyjściowe obu liczb powinny zawierać się w przedziale 0–5 włącznie.
- Jeśli poprawnie odgadniesz wybór przeciwnika, ale przeciwnik nie zgadł poprawnie, wygrywasz określoną liczbę punktów równą sumie dwóch rozegranych liczb. Na przykład, jeśli rozegrane liczby to 3 i 5, prawidłowe odgadnięcie byłoby warte 8 punktów.
- Jeśli obaj lub żaden z graczy nie zgadnie poprawnie, nie przyznaje się punktów.
- Osoba z największą liczbą punktów po 1000 rundach wygrywa tę grę.
Turniej
Turniej zostanie przeprowadzony w stylu robota okrągłego i będzie prowadzony przez utworzenie każdej możliwej pary zawodnika. Za każde zwycięstwo uczestnik otrzymuje 2 punkty zwycięstwa. Każdy remis daje 1 punkt zwycięstwa. Przegrana nie daje żadnych punktów zwycięstwa.
Intuicyjnie zwycięzcą turnieju będzie zawodnik z największą liczbą punktów zwycięstwa nad innymi.
Jak wejść
Będą dwie metody zgłaszania botów do rywalizacji. Pierwszą i bardzo preferowaną metodą jest implementacja interfejsu Java dostarczanego przez kontroler. Drugą metodą jest napisanie niezależnego programu.
Najpierw omówmy metodę Java. Interfejs trzeba będzie wdrożyć to Player
i to definiuje dwie metody: public String getName()
identyfikuje bot, i public int[] getMove(String[] args)
trwa args
jako tablica sześciu strun, mychoices myguesses myscore opponentchoices opponentguesses opponentscore
. Przykład jest następujący:
042 045 0 324 432 6
Oznacza to, że wybrałem 0 w pierwszej rundzie i zgadywałem, że mój przeciwnik rzuci 0. Mój przeciwnik rzucił 3 i domyśliłem się, że rzuci 4. W trzeciej rundzie mój przeciwnik poprawnie zgadywał, że rzuciłem 2, co oznacza, że zyskuje 2 + 4 = 6 punktów.
Twoja metoda zwróci tablicę dwóch liczb całkowitych, które są odpowiednio twoim wyborem i zgadnij. Przykładem jest {4,2}
wybór 4 i zgadywanie 2.
Oto przykład kompletnego bota Java napisanego jako metoda. Jeśli chcesz, Twoje zgłoszenie musi zawierać tylko to, co dzieje się w getMove
metodzie.
import java.util.Random;
/**
* A simple example Morra bot to get you started.
*/
public class ExampleBot implements Player
{
public String getName()
{
return "ExampleBot";
}
public int[] getMove(String [] args)
{
//easiest way I know to break down to create a move history
//(just contains their throw history)
char[] theirThrowsC = args[3].toCharArray();
int[] theirThrows = new int[theirThrowsC.length];
for(int i = 0; i < theirThrowsC.length; i++)
{
theirThrows[i] = Integer.parseInt(Character.toString(theirThrowsC[i]));
}
//get my score
int myScore = Integer.parseInt(args[2]);
Random r = new Random();
int guess = r.nextInt(6);
if(theirThrows.length > 0)
{
guess = theirThrows[theirThrows.length-1];
}
//throws a random number, guesses what they threw last
return new int[] {r.nextInt(6),guess};
}
public static int otherMethod(int example) //you can write additional static methods
{
return 0;
}
}
Jako niezależny program
Obecnie mam ograniczone wsparcie dla dodatkowych języków. Poza Javą mogę akceptować programy napisane w Python 3.4, Perl 5 lub Ruby 2.1.5. Jeśli istnieje język, który wydaje się być potrzebny kilku osobom, dołożę wszelkich starań, aby go dodać.
Dane wejściowe do programu będą argumentami w wierszu poleceń. Może to wyglądać tak:
perl awesomebot.plx 042 045 0 324 432 6
Wyjście twojego programu powinno być twoim wyborem, a następnie zgadnięciem, a po każdym spacją.
Podaj w odpowiedzi dokładne polecenie potrzebne do jego uruchomienia. Pamiętaj, że korzystam z systemu Windows 8.1.
Dodatkowe zasady
Saving State and Timeouts
Twój program będzie mógł utworzyć jeden plik tekstowy w katalogu lokalnym, w którym możesz przechowywać informacje. Informacje te będą przechowywane przez cały turniej, ale zostaną później usunięte. Nadaj plikowi nazwę, którą mogę zidentyfikować.
Kod ma limit czasowy 500 milisekund na odpowiedź. Brak odpowiedzi w wyznaczonym terminie (lub udzielenie nieprawidłowego ruchu) spowoduje przepadek tego konkretnego meczu. Zgłoszenia Java mają obecnie pasywny limit czasu (który mogę uaktualnić do aktywnego), podczas gdy zgłoszenia inne niż Java mają aktywny limit czasu, w którym ich proces kończy się po 500 milisekundach.
Więcej zasad składania
- Dozwolone jest wielokrotne przesyłanie, o ile są one zgodne z zasadami i nie tagują zespołu.
- Każdy wpis musi być unikalny. Nie można wykonać dokładnej kopii logiki innego bota w innym języku.
- Boty nie mogą ze sobą wchodzić w interakcje (w celu utworzenia jakiegokolwiek zespołu).
- Nie możesz użyć logiki innych botów wewnątrz bota, aby, powiedzmy, zidentyfikować konkurenta i przewidzieć jego działania. Możesz oczywiście spróbować ustalić strategię przeciwnika.
- Nie próbuj zadzierać z kontrolerem, innymi uczestnikami lub moim komputerem. Nie łącz się z zewnętrznymi źródłami informacji.
Kontroler
Aktualna wersja kontrolera znajduje się tutaj . Jest napisany w Javie 8. Plik „Tournament” jest głównym kontrolerem, który zawiera również listę zawodników (jeśli chcesz organizować własne zawody).
Tabela liderów
Tak naprawdę nie byłem w stanie często aktualizować tabeli wyników. Jestem raczej zajęty w ten weekend. Przez „raczej zajęty” mam na myśli brak dostępu do komputera od 6:30 do 21:30. Oto wyniki po 5 biegach. Bot „Echo” z jakiegoś powodu wciąż przepadał (być może to moja wina, jeszcze nie zbadałem).
170 - Quinn and Valor
158 - Historian
142 - DeltaMax
140 - MorraCowbell
132 - Extrapolator
115 - Rainbolt
102 - Popularity
100 - Interpolator
83 - CounterBot
80 - Basilisk
76 - Erratica
65 - Trendy
63 - Scholar
62 - RandomGuesser
60 - KingFisher
59 - NullifierBot
55 - EvolvedBot
48 - Confused
Kredyt
Ogromne podziękowania dla Rainbolt i Petera Taylora za pomoc w obsłudze kontrolera.
źródło
Odpowiedzi:
Morra Cowbell
Dla każdego, kto szuka znaczenia w nazwie tego bota, nazwa Morra kojarzy mi się z kosmicznym włoskim , więc pomyślałem, że potrzebuję nazwy, która się na nim gra. Inni kandydaci to Morra oszukać ciebie i Morrę za mnie .
Jest to pełna klasa implementująca
Player
interfejs. Objaśnienie poniżej.Wyjaśnienie
Zacząłem od analizy gier z mniejszą liczbą palców. Najprostszy nietrywialny pozwala na wywołania
0
lub1
ma następującą tabelę wypłat (wartości są wypłatą dla gracza rzędowego):(0,0)
Strategia dominuje(0,1)
, więc możemy zmniejszyć tabelęTeraz
(1,0)
strategia jest zdominowana przez(0,1)
, więc możemy jeszcze bardziej zredukować stół doA teraz
(1,1)
jest zdominowany przez(0,1)
, więc kończymyDlatego zawsze granie
(0,1)
jest równowagą Nasha. Ale ciekawe jest to, że nie jest to jedyny. To symetryczne gry sumie zerowej, tak więc oczekiwano wypłata jest 0, a każda mieszana strategii łączenia(0,1)
i(1,0)
w której(0,1)
jest zbierany w co najmniej 50% czasu, to osiąga wypłat. Mamy więc jednowymiarową przestrzeń równowagi Nasha.Wydaje się, że tak jest, chociaż nie udowodniłem tego, że
n
-wysyłka Morra ma wielowymiarowy politopn
równowag Nasha, które są mieszanymi strategiami międzyn+1
(pick, guess)
parami, dla którychpick + guess = n
.Liczby magiczne w powyższym kodzie kodują 32 wierzchołki 5-wymiarowego politopu równowag Nasha. Znalazłem je, ustawiając instancję programowania liniowego, która reprezentowała polytop, a następnie używając losowych funkcji celu. Powód kodowania wszystkich 32 zamiast wybierania jednego jest prosty: oczekiwana wypłata wynosi 0, więc muszę zrobić lepiej niż się spodziewałem, aby wygrać. Zasadniczo zakładam, że drugi gracz stosuje mieszaną strategię i szacuję dystrybucję na podstawie historii wyboru. Następnie wybieram wierzchołek polytopa, który maksymalizuje moje oczekiwane wzmocnienie w stosunku do tego szacowanego rozkładu.
QuinnAndValor pokazuje podatność założenia, że drugi gracz stosuje strategię mieszaną. Po wykryciu gracza, który korzysta ze strategii z równowag Nasha, jest w stanie przejść do trybu losowego chodzenia, w którym grając w strategię nierównowagi, może przegrać, ale musi zdobyć przewagę tylko raz może powrócić do par gry, dla których
pick + guess = n
. Tak więc równowaga Nasha dla pojedynczej gry nie uogólnia na równowagę Nasha dla powtarzanej gry, co pozwala na bardziej złożone strategie.źródło
Quinn and Valor (zaktualizowany)
Quinn i Valor to elitarna drużyna zwiadowcza. Kuszą i pazurami rozdzierają każdego przeciwnika, który ma odwagę rzucić mu wyzwanie.
Prawie zawsze wygrywają ze wszystkimi rozwiązaniami Java na moim komputerze.
Edytować:
Przyznaję, że Quinn i Valor nie zdążyli pojedynkować się z Historianem, ale nadal wierzę w nie, aby wygrać turniej.
Moją zasadą jest, aby w przypadku każdego rozwiązania
choice + guess == 5
również bawić się zchoice + guess == 5
beneficjentami zachowującymi przewagę.Aktualizacja:
Cóż ... wszystko się skomplikowało.
źródło
Uczony
Uczony próbuje uczyć się na podstawie ruchów swojego przeciwnika, wybierając ten, którego jego przeciwnik mniej zgadł, i domyślając się tego, którego jego przeciwnik najczęściej używał. Ale teoria to nie wszystko, więc Scholar nie radzi sobie zbyt dobrze ...
źródło
DeltaMax
(Zaktualizowano, aby nie używać plików i dodano nową sekcję. Zmodyfikowano również, aby nie blokować wiązania w pierwszej sekcji).
Składa się z kilku strategii, które zaczynają się od prostych, a następnie stają się bardziej złożone - jeśli wyczyścisz jedną, spowoduje to przejście do następnej sekcji.
{0, 5}
konsekwentnie(choice, guess)
parę, która miałaby najlepsze oczekiwania, ważona tak, aby ostatnie rundy były ważniejszeAby dowiedzieć się, która warstwa została użyta na końcu, odkomentuj
linia.
Przepraszam za okropną Javę, spędziłem popołudnie składając kawałki i ucząc się języka :)
źródło
private int strat;
jest wystarczająco dobry.Historyk
(Zaktualizowano: ta sama logika, krótszy kod i 100 razy szybszy, ale w turnieju można użyć tylko jednego bota Historian.)
Używa ważonej losowo, aby wybrać parę zgadywania rzutów na podstawie skuteczności użycia tylko tej pary przeciwko poprzedniej historii przeciwników. Wagi są kwadratami osiągalnych wyników.
Bije
Quinn and Valor
(już nie) i przegrywaMorra Cowbell
. W turnieju z większością botówHistorian
jest na drugim miejscuQuinn and Valor
.źródło
Morra Cowbell
. Edytowałem post. Możesz usunąć komentarze, jeśli staną się nieaktualne.Ekstrapolator (v1.1)
Ekstremalna ekstrapolacja z jednej z równowag Nasha w prostszej grze.
Obsługuję zwięzły format odpowiedzi! (W stylu python.)
Wydaje się wiązać z Magic Cow (Morra Cowbell) i bije inne wpisy, które sprawdziłem.
źródło
Modny
Trendy przygląda się wcześniejszym ruchom przeciwnika, ważąc je według aktualności. Zgaduje najcięższy i wybiera jeden, który nieznacznie się podniósł. Oto w pełnej krasie:
Jedyne, co mogę teraz z tym porównać, to Cowbell. Traci przez większość czasu niewielkim marginesem, ale dość często wychodzi mi na wierzch. Zobaczymy, jak to działa z większą liczbą konkurentów.
źródło
Random Guesser
To jest naprawdę proste. Skutecznie rzuca k6 i zgaduje, że dodaje kolejny rzut do poprzedniego rzutu. Nie wygra, ale zapewni dobry poziom odniesienia.
źródło
Zmieszany, Python 3
Niepotrzebnie skomplikowany wpis. Nawet ja nie wiem co to robi.
Chociaż ten zaawansowany algorytm wydaje się działać gorzej niż losowo w tym turnieju i zużywa znaczną pamięć i czas wykonywania, ma oszałamiające wyniki dla niektórych wartości 5 ;-)
źródło
Rainbolt
Uwzględnia różnicę między dwiema ostatnimi liczbami, które odgadł nasz przeciwnik, dodaje, że do najnowszej odpowiedzi naszego przeciwnika, znajduje moduł i unika wyboru tej liczby za wszelką cenę. Na przykład, jeśli zgadniesz {5,4,3} (zmniejszając się o jeden), unikalibyśmy wyboru 2 za wszelką cenę.
Uwzględnia różnicę między dwoma ostatnimi liczbami, które wybrał nasz przeciwnik, dodaje to do ostatniego wyboru naszego przeciwnika i zgaduje tę liczbę. Na przykład, jeśli zgadniesz {1,4,5,2} (wzrost o trzy), zgadniemy 5.
Unika bezcelowych lub bardzo blisko bezcelowych rzutów.
źródło
getMove()
metody na statyczną. Nie można zaimplementować takiej metody niestatycznej (przynajmniej nie w Javie 8).Evolved Bot
Ewoluowałem tego bota, aby był najlepszym botem opartym na losowości.
źródło
Popularność, Python 3
Oblicz zgadywanie na podstawie popularnych liczb używanych w przeszłości przez przeciwnika. Ostatnio używane liczby mają większą wagę. Wybór liczb jest często taki sam jak przypuszczenie.
źródło
Interpolator
(Przełączono na Javę, ponieważ Python powodował problemy)
Używa interpolacji wielomianowej dla ostatnich 10 wyborów przeciwnika, aby obliczyć kolejny numer przeciwnika, a następnie robi to samo z własnymi wyborami i unika wybierania tej liczby. Interpolator ma również niewielkie uprzedzenie do wyboru 0 lub 5, a jego wybór czasami zależy od zgadywania:
źródło
CounterBot
Nie przeciwdziała nikomu, ale liczy od 0 do 5 w okręgu (
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4 ...
)źródło
Bazyliszek, Python
Według legendy Bazyliszek jest królem węży. ( źródło ) Uznałem, że to odpowiednia nazwa dla bota, który gra w „Noble Game Of Kings” i jest napisany w pythonie. = D Ten bot wywołuje strach w sercu innych botów i powoduje śmierć jednym spojrzeniem.
Działa to na dość prostej strategii. Nie oczekuję, że wygra, ale pisanie było fajne. To także moje pierwsze wyzwanie KoTH, więc jestem podekscytowany tym, jak dobrze sobie radzi.
Jak wybiera następny ruch.
Bazyliszek zawsze wykonuje ruch, który jego przeciwnik odgadł najmniej razy. W przypadku remisu wybierze mniejszą liczbę. (aby zminimalizować liczbę punktów przeciwnika).
Jak wybiera następną zgadywankę.
Bazyliszek wybierze najbardziej prawdopodobną odpowiedź na swoje poprzednie przypuszczenia. Na przykład, jeśli ostatnim razem odgadł 3, wróci do wszystkich poprzednich czasów, w których odgadł 3, a następnie zwróci najczęstszy ruch przeciwnika, który pojawia się po odgadnięciu 3. W przypadku remisu , wybierze większą liczbę (aby zmaksymalizować liczbę punktów, które mógłby zdobyć).
Czy w informacji technicznej będzie to działało poprawnie? Czy print () jest wystarczające, czy powinienem użyć czegoś takiego jak sys.stdout.write (), tak jak zrobiły to inne Pythonisty?
źródło
Tak samo
To zamienia się w przeciwnika, ale z tyłu jednym zgadywaniem / wyborem.
źródło
NullifierBot, Java
Zawsze rzuca 0, aby zminimalizować wygrane przeciwnika. Jeśli przeciwnik kiedykolwiek zgadnie mój numer, zarabia tylko tyle, ile rzucił.
Zawsze zgaduję 5, aby zmaksymalizować moje wygrane. Ponieważ nie mogę zdobyć żadnych punktów z rzutu, chcę zdobyć jak najwięcej od przeciwnika. Mogłem losowo zgadywać, ale gdzie jest w tym zabawa?
źródło
Erratica, Java
Nie wspaniale, ale pierwotnie został zaprojektowany tak, aby był w większości losowy, dopóki nie spadła na mnie wartość kompromisu. Konsekwentnie przegrywa z Counter Bot> _ <
źródło
Echo, Ruby
Odtwarza ostatnią grę przeciwnika, na podstawie teorii, że każdy może stworzyć bota, którego nie jest w stanie przewidzieć. Domysły oparte na wartości oczekiwanej przy użyciu próbki o stu ruchach.
źródło
echo.rb:3:in
<główna> ': niezdefiniowana metodasize' for nil:NilClass (NoMethodError)
. Wydaje się, że występuje tylko w pierwszej rundzie, gdy nie ma historii ruchów.if (mychoices.size > 990 && myscore == '0') nextchoice = rand(1..5)
części?KING FISHER
Ten facet składa się ze złych algorytmów zgadywania, które używają głównie tablic ważonych.
źródło
Uh Wiem, o czym myślisz. „Czy wybierze pięć czy coś innego?” Cóż, prawdę mówiąc, w całym tym podekscytowaniu sam nie jestem pewien, ale ponieważ jest to metoda .44, najsilniejsza metoda na świecie i od razu przeciążałaby twój stos, musisz zadać sobie jedno pytanie : „Czy mam szczęście?”
Cóż, punk?
źródło