Risultato finale
La competizione è finita. Congratulazioni a hard_coded
!
Alcuni fatti interessanti:
In 31600 delle 40920 aste (77,2%), il vincitore del primo round ha vinto il maggior numero di round in quell'asta.
Se nella competizione vengono inclusi esempi di robot, i primi nove posti non cambieranno tranne quello
AverageMine
eheurist
cambieranno le loro posizioni.I 10 migliori risultati in un'asta:
[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
Conteggio Tie (numero di aste che l'i-esimo turno aveva nessun vincitore):
[719, 126, 25, 36, 15, 58, 10, 7, 19, 38]
.Offerta media vincente della i-esimo turno:
[449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1]
.
tabellone segnapunti
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 questo gioco, simuleremo un'asta con offerta sigillata.
Ogni asta è un gioco a 4 giocatori, composto da 10 round. Inizialmente, i giocatori non hanno soldi. All'inizio di ogni round, ogni giocatore riceverà $ 500, quindi farà le proprie offerte. L'offerta può essere qualsiasi numero intero non negativo inferiore o uguale all'importo che hanno. Di solito, chi offre il punteggio più alto vince il round. Tuttavia, per rendere le cose più interessanti, se più giocatori dichiarano lo stesso prezzo, la loro offerta non verrà presa in considerazione (quindi non può vincere il round). Ad esempio, se quattro giocatori dichiarano 400 400 300 200, quello che offre 300 vince; se offrono 400 400 300 300, nessuno vince. Il vincitore dovrebbe pagare ciò che ha offerto.
Dato che si tratta di un'asta "a offerta chiusa", l'unica informazione che il giocatore saprà sull'offerta è il vincitore e quanto ha pagato all'inizio del prossimo round (così il giocatore può sapere quanto tutti hanno).
punteggio
Si terrà un'asta per ogni possibile combinazione di 4 giocatori. Cioè, se ci sono N robot in totale, ci sarà un'asta N C 4 . Il bot che vince il maggior numero di round sarà il vincitore finale. Nel caso in cui ci sia un pareggio, vincerà il bot che ha pagato il minimo. Se c'è ancora un pareggio, allo stesso modo dell'offerta, questi legami verranno rimossi.
Coding
Dovresti implementare una classe Python 3 con una funzione membro play_round
(e __init__
o altre se ne hai bisogno). play_round
dovrebbe prendere 3 argomenti (incluso self). Il secondo e il terzo argomento saranno, in ordine: l'id del vincitore del round precedente, seguito da quanto hanno pagato. Se nessuno vince o è il primo round, saranno entrambi -1. Il tuo ID sarà sempre 0 e l'id 1-3 saranno gli altri giocatori in un ordine determinato solo dalla posizione su questo post.
Regole aggiuntive
1. Deterministico:
il comportamento della tua funzione dovrebbe dipendere solo dagli argomenti di input all'interno di un'asta. Cioè, non è possibile accedere a file, tempo, variabili globali o qualsiasi cosa che memorizzerà gli stati tra aste o robot diversi . Se vuoi usare un generatore pseudocasuale, è meglio scriverlo da solo (per evitare di influenzare i programmi di altri come random
in Python lib), e assicurarti di averlo resettato con un seed fisso nel __init__
primo round.
2. Tre robot per persona: puoi inviare al massimo 3 robot, quindi puoi sviluppare una strategia per "cooperare" in qualche modo.
3. Non troppo lento: poiché ci saranno molte aste, assicurati che i tuoi robot non funzionino troppo lentamente. I tuoi robot dovrebbero essere in grado di completare almeno 1.000 aste in un secondo.
controllore
Ecco il controller che sto usando. Tutti i bot verranno importati e aggiunti bot_list
nell'ordine in questo post.
# 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))
Esempi
Se hai bisogno di un generatore pseudocasuale, eccone uno semplice.
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
Risultato
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
Il vincitore è all_in_bot
. Si noti che zero_bot
e fortytwo_bot
hanno lo stesso punteggio e totale, quindi sono rimossi.
Questi robot non saranno inclusi nella competizione. Puoi usarli se pensi che siano fantastici.
La competizione finale si svolgerà il 23/11/2017 alle 14:00 (UTC) . Prima di allora puoi apportare qualsiasi modifica ai tuoi robot.