最終結果
競争は終わりました。おめでとうございますhard_coded
!
興味深い事実:
40920のオークションのうち31600(77.2%)で、最初のラウンドの勝者がそのオークションで最も多くのラウンドを獲得しました。
例えば、ボットが競争に含まれている場合は、トップ9の場所は点を除いて変更されません
AverageMine
し、heurist
その位置を入れ替えます。オークションの上位10件:
[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
タイ・カウント(i番目のラウンドは何の勝者がなかったことをオークションの数):
[719, 126, 25, 36, 15, 58, 10, 7, 19, 38]
。i番目のラウンドの平均落札価格:
[449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1]
。
スコアボード
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
このゲームでは、封印された入札オークションをシミュレートします。
各オークションは4プレイヤーゲームで、10ラウンドで構成されています。最初は、プレイヤーにはお金がありません。各ラウンドの開始時に、各プレイヤーは$ 500を獲得し、独自の入札を行います。入札は、負の整数で、金額よりも小さいか等しい場合があります。通常、最高額の入札者がラウンドに勝ちます。しかし、物事をより面白くするために、複数のプレイヤーが同じ価格で入札した場合、入札は考慮されません(したがって、ラウンドに勝つことはできません)。たとえば、4人のプレイヤーが400 400 300 200を入札した場合、1人が300を入札します。400 400 300 300を入札した場合、誰も勝ちません。勝者は、入札した金額を支払う必要があります。
これは「封印入札」オークションであるため、プレイヤーが入札について知る唯一の情報は勝者であり、次のラウンドの開始時に支払った金額です(したがって、プレイヤーは全員がどれだけ持っているかを知ることができます)。
得点
4人のプレーヤーの組み合わせごとに1つのオークションが開催されます。つまり、合計でボットがN個ある場合、N C 4オークションが行われます。最も多くのラウンドに勝ったボットが最終的な勝者になります。同点の場合、合計で最低額を支払ったボットが勝ちます。入札と同じように、まだ同点がある場合、それらの同点は削除されます。
コーディング
メンバー関数を使用してPython 3クラスを実装する必要がありますplay_round
(__init__
または必要に応じて他のクラス)。play_round
3つの引数(selfを含む)を取る必要があります。2番目と3番目の引数は順番に、前のラウンドの勝者のIDに続いて、彼らが支払った金額です。誰も勝てないか、それが最初のラウンドである場合、両方とも-1になります。IDは常に0で、ID 1–3はこの投稿の位置によってのみ決定される順序で他のプレイヤーになります。
追加のルール
1.確定的:
関数の動作は、オークション内の入力引数のみに依存する必要があります。つまり、ファイル、時間、グローバル変数、または異なるオークションやボット間で状態を保存するものにはアクセスできません。擬似乱数ジェネレーターを使用する場合は、自分で作成して(random
Python libのような他のユーザーのプログラムに影響を与えないようにする)、固定シード__init__
または最初のラウンドでリセットするようにしてください。
2. 1人あたり3つのボット: 最大3つのボットを送信できるため、何らかの方法でボットを「連携」させる戦略を開発できます。
3.遅すぎない: 多くのオークションがあるので、ボットが遅くなりすぎないようにしてください。ボットは、1秒で少なくとも1,000のオークションを完了できる必要があります。
コントローラ
これが私が使用しているコントローラーです。すべてのボットがインポートされbot_list
、この投稿の順序で追加されます。
# 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))
例
擬似乱数ジェネレーターが必要な場合、簡単なものを以下に示します。
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
結果
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
勝者はall_in_bot
です。なお、zero_bot
及びfortytwo_bot
それらを削除しているので、同じスコアと合計を持っています。
これらのボットはコンテストに含まれません。あなたが彼らが素晴らしいと思うなら、あなたはそれらを使うことができます。
最終コンペは2017/11/23 14:00(UTC)に開催されます。それ以前にボットに変更を加えることができます。