HERAUSFORDERUNGSSTATUS: OFFEN
Kommentar, PR eröffnen oder mich anderweitig anschreien, wenn ich deinen Bot vermisse.
Gefangenendilemma ... mit drei Möglichkeiten. Verrückt, nicht wahr?
Hier ist unsere Auszahlungsmatrix. Spieler A links, B oben
A,B| C | N | D
---|---|---|---
C |3,3|4,1|0,5
N |1,4|2,2|3,2
D |5,0|2,3|1,1
Die Auszahlungsmatrix ist so konstruiert, dass beide Spieler immer zusammenarbeiten können. Sie können jedoch (normalerweise) gewinnen, indem Sie Neutral oder Defection wählen.
Hier sind einige (konkurrierende) Beispiel-Bots.
# turns out if you don't actually have to implement __init__(). TIL!
class AllC:
def round(self, _): return "C"
class AllN:
def round(self, _): return "N"
class AllD:
def round(self, _): return "D"
class RandomBot:
def round(self, _): return random.choice(["C", "N", "D"])
# Actually using an identically-behaving "FastGrudger".
class Grudger:
def __init__(self):
self.history = []
def round(self, last):
if(last):
self.history.append(last)
if(self.history.count("D") > 0):
return "D"
return "C"
class TitForTat:
def round(self, last):
if(last == "D"):
return "D"
return "C"
Ihr Bot ist eine Python3-Klasse. Für jedes Spiel wird eine neue Instanz erstellt, round()
die in jeder Runde mit der Auswahl des Gegners aus der letzten Runde aufgerufen wird (oder Keine, wenn es die erste Runde ist).
In nur einem Monat gibt es eine Prämie von 50 Wiederholungen für den Gewinner.
Besonderheiten
- Jeder Bot spielt in [ANONYMISIERT] Runden jeden anderen Bot (1vs1), einschließlich sich selbst.
- Standardlücken sind nicht erlaubt.
- Keine Unordnung mit irgendetwas außerhalb Ihrer Klasse oder anderen hinterhältigen Spielereien.
- Sie können bis zu fünf Bots einreichen.
- Ja, Sie können Handshake implementieren.
- Jede andere Antwort als
C
,N
oderD
wird stillschweigend alsN
. - Die Punkte jedes Bots aus jedem Spiel, das er spielt, werden aufsummiert und verglichen.
Regler
Andere Sprachen
Ich werde eine API zusammenstellen, falls jemand sie benötigt.
Scores: 2018-11-27
27 bots, 729 games.
name | avg. score/round
----------------|-------------------
PatternFinder | 3.152
DirichletDice2 | 3.019
EvaluaterBot | 2.971
Ensemble | 2.800
DirichletDice | 2.763
Shifting | 2.737
FastGrudger | 2.632
Nash2 | 2.574
HistoricAverage | 2.552
LastOptimalBot | 2.532
Number6 | 2.531
HandshakeBot | 2.458
OldTitForTat | 2.411
WeightedAverage | 2.403
TitForTat | 2.328
AllD | 2.272
Tetragram | 2.256
Nash | 2.193
Jade | 2.186
Useless | 2.140
RandomBot | 2.018
CopyCat | 1.902
TatForTit | 1.891
NeverCOOP | 1.710
AllC | 1.565
AllN | 1.446
Kevin | 1.322
quelle
while len(botlist) > 1:
mit einschließenbotlist.remove(lowest_scoring_bot)
, erhalten Sie ein Ausscheidungsturnier mit interessanten Ergebnissen.Antworten:
EvaluaterBot
Gewinne gegen alle zuvor eingereichten Bots mit Ausnahme (vielleicht) des zufälligen Bots (aber es könnte einen Vorteil haben, weil es D bei einem Unentschieden auswählt und D optimal sein sollte) und ein konstantes Unentschieden gegen sich selbst spielt.
quelle
NashEquilibrium
Dieser Bot hat eine Spieltheorie-Klasse im College besucht, war aber faul und ging nicht in die Klasse, in der er iterierte Spiele behandelte. Er spielt also nur Single Game Mixed Nash Equilibrium. Es stellt sich heraus, dass 1/5 2/5 2/5 das gemischte NE für die Auszahlungen ist.
Ständiger Missbrauch des Nash-Gleichgewichts
Dieser Bot hat eine oder zwei Lektionen von seinem faulen Bruder erhalten. Das Problem seines faulen Bruders war, dass er keine festen Strategien ausnutzte. Diese Version prüft, ob der Gegner ein konstanter Spieler oder ein Titfortat ist und spielt dementsprechend, ansonsten spielt sie das reguläre Nash-Gleichgewicht.
Der einzige Nachteil ist, dass es durchschnittlich 2,2 Punkte pro Spielzug gibt, wenn man gegen sich selbst spielt.
quelle
class NashEquilibrium: def round(self, _): a = random.random() for k, v in [(0.2, "C"), (0.6, "N"), (1, "D")]: if a <= k: return v
TatForTit
Dieser Bot wählt abwechselnd DNDN aus, während TitForTat CDCD abwechselt, was einen durchschnittlichen Nettogewinn von 3 Punkten pro Runde ergibt, wenn ich die Auszahlungsmatrix richtig gelesen habe. Ich denke, das könnte gegen TitForTat optimal sein. Natürlich könnte es verbessert werden, einen Nicht-TFT-Gegner zu erkennen und andere Strategien zu verfolgen, aber ich habe nur das ursprüngliche Kopfgeld angestrebt.
quelle
PatternFinder
Dieser Bot sucht nach früheren Ereignissen des letzten Spielzustands, um zu sehen, wie der Gegner auf diese Ereignisse reagiert hat. Dabei werden längere Musterübereinstimmungen und neuere Übereinstimmungen bevorzugt. Anschließend wird der Zug ausgeführt, der den vorhergesagten Zug des Gegners "schlägt". Es gibt viel Raum, damit es mit all den Daten, die es verfolgt, intelligenter wird, aber ich hatte keine Zeit mehr, daran zu arbeiten.
quelle
Jade
Beginnt optimistisch, wird aber zunehmend bitterer, da der Gegner sich weigert zu kooperieren. Viele magische Konstanten, die wahrscheinlich angepasst werden könnten, aber dies wird wahrscheinlich nicht gut genug sein, um die Zeit zu rechtfertigen.
quelle
Ensemble
Dies lässt ein Ensemble verwandter Modelle laufen. Die einzelnen Modelle berücksichtigen unterschiedliche historische Beträge und haben die Option, entweder immer den Zug zu wählen, der die erwartete Auszahlungsdifferenz optimiert, oder zufällig einen Zug im Verhältnis zur erwarteten Auszahlungsdifferenz auszuwählen.
Jedes Ensemblemitglied stimmt dann über seinen bevorzugten Zug ab. Sie erhalten eine Stimmenzahl, die der Anzahl der Stimmen entspricht, die sie gewonnen haben, als die des Gegners (was bedeutet, dass schreckliche Models negative Stimmen erhalten). Welcher Zug gewinnt die Abstimmung wird dann ausgewählt.
(Wahrscheinlich sollten sie ihre Stimmen auf die einzelnen Schritte aufteilen, je nachdem, wie sehr sie sie bevorzugen, aber mir ist es im Moment nicht wichtig genug, dies zu tun.)
Es schlägt alles, was bisher gepostet wurde, mit Ausnahme von EvaluaterBot und PatternFinder. (Eins-zu-eins schlägt es EvaluaterBot und verliert gegen PatternFinder).
Test Framework
Für den Fall, dass es jemand anderes nützlich findet, finden Sie hier ein Test-Framework zum Betrachten einzelner Übereinstimmungen. Python2. Setzen Sie einfach alle Gegner, an denen Sie interessiert sind, in opponents.py ein und ändern Sie die Verweise auf Ensemble in Ihre eigenen.
quelle
OldTitForTat
Old School-Spieler sind zu faul, um die neuen Regeln zu aktualisieren.
quelle
NeverCOOP
Wenn der gegnerische Bot fehlerhaft oder neutral ist, wählen Sie einen Fehler. Andernfalls, wenn dies die erste Runde ist oder der gegnerische Bot kooperiert, wähle neutral. Ich bin mir nicht sicher, wie gut das funktionieren wird ...
quelle
if(last):
in Ihrem Grudger-Bot, um festzustellen, ob es eine vorherige Runde gab.None in "ND"
fehler.if last and last in "ND":
es zu kompliziert war?LastOptimalBot
Nimmt an, dass der gegnerische Bot immer wieder den gleichen Zug spielt und wählt denjenigen, der die beste Auszahlung hat.
Durchschnittswerte:
quelle
return last
.return last
wäre, würde LOB über 6 Runden 18-9 gehen und nicht über 5 Runden 13-10 . Ich denke, es ist in Ordnung so wie es ist - mach dir keine Sorgen, die Beispiel-Bots zu optimieren.return last
wäre ein besserer T4T für diese Herausforderung, denke ichif(last): return last; else: return "C"
ist schlimmer.CopyCat
Kopiert den letzten Zug des Gegners.
Ich erwarte nicht, dass das gut geht, aber noch hatte niemand diesen Klassiker implementiert.
quelle
Verbesserte Dirichletwürfel
Dies ist eine verbesserte Version von Dirichlet Dice. Anstatt die erwartete Multinomialverteilung aus der Dirichlet-Verteilung zu ziehen, wird eine Multinomialverteilung zufällig aus der Dirichlet-Verteilung gezogen. Anstatt vom Multinomial zu zeichnen und die optimale Antwort darauf zu geben, gibt es die optimale erwartete Antwort auf das gegebene Multinomial unter Verwendung der Punkte. Die Zufälligkeit wurde also im Wesentlichen vom Multinomial Draw zum Dirichlet Draw verschoben. Außerdem sind die Priors jetzt flacher, um die Erkundung anzuregen.
Es ist "verbessert", weil es jetzt das Punktesystem berücksichtigt, indem es den besten erwarteten Wert für die Wahrscheinlichkeiten angibt, während es seine Zufälligkeit beibehält, indem es die Wahrscheinlichkeiten selbst zeichnet. Früher habe ich einfach versucht, die bestmögliche Auszahlung aus den erwarteten Wahrscheinlichkeiten zu erzielen, aber das war schlecht, weil es einfach hängen geblieben ist und nicht genug erforscht hat, um seine Würfel zu aktualisieren. Es war auch vorhersehbarer und ausnutzbarer.
Ursprüngliche Einreichung:
Dirichlet Würfel
Grundsätzlich gehe ich davon aus, dass die Antwort des Gegners auf meine letzte Ausgabe eine multinomiale Variable (gewichtete Würfel) ist, einer für jede meiner Ausgaben, also gibt es einen Würfel für "C", einen für "N" und einen für "D". . Wenn mein letzter Wurf zum Beispiel ein "N" wäre, würfle ich mit den "N-Würfeln", um zu erraten, wie sie auf mein "N" reagieren würden. Ich beginne mit einem Dirichlet, das voraussetzt, dass mein Gegner etwas "schlau" ist (eher derjenige mit der besten Auszahlung gegen meinen letzten Wurf, weniger derjenige mit der schlechtesten Auszahlung). Ich generiere die "erwartete" Multinomialverteilung aus dem entsprechenden Dirichlet vor (dies ist der erwartete Wert der Wahrscheinlichkeitsverteilung über ihre Würfelgewichte). Ich würfle mit dem Gewicht meiner letzten Ausgabe.
Ab der dritten Runde aktualisiere ich das entsprechende Dirichlet nach Bayes, bevor mein Gegner das letzte Mal auf das Spiel reagiert, das ich vor zwei Runden gespielt habe. Ich versuche iterativ ihre Würfelgewichte zu lernen.
Ich hätte auch einfach die Antwort mit dem besten "erwarteten" Ergebnis auswählen können, nachdem ich die Würfel erzeugt hatte, anstatt einfach die Würfel zu würfeln und auf das Ergebnis zu reagieren. Ich wollte jedoch die Zufälligkeit beibehalten, damit mein Bot weniger anfällig für diejenigen ist, die versuchen, ein Muster vorherzusagen.
quelle
Kevin
Picks die schlechteste Wahl. Der schlimmste Bot gemacht.
Nutzlos
Es betrachtet die letzten beiden Züge des Gegners und wählt die am meisten nicht ausgeführten aus, ansonsten wählt es etwas Zufälliges aus. Es gibt wahrscheinlich einen besseren Weg, dies zu tun.
quelle
Historischer Durchschnitt
Schaut sich die Geschichte an und findet die Aktion, die im Durchschnitt am besten gewesen wäre. Startet die Zusammenarbeit.
quelle
Gewichteter Durchschnitt
Das Verhalten des Gegners wird als rechtwinkliges Dreieck mit CND-Ecken von 0,0 0,1 1,0 modelliert. Jede Bewegung des Gegners verschiebt den Punkt innerhalb dieses Dreiecks in Richtung dieser Ecke, und wir spielen, um den durch den Punkt angegebenen Zug zu schlagen (wobei C eine einstellbare kleine Scheibe des Dreiecks erhält). Theoretisch wollte ich, dass dies ein längeres Gedächtnis mit mehr Gewicht gegenüber früheren Zügen hat, aber in der Praxis bevorzugt das aktuelle Meta Bots, die sich schnell ändern, so dass sich dies in einer Annäherung an LastOptimalBot gegen die meisten Feinde entwickelt. Posting für die Nachwelt; Vielleicht lässt sich jemand inspirieren.
quelle
Tetragramm
Versuchen Sie, ein Muster in den Zügen des Gegners zu finden, vorausgesetzt, er beobachtet auch unseren letzten Zug.
quelle
Handschlag
Erkennt, wenn es gegen sich selbst spielt, und kooperiert dann. Andernfalls wird LastOptimalBot nachgebildet, was nach der besten Einzeilenstrategie aussieht. Führt eine schlechtere Leistung als LastOptimalBot aus, und zwar um einen Betrag, der umgekehrt proportional zur Anzahl der Runden ist. Wäre natürlich besser, wenn es mehr Exemplare auf dem Feld gäbe * husten ** zwinker *.
quelle
ShiftingOptimalBot
Dieser Bot verwendet den Algorithmus von LastOptimalBot, solange er gewinnt. Wenn der andere Bot dies jedoch vorhersagt, beginnt er zu spielen, welcher Zug auch immer sein Gegner zuletzt gespielt hat (das ist der Zug, der den Zug schlägt, der LastOptimalBot schlagen würde). Es durchläuft einfache Transpositionen dieser Algorithmen, solange sie verlieren (oder wenn es langweilig wird, wenn viel gezeichnet wird).
Ehrlich gesagt, ich bin überrascht, dass LastOptimalBot auf dem fünften Platz sitzt, als ich dies poste. Ich bin mir ziemlich sicher, dass dies besser gelingen wird, vorausgesetzt, ich habe diese Python korrekt geschrieben.
quelle
HandshakePatternMatch
Warum stimmen Sie mit Ihrem Muster überein? Händedruck und kooperieren weg.
quelle
import PatternFinder
betrügt in meinen Büchern.Hardcoded
Spielt einfach eine hartkodierte Folge von Zügen ab, die optimiert wurden, um einige der besten deterministischen Bots zu schlagen.
quelle