Endergebnis
Der Wettbewerb ist vorbei. Glückwunsch an hard_coded
!
Einige interessante Fakten:
In 31600 von 40920 Auktionen (77,2%) hat der Gewinner der ersten Runde die meisten Runden in dieser Auktion gewonnen.
Wenn Beispiel-Bots in den Wettbewerb aufgenommen werden, ändern sich die ersten neun Plätze nicht
AverageMine
undheurist
tauschen ihre Positionen.Top 10 Ergebnisse einer Auktion:
[2, 2, 3, 3] 16637
[0, 3, 3, 4] 7186
[1, 3, 3, 3] 6217
[1, 2, 3, 4] 4561
[0, 1, 4, 5] 1148
[0, 2, 4, 4] 1111
[2, 2, 2, 4] 765
[0, 2, 3, 5] 593
[1, 1, 4, 4] 471
[0, 0, 5, 5] 462
Tie Zahl (Anzahl der Auktionen , dass der i-ten Runde hatte keinen Sieger):
[719, 126, 25, 36, 15, 58, 10, 7, 19, 38]
.Durchschnittliches Höchstgebot des i-ten Runde:
[449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1]
.
Anzeigetafel
Bot count: 33
hard_coded Score: 16141 Total: 20075170
eenie_meanie_more Score: 15633 Total: 18513346
minus_one Score: 15288 Total: 19862540
AverageMine Score: 15287 Total: 19389331
heurist Score: 15270 Total: 19442892
blacklist_mod Score: 15199 Total: 19572326
Swapper Score: 15155 Total: 19730832
Almost_All_In Score: 15001 Total: 19731428
HighHorse Score: 14976 Total: 19740760
bid_higher Score: 14950 Total: 18545549
Graylist Score: 14936 Total: 17823051
above_average Score: 14936 Total: 19712477
below_average Score: 14813 Total: 19819816
Wingman_1 Score: 14456 Total: 18480040
wingman_2 Score: 14047 Total: 18482699
simple_bot Score: 13855 Total: 20935527
I_Dont_Even Score: 13505 Total: 20062500
AntiMaxer Score: 13260 Total: 16528523
Showoff Score: 13208 Total: 20941233
average_joe Score: 13066 Total: 18712157
BeatTheWinner Score: 12991 Total: 15859037
escalating Score: 12914 Total: 18832696
one_upper Score: 12618 Total: 18613875
half_in Score: 12605 Total: 19592760
distributer Score: 12581 Total: 18680641
copycat_or_sad Score: 11573 Total: 19026290
slow_starter Score: 11132 Total: 20458100
meanie Score: 10559 Total: 12185779
FiveFiveFive Score: 7110 Total: 24144915
patient_bot Score: 7088 Total: 22967773
forgetful_bot Score: 2943 Total: 1471500
bob_hater Score: 650 Total: 1300
one_dollar_bob Score: 401 Total: 401
In diesem Spiel simulieren wir eine Auktion mit Siegelgebot.
Jede Auktion ist ein 4-Spieler-Spiel, das aus 10 Runden besteht. Anfangs haben die Spieler kein Geld. Zu Beginn jeder Runde erhält jeder Spieler 500 US-Dollar und macht dann seine eigenen Gebote. Das Gebot kann eine nicht negative ganze Zahl sein, die kleiner oder gleich dem Betrag ist, den sie haben. Gewöhnlich gewinnt einer, der das höchste Gebot abgibt, die Runde. Wenn jedoch mehrere Spieler den gleichen Preis bieten, wird ihr Gebot nicht berücksichtigt (daher kann die Runde nicht gewonnen werden), um die Sache interessanter zu machen. Wenn zum Beispiel vier Spieler 400 400 300 200 bieten, gewinnt der eine 300; Wenn sie 400 400 300 300 bieten, gewinnt niemand. Der Gewinner muss bezahlen, was er geboten hat.
Da es sich um eine Auktion mit versiegeltem Gebot handelt, ist die einzige Information, die der Spieler über das Bieten erhält, der Gewinner und wie viel er zu Beginn der nächsten Runde gezahlt hat (damit der Spieler wissen kann, wie viel jeder hat).
Wertung
Für jede mögliche 4-Spieler-Kombination findet eine Auktion statt. Das heißt, wenn es insgesamt N Bots gibt, wird es eine N C 4 Auktion geben. Der Bot, der die meisten Runden gewinnt, ist der endgültige Gewinner. Bei einem Gleichstand gewinnt der Bot, der insgesamt am wenigsten bezahlt hat. Wenn es wie beim Bieten immer noch ein Unentschieden gibt, werden diese Unentschieden entfernt.
Codierung
Sie sollten eine Python 3- Klasse mit einer Member-Funktion implementieren play_round
(und __init__
bei Bedarf mit anderen). play_round
sollte 3 Argumente nehmen (einschließlich Selbst). Das zweite und dritte Argument lauten in der Reihenfolge: die ID des Gewinners der vorherigen Runde, gefolgt von der Höhe der Auszahlung. Wenn niemand gewinnt oder es die erste Runde ist, sind beide -1. Ihre ID ist immer 0, und ID 1–3 sind die anderen Spieler in einer Reihenfolge, die nur durch die Position in diesem Beitrag bestimmt wird.
Zusätzliche Regeln
1. Deterministisch:
Das Verhalten Ihrer Funktion sollte nur von den Eingabeargumenten innerhalb einer Auktion abhängen. Das heißt, Sie können nicht auf Dateien, Zeit, globale Variablen oder irgendetwas zugreifen, das Zustände zwischen verschiedenen Auktionen oder Bots speichert . Wenn Sie einen Pseudozufallsgenerator verwenden möchten, ist es besser, ihn selbst zu schreiben (um zu verhindern, dass die Programme anderer wie random
in Python lib beeinflusst werden) und ihn mit einem festen Startwert in __init__
oder in der ersten Runde zurückzusetzen.
2. Drei Bots pro Person: Sie dürfen höchstens drei Bots einsenden, damit Sie eine Strategie entwickeln können, mit der Ihre Bots auf irgendeine Weise "kooperieren".
3. Nicht zu langsam: Da es viele Auktionen geben wird, stellen Sie sicher, dass Ihre Bots nicht zu langsam laufen. Ihre Bots sollten in der Lage sein, mindestens 1.000 Auktionen in einer Sekunde abzuschließen.
Regler
Hier ist der Controller, den ich verwende. Alle Bots werden importiert und bot_list
in der Reihenfolge in diesem Beitrag hinzugefügt .
# from some_bots import some_bots
bot_list = [
#one_bot, another_bot,
]
import hashlib
def decide_order(ls):
hash = int(hashlib.sha1(str(ls).encode()).hexdigest(), 16) % 24
nls = []
for i in range(4, 0, -1):
nls.append(ls[hash % i])
del ls[hash % i]
hash //= i
return nls
N = len(bot_list)
score = [0] * N
total = [0] * N
def auction(ls):
global score, total
pl = decide_order(sorted(ls))
bots = [bot_list[i]() for i in pl]
dollar = [0] * 4
prev_win, prev_bid = -1, -1
for rounds in range(10):
bids = []
for i in range(4): dollar[i] += 500
for i in range(4):
tmp_win = prev_win
if prev_win == i: tmp_win = 0
elif prev_win != -1 and prev_win < i: tmp_win += 1
bid = int(bots[i].play_round(tmp_win, prev_bid))
if bid < 0 or bid > dollar[i]: raise ValueError(pl[i])
bids.append((bid, i))
bids.sort(reverse = True)
winner = 0
if bids[0][0] == bids[1][0]:
if bids[2][0] == bids[3][0]: winner = -1
elif bids[1][0] == bids[2][0]: winner = 3
else: winner = 2
if winner == -1:
prev_win, prev_bid = -1, -1
else:
prev_bid, prev_win = bids[winner]
score[pl[prev_win]] += 1
total[pl[prev_win]] += prev_bid
dollar[prev_win] -= prev_bid
for a in range(N - 3):
for b in range(a + 1, N - 2):
for c in range(b + 1, N - 1):
for d in range(c + 1, N): auction([a, b, c, d])
res = sorted(map(list, zip(score, total, bot_list)), key = lambda k: (-k[0], k[1]))
class TIE_REMOVED: pass
for i in range(N - 1):
if (res[i][0], res[i][1]) == (res[i + 1][0], res[i + 1][1]):
res[i][2] = res[i + 1][2] = TIE_REMOVED
for sc, t, tp in res:
print('%-20s Score: %-6d Total: %d' % (tp.__name__, sc, t))
Beispiele
Wenn Sie einen Pseudozufallsgenerator benötigen, finden Sie hier einen einfachen.
class myrand:
def __init__(self, seed): self.val = seed
def randint(self, a, b):
self.val = (self.val * 6364136223846793005 + 1) % (1 << 64)
return (self.val >> 32) % (b - a + 1) + a
class zero_bot:
def play_round(self, i_dont, care): return 0
class all_in_bot:
def __init__(self): self.dollar = 0
def play_round(self, winner, win_amount):
self.dollar += 500
if winner == 0: self.dollar -= win_amount
return self.dollar
class random_bot:
def __init__(self):
self.dollar = 0
self.random = myrand(1)
def play_round(self, winner, win_amount):
self.dollar += 500
if winner == 0: self.dollar -= win_amount
return self.random.randint(0, self.dollar)
class average_bot:
def __init__(self):
self.dollar = 0
self.round = 11
def play_round(self, winner, win_amount):
self.dollar += 500
self.round -= 1
if winner == 0: self.dollar -= win_amount
return self.dollar / self.round
class fortytwo_bot:
def play_round(self, i_dont, care): return 42
Ergebnis
all_in_bot Score: 20 Total: 15500
random_bot Score: 15 Total: 14264
average_bot Score: 15 Total: 20000
TIE_REMOVED Score: 0 Total: 0
TIE_REMOVED Score: 0 Total: 0
Der Gewinner ist all_in_bot
. Beachten Sie, dass zero_bot
und fortytwo_bot
haben die gleiche Punktzahl und Summe, so dass sie entfernt werden.
Diese Bots werden nicht in den Wettbewerb aufgenommen. Sie können sie verwenden, wenn Sie denken, dass sie großartig sind.
Die Endrunde findet am 23.11.2017 um 14:00 Uhr (UTC) statt . Sie können Ihre Bots vorher beliebig ändern.
quelle
Antworten:
hard_coded
Dieser Bot ist das Ergebnis von Gentraining gegen viele andere Pseudo-Zufalls-Bots (und einige der Bots in anderen Antworten). Ich habe am Ende einige Zeit mit der Feinabstimmung verbracht, aber die Struktur ist eigentlich sehr einfach.
Die Entscheidungen stützen sich nur auf einen festgelegten Parametersatz und nicht auf das Ergebnis früherer Runden.
Der Schlüssel scheint die erste Runde zu sein: Man muss All-In gehen, 500 zu bieten ist der sichere Zug. Zu viele Bots versuchen, den ersten Zug zu überlisten, indem sie 499 oder 498 bieten. Wenn Sie die erste Runde gewinnen, haben Sie einen großen Vorteil für den Rest der Auktion. Sie sind nur 500 Dollar im Rückstand und haben Zeit, sich zu erholen.
Eine sichere Wette in der zweiten Runde ist etwas mehr als 990, aber selbst wenn Sie 0 bieten, erhalten Sie ein gutes Ergebnis. Zu hohe Gebote und Gewinne könnten schlimmer sein, als diese Runde zu verlieren.
In der dritten Runde hören die meisten Bots auf zu eskalieren: 50% von ihnen haben mittlerweile weniger als 1500 Dollar, sodass Sie in dieser Runde kein Geld verschwenden müssen. 1170 ist ein guter Kompromiss. Gleiches in der vierten Runde. Wenn Sie die ersten drei verloren haben, können Sie diese sehr billig gewinnen und haben immer noch genug Geld für die nächste.
Danach beträgt das durchschnittliche Geld, das benötigt wird, um eine Runde zu gewinnen, 1500 Dollar (was die logische Schlussfolgerung ist: Jeder gewinnt inzwischen eine Runde von vier, weniger zu bieten, um später zu gewinnen, ist nur Geldverschwendung, die Situation hat sich stabilisiert und es ist einfach rund. Robin von nun an).
Die letzte Runde muss All-In sein, und die anderen Parameter sind genau abgestimmt, um die letzte Runde zu gewinnen, indem bis dahin so niedrig wie möglich geboten wird.
Viele Bots versuchen, die neunte Runde zu gewinnen, indem sie mehr als 2000 Dollar bieten. Deshalb habe ich das berücksichtigt und versucht, sie zu überbieten (ich kann sowieso nicht beide Runden gewinnen, und die letzte wird schwieriger).
quelle
Überdurchschnittlich
Gebote über dem durchschnittlichen Geldbetrag der anderen Spieler. Bietet alles in der letzten Runde.
quelle
Ich tue nicht einmal
Nimmt nur an ungeraden und letzten Runden teil.
quelle
Der vergessliche Bot weiß nicht, wie viel Geld er hat, also setzt er nur das Geld ein, das er für diese Runde erhalten hat. Wenn er am Ende etwas Geld findet, spendet er es einfach an eine Wohltätigkeitsorganisation.
quelle
One Upper
Ich weiß nicht viel über Python, daher könnte ich einen Fehler machen
bietet 1 höher als das vorherige Gewinngebot oder geht in der letzten Runde All-in.
Ich kann mich in Zukunft für eine andere Strategie entscheiden, wenn
win_amount
-1 istquelle
Patient Bot
Bietet nichts für die ersten fünf Runden, bietet dann ~ 1000 Dollar für die nächsten vier Runden und bietet schließlich alles, was es in der letzten Runde hat.
quelle
Nachahmer oder traurig
Dritter und letzter Bot.
Dieser Bot bietet genau den gleichen Betrag wie der vorherige Gewinner (einschließlich sich selbst). Wenn es jedoch nicht genug Geld dafür hat, wird es traurig sein und stattdessen einen miesen 1-Dollar-Schein mit seiner Träne drauf bieten. In der letzten Runde geht es All-In.
Ich programmiere nie in Python. Wenn Sie also Fehler sehen, lassen Sie es mich wissen.
quelle
-1
auf die erste Auktion.Testlauf
Ich habe einen früheren von Steadybox zusammengestellten Testlauf bearbeitet und die neuesten Einsendungen hinzugefügt.
Ich poste es hier, damit es einen Ort gibt, an dem der Link mit neueren Versionen aktualisiert werden kann. Dieser Beitrag ist ein Community-Wiki. Sie können ihn also jederzeit aktualisieren, wenn Sie einen neuen Beitrag posten, einen alten ändern oder einfach etwas sehen neu von einem anderen Beitrag!
Hier ist der Link zum Testlauf! (TIO)
quelle
Zur Hälfte
Dieser Bot bietet immer die Hälfte von dem, was er übrig hat, außer in der letzten Runde, in der er alles geben wird.
Ich programmiere nie in Python. Wenn Sie also Fehler sehen, lassen Sie es mich wissen.
quelle
Graylist
Inspiriert von der Blacklist-Einreichung des Histokraten , behält dieser Bot alle vorherigen Gewinnwetten anderer Spieler im Gedächtnis, sowohl als Verhältnis des Geldes zu ihrem vollen Geld als auch als Differenz zwischen ihrem Einsatzbetrag und dem vollen Betrag. Um eine Niederlage zu vermeiden (was anscheinend ein wichtiger Faktor in diesem Wettbewerb ist), wird darauf verzichtet, eine beliebige Zahl zu setzen, die bei den aktuellen Geldern des Gegners zu den gleichen Ergebnissen führen könnte.
BEARBEITEN: Als Startwert für das Gebot wird nun das Minimum zwischen dem aktuellen Geld, 1 mehr als das Geld des reichsten Gegners, X mehr als die letzte Gewinnwette oder Y mehr als das durchschnittliche Geld seiner Gegner verwendet. X und Y sind Konstanten, die wahrscheinlich vor dem Ende des Wettbewerbs geändert werden.
quelle
AverageMine
Dieser Spieler berechnet den Prozentsatz (Gebot / Gesamtgeld) für den Gewinner jeder Runde und bietet seinen (Gesamtgeld * durchschnittlicher Gewinnprozentsatz + 85), sofern er nicht mehr Geld hat als alle anderen Spieler, dann bietet er 1 mehr als der höchste Konkurrent . Beginnt mit einem Gebot von 99,0% des Startbetrags.
quelle
Eenie Meanie More
Dieser Spieler ist mit Ausnahme einer Variablen mit Meanie identisch. Diese Version bietet aggressiver und veranlasst einige Spieler, mehr Geld auszugeben, als Meanie für die Auktion wert hält.
quelle
Verteiler
Wenn dieser Bot eine Runde verliert, verteilt er das überschüssige Geld auf alle nächsten Runden. Er setzt in der ersten Runde 499 $ ein und denkt, dass die anderen mit 500 $ gleichziehen und eliminiert werden.
quelle
rounds
anstelle vonself.rounds
führt zu Fehlern. Gleiche mitmoney
.Meanie
Dieser Spieler erhält das gesamte Geld, das in das Spiel kommt, um das Durchschnittsgebot für die Anzahl der Spieler und verbleibenden Runden zu erhalten. Wenn dieses Ziel höher ist als das aller anderen Spieler, senkt es sein Gebot auf den Kontostand seines größten Konkurrenten plus eins. Wenn sich der Spieler sein Ziel nicht leisten kann, ist er All-In.
quelle
Schlage den Sieger
Bieten Sie 1 mehr als der Spieler mit den meisten Gewinnen
quelle
m,w
in der richtigen Reihenfolge?Minus eins
quelle
Bieten Sie höher
Lerne noch Python; Bieten Sie etwas höher als der letzte Gewinner.
quelle
inc = 100
zuinc = 101
.FiveFiveFive
Überspringt die erste Runde und bietet in den verbleibenden Runden 555 $. In der letzten Runde geht alles rein, es sei denn, 2 andere Bots haben den gleichen Betrag (und binden vermutlich aus).
quelle
Fast alles in
Bietet immer etwas weniger als es hat.
quelle
Schnell eskalieren
Bietet mehr Bruchteile seines Geldes pro Runde (bitte lassen Sie mich wissen, wenn Fehler aufgetreten sind, seit ich Python verwendet habe)
quelle
Unterdurchschnittlich
Ähnlich wie überdurchschnittlich, geht aber etwas tiefer
quelle
Hohes Ross
Dieser Spieler bietet sein gesamtes Geld abzüglich der aktuellen Rundenanzahl, außer in der letzten Runde, in der er All-In geht.
quelle
Swapper
Wechselt zwischen Bieten unter seinem Maximum und All-In.
Ich dachte, ich müsste etwas finden, das Steadybox 'minus_one übertreffen könnte. :)
quelle
Modulare Blacklist
Setzt den höchsten Betrag, der nicht mit dem Modulo 500 kongruent ist, auf eine zuvor gesehene Zahl.
Bearbeitet, um die schwarze Liste nicht anzuwenden, wenn ein garantierter Gewinn erzielt werden kann.
quelle
blacklist_mod
ist Fünfter in der Rangliste , währendblacklist
auf dem zweiten Platz. Wirdblacklist
stattdessen die ältere Version von verwendet,blacklist
fällt der auf den sechsten Platz,blacklist_mod
übernimmt aber die Führung !blacklist
wegzuwerfen scheintblacklist_mod
eine noch solidere Führung zu geben , aber das ist nicht schlüssig.Heurist
Der Heurist betrachtet dieses Spiel als ein Spiel mit wiederholbarer Wahrscheinlichkeit, sodass er weiß, wo er die Grenze ziehen muss.
Es ist auch geizig, also bietet es das Nötigste, das für einen Sieg erforderlich ist, wenn es kann.
Haftungsausschluss:
max_bid
Änderungen vorbehaltenquelle
bob_hater
Dieser Bot mag Bob nicht und bietet daher immer 2 $, um gegen Bob zu gewinnen.
quelle
Angeben
Dies ist der Typ, der seine mathematischen Fähigkeiten in Situationen unter Beweis stellt, in denen wirklich nichts so Kompliziertes erforderlich ist. Bis zur letzten Runde (in der er All-In geht) verwendet er ein logistisches Modell, um sein Gebot zu bestimmen, mehr, wenn seine Feinde einen größeren Teil ihres Geldes übrig haben.
Die verwendete Logistikkurve ist f (x) = 1 / (1 + e -8 (x-0,5) ), wobei x das Verhältnis des aktuellen Feindgeldes zum gesamten potenziellen Feindgeld der Runde ist. Je mehr die anderen haben, desto mehr bietet er. Dies hat den möglichen Vorteil, dass in der ersten Runde fast 500 US-Dollar geboten werden.
quelle
AntiMaxer
Kombiniere den höchsten Betrag, den wir uns von allen Spielern leisten können. Wird dazu führen, dass ein Bot, der in dieser Runde All-In geht, aussteigt.
quelle
Einfacher Bot
Fast dasselbe wie Patient Bot, aber nicht als Patient. Erzielt jedoch ein viel besseres Ergebnis.
quelle
Flügelmann 2
Wenn ein Flügelmann gut ist, müssen zwei besser sein?
quelle