Erstellen Sie einen Bot, um die kleinste eindeutige Nummer auszuwählen.
(Basierend auf einem Psychologieexperiment, von dem ich vor vielen Jahren gehört habe, das ich aber nicht wieder finden konnte.)
Regeln
- Jedes Spiel besteht aus 10 zufällig ausgewählten Bots, die 1000 Runden spielen.
- In jeder Runde wählen alle Bots eine ganze Zahl von 1 bis 10 (einschließlich). Alle Bots, die denselben Wert wählen, werden ausgeschlossen und der verbleibende Bot mit dem kleinsten Wert erhält einen Punkt.
- Für den Fall, dass kein Bot einen eindeutigen Wert auswählt, werden keine Punkte vergeben.
- Am Ende von 1000 Runden gewinnt der Bot mit den meisten Punkten (oder alle Bots mit den meisten Punkten) das Spiel.
- Das Turnier wird 200 * (Anzahl der Spieler) Spiele dauern.
- Der Bot mit dem höchsten Gewinnanteil gewinnt das Turnier.
Spezifikationen
Bots müssen Python 3-Klassen sein und zwei Methoden implementieren: select
und update
.
Bots werden mit einem Index erstellt.
select
Es werden keine Argumente übergeben und die Auswahl des Bots für die aktuelle Runde zurückgegeben.
update
Es wird eine Liste der von jedem Bot in der vorherigen Runde getroffenen Entscheidungen übergeben.
Beispiel
class Lowball(object):
def __init__(self, index):
# Initial setup happens here.
self.index = index
def select(self):
# Decision-making happens here.
return 1
def update(self, choices):
# Learning about opponents happens here.
# Note that choices[self.index] will be this bot's choice.
pass
Regler
import numpy as np
from bots import allBotConstructors
allIndices = range(len(allBotConstructors))
games = {i: 0 for i in allIndices}
wins = {i: 0 for i in allIndices}
for _ in range(200 * len(allBotConstructors)):
# Choose players.
playerIndices = np.random.choice(allIndices, 10, replace=False)
players = [allBotConstructors[j](i) for i, j in enumerate(playerIndices)]
scores = [0] * 10
for _ in range(1000):
# Let everyone choose a value.
choices = [bot.select() for bot in players]
for bot in players:
bot.update(choices[:])
# Find who picked the best.
unique = [x for x in choices if choices.count(x) == 1]
if unique:
scores[choices.index(min(unique))] += 1
# Update stats.
for i in playerIndices:
games[i] += 1
bestScore = max(scores)
for i, s in enumerate(scores):
if s == bestScore:
wins[playerIndices[i]] += 1
winRates = {i: wins[i] / games[i] for i in allIndices}
for i in sorted(winRates, key=lambda i: winRates[i], reverse=True):
print('{:>40}: {:.4f} ({}/{})'.format(allBotConstructors[i], winRates[i], wins[i], games[i]))
Zusätzliche Information
- Kein Bot wird in einem Spiel gegen sich selbst spielen.
- In dem unwahrscheinlichen Fall, dass ein Bot in weniger als 100 Spielen enthalten ist, wird das Turnier wiederholt.
- Bots können den Status zwischen Runden speichern, jedoch nicht zwischen Spielen.
- Der Zugriff auf den Controller oder andere Bots ist nicht gestattet.
- Die Anzahl der Spiele und die Anzahl der Runden pro Spiel können sich erhöhen, wenn die Ergebnisse zu unterschiedlich sind.
- Alle Bots, die Fehler auslösen oder ungültige Antworten geben (Nicht-Eingaben, Werte außerhalb von [1, 10] usw.), werden disqualifiziert und das Turnier wird ohne sie wiederholt.
- Es gibt keine zeitliche Begrenzung für Runden, aber ich kann eine implementieren, wenn Bots zu lange zum Nachdenken brauchen.
- Die Anzahl der Einsendungen pro Benutzer ist nicht begrenzt.
Einsendeschluss ist Freitag, 28. September, 23:59:59 UTC.Das Turnier ist nun für Einsendungen geschlossen.
Ergebnisse
BayesBot: 0.3998 (796/1991)
WhoopDiScoopDiPoop: 0.3913 (752/1922)
PoopDiScoopty: 0.3216 (649/2018)
Water: 0.3213 (660/2054)
Lowball: 0.2743 (564/2056)
Saboteur: 0.2730 (553/2026)
OneUpper: 0.2640 (532/2015)
StupidGreedyOne: 0.2610 (516/1977)
SecondSaboteur: 0.2492 (492/1974)
T42T: 0.2407 (488/2027)
T4T: 0.2368 (476/2010)
OpportunityBot: 0.2322 (454/1955)
TheGeneral: 0.1932 (374/1936)
FindRepeats: 0.1433 (280/1954)
MinWin: 0.1398 (283/2025)
LazyStalker: 0.1130 (226/2000)
FollowBot: 0.1112 (229/2060)
Assassin: 0.1096 (219/1999)
MostlyAverage: 0.0958 (194/2024)
UnchosenBot: 0.0890 (174/1955)
Raccoon: 0.0868 (175/2015)
Equalizer: 0.0831 (166/1997)
AvoidConstantBots: 0.0798 (158/1980)
WeightedPreviousUnchosen: 0.0599 (122/2038)
BitterBot: 0.0581 (116/1996)
Profiteur: 0.0564 (114/2023)
HistoryBot: 0.0425 (84/1978)
ThreeFourSix: 0.0328 (65/1984)
Stalker: 0.0306 (61/1994)
Psychadelic: 0.0278 (54/1943)
Unpopulist: 0.0186 (37/1994)
PoissonsBot: 0.0177 (35/1978)
RaccoonTriangle: 0.0168 (33/1964)
LowHalfRNG: 0.0134 (27/2022)
VictoryPM1: 0.0109 (22/2016)
TimeWeighted: 0.0079 (16/2021)
TotallyLost: 0.0077 (15/1945)
OneTrackMind: 0.0065 (13/1985)
LuckySeven: 0.0053 (11/2063)
FinalCountdown: 0.0045 (9/2000)
Triangle: 0.0039 (8/2052)
LeastFrequent: 0.0019 (4/2067)
Fountain: 0.0015 (3/1951)
PlayerCycle: 0.0015 (3/1995)
Cycler: 0.0010 (2/1986)
SecureRNG: 0.0010 (2/2032)
SneakyNiner: 0.0005 (1/2030)
I_Like_Nines: 0.0000 (0/1973)
bots.py
im selben Verzeichnis aufgerufen wird und alle Bots enthält. Erstellen Sie am Ende eine Liste der Konstruktoren:allBotConstructors = [Lowball, BayesBot, ...]
Antworten:
BayesBot
Versucht, mithilfe eines einfachen statistischen Modells die optimale Auswahl zu treffen.
quelle
Vermeiden Sie konstante Bots
Verfolgen Sie, welche Bots immer den gleichen Wert zurückgegeben haben, und überspringen Sie diese Werte. Wählen Sie die verbleibenden Werte nach dem Zufallsprinzip aus, jedoch mit einer deutlichen Tendenz zu niedrigeren Werten.
quelle
WaitWhatBot
Nicht der konkurrenzfähigste Bot und definitiv nicht GTO , aber erdrosselt die Punktzahl eines "immer 1" - oder "fast immer 1" -Objekts im selben Spiel wie in einem solchen Szenario. WaitWhatBot wird auch so ein Bot.
Verwendet sich entwickelnde Wahrscheinlichkeiten mit gewichteten Gewichten sowohl in Bezug auf die Zeit (neuere -> größere Gewichtung) als auch den Auswahlwert (unterer Punkt -> größere Gewichtung).
Verwendet etwas verschleierten Code, um ein bisschen zu kichern.
quelle
Stalker
Zu Beginn des Spiels wählt dieser Bot zufällig einen bestimmten Index als Ziel. Es pirscht sich dann an das Ziel des gesamten Spiels und kopiert die Nummer, die es in der vorherigen Runde gewählt hat.
quelle
Dumme Gierige
Dieser Bot geht davon aus, dass andere Bots nicht binden wollen.
Mir ist klar, dass dies dasselbe ist wie das angegebene Beispiel, aber ich hatte den Gedanken, bevor ich so weit gelesen hatte. Wenn dies nicht mit dem Ablauf der KoTH-Herausforderungen übereinstimmt, lassen Sie es mich wissen.
quelle
self.index
.HistoryBot
Implementierung des Kommentars von user2390246:
quelle
OneUpper
Die Bots aller anderen zielen entweder auf 1 oder zufällig, warum also nicht einfach auf 2?
quelle
Fließen wie Wasser
Vermeidet grundlegende Algorithmen zur Erkennung konstanter Bots, indem jede Zahl verdoppelt und langsam auf niedrigere Werte umgeschaltet wird, wenn sie nicht belegt sind.
quelle
Total verloren
quelle
Der finale Countdown
Probieren Sie es online!
Gibt 10 für die ersten 100 Runden, 9 für die nächsten 100 usw. zurück.
quelle
Opportunitybot
Dieser Bot verfolgt in jeder Runde die niedrigste Zahl, die nicht von anderen Bots ausgewählt wurde (die niedrigste verfügbare Zahl oder Chance), und spielt die Zahl, die diese Zahl am häufigsten war.
quelle
PatterMatcher
Sucht nach sich wiederholenden Abschnitten in den Einsendungen der Bots, versucht dort Zahlen vorherzusagen und zu vermeiden.
Dreieck
Die Chance n zu wählen ist
(10-n)/45
Zeitgewichtet
Die Wahrscheinlichkeit, mit der ein Bot eine Zahl auswählt, ist proportional zu
(10-n)*Δt
. Die erste Runde ist identisch mit Dreieck.Am wenigsten häufig
Sendet die am seltensten vorkommende Zahl, wenn sie gleich ist, nimmt die niedrigste.
Längste Zeit
Wie bei den Frequenzen, jedoch mit der längsten Zeit zwischen den Einsendungen.
Saboteur
Sendet die niedrigste Nummer, die zuletzt gesendet wurde.
Zweiter Saboteur
Sendet die zweitniedrigste Nummer, die zuletzt gesendet wurde
Profiteur
Sendet die niedrigste Nummer, die beim letzten Mal nicht gesendet wurde
Es tut mir leid, dass ich ein bisschen mitgerissen wurde, als ich die Idee für neue Bots bekam, während ich die vorherige einmal implementierte. Ich war mir nicht sicher, welches das Beste sein würde und bin gespannt auf die Leistung jedes einzelnen. Sie finden sie alle hier: https://repl.it/@Fejfo/Lowest-Unique-Number
quelle
set(range(10)
.Der Top 50% RNG Bot
Ich wollte gerade einen zufälligen Bot posten, aber hidefromkgb hat vor mir gepostet (durch das Posten machen sie sich ein einfaches Ziel für den KGB, kein guter Weg, sich zu verstecken). Dies ist meine erste KOTH-Antwort in der Hoffnung, den rng-Bot schlagen zu können.
quelle
Der Cycler
Dieser Bot durchläuft einfach jede der Zahlen in seinem Zug. Nur zum Spaß initialisiert es den Zähler mit seinem Index.
quelle
OneTrackMind
Dieser Bot wählt zufällig eine Zahl und bleibt 50 Runden lang dabei. Dann wählt er eine andere und wiederholt sie.
quelle
Glückliche sieben
Ich fühle mich heute glücklich! Ich werfe alles auf 7 raus!
quelle
Meine Idee ist, dass die Strategie mehr von der Anzahl der Bots abhängt als von der tatsächlichen Bewertung der Strategien.
Bei einer erheblichen Anzahl von Bots stehen folgende Optionen zur Verfügung:
"Gierige" Roboter, die auf die unteren 1-3 Zahlen abzielen 10 Bots sind "schlau" und streben die unteren 1-3 Zahlen an. Am besten lassen Sie diese Bots einfach dazwischen stören.
"Intelligente" Roboter, die, sobald sie feststellen, dass 4 immer aufgehoben sind, woanders hingehen.
"Zufällige" und "konstante" Roboter. Hier gibt es nicht viel zu tun.
Also wette ich auf # 4.
quelle
Der unentbehrliche RNG-Bot
quelle
Attentäter
Bleibt im Schatten, zielt dann auf die aktuell niedrigste Schätzung. Lauf.
quelle
FollowBot
Kopieren Sie den Gewinner aus der letzten Runde oder zumindest die beste Auswahl, wenn es keinen Gewinner gibt.
quelle
Psychadelic
Der einzige Weg, einen Atomkrieg zu gewinnen, besteht darin, sich wahnsinnig zu machen. Also werde ich jeden Predictive Bot im Turnier verrückt machen.
quelle
UnchosenBot
Nimmt die Auswahl der letzten Runde und wählt die niedrigste nicht ausgewählte Zahl (wobei die Auswahl von UnchosenBot natürlich ignoriert wird).
quelle
Whoop-di-Scoop-di-Poop
Poop-di-Scoopty
Ich habe Python noch nie gesehen oder berührt, ist das unpythonisch?
quelle
<!-- language: lang-python -->
vor dem Codeblock hinzu, um die Syntaxhervorhebung zu aktivierenpython
Tag zu der Frage halluziniert und dachte, es wäre automatisch, aber ich habe etwas Schlechtes geschrieben.others = [c for i, c in enumerate(choices) if i != self.index]
, oder, weil danach nur Sie diese Variable für die Mitgliedschaft Tests verwenden,{ }
anstatt[ ]
eine konstruieren würde ,set
anstatt einlist
.if (self.guess)
ist auch sehr unpythonisch.self.guess
da reingekommen sind! Muss einer der Formatierer gewesen sein.Brunnen
Ein einfacher Bot wählt zuerst die niedrigste Zahl und wenn ein anderer Bot sie ebenfalls wählt, erhöht er den Zähler - der Boden wird gefüllt und das Wasser fließt nach unten. Wenn es 11 erreicht, startet es wieder auf 1 - das Wasser wird wieder nach oben gepumpt.
quelle
target
auf 10 setzen?PoissonsBot
Wählen Sie Zahlen aus einer Poisson-Verteilung aus, die auf niedrigere Werte eingestellt ist. Passen Sie den Mittelwert der Verteilung nach oben an, wenn wir gleichauf sind, und nach unten, wenn unter uns Vermutungen liegen. Die Schrittgröße wird mit fortschreitendem Spiel immer kleiner.
quelle
MinWin
Es wird eine fortlaufende Zählung der Gewinnwerte und der minimalen nicht ausgewählten Werte durchgeführt (wobei der minimale nicht ausgewählte Wert nur berücksichtigt wird, wenn er kleiner als der Gewinnwert ist). Es wählt zufällig zwischen diesen Gewinn- und Mindestwerten.
quelle
Spielerzyklus
Wechselt durch die Spieler. Der aktuelle Spieler (könnte selbst sein) hat nun die Wahl dieses Bots. Beginnt mit dem Drucken von 8, weil warum nicht. Entschuldigung, ich kann nicht python, das ist wahrscheinlich schlechter Code.
Edit: Danke an Triggernometry für die Verbesserung meines Codes mit itertools
quelle
Waschbär
Wählen Sie die niedrigste Zahl, die in der vorherigen Runde nicht ausgewählt wurde, mit Ausnahme unserer eigenen vorherigen Auswahl, die dieses Mal erneut ausgewählt werden könnte. Wählen Sie in der ersten Runde 1 aus. (Bei 9 Gegnern und 10 Auswahlmöglichkeiten gibt es garantiert einen verfügbaren Wert.)
Das habe ich mir unabhängig ausgedacht, aber jetzt sehen wir mindestens zwei vorhergehende Bots, die im Wesentlichen gleich sind.
Waschbär-Dreieck
Kombiniert Waschbär und Dreieck: Wählen Sie aus den nicht gewählten Werten einen aus, der auf der Wahrscheinlichkeit des umgekehrten Dreiecks basiert.
quelle
AttributeError: 'RaccoonTriangle' object has no attribute 'boundaries'
Die allgemeine
Der General kämpft immer den letzten Krieg (n) .
quelle
No-Repeat Random
Bot pickt zufällig, vermeidet jedoch, die gleiche Zahl zu wählen, die er in der vorherigen Runde gespielt hat.
quelle