最初の価格の密封入札オークション


32

最終結果

競争は終わりました。おめでとうございます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_round3つの引数(selfを含む)を取る必要があります。2番目と3番目の引数は順番に、前のラウンドの勝者のIDに続いて、彼らが支払った金額です。誰も勝てないか、それが最初のラウンドである場合、両方とも-1になります。IDは常に0で、ID 1–3はこの投稿の位置によってのみ決定される順序で他のプレイヤーになります。


追加のルール

1.確定的: 関数の動作は、オークション内の入力引数のみに依存する必要があります。つまり、ファイル、時間、グローバル変数、または異なるオークションやボット間で状態を保存するものにはアクセスできません。擬似乱数ジェネレーターを使用する場合は、自分で作成して(randomPython 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)に開催されます。それ以前にボットに変更を加えることができます。


5
彼らは各ラウンドで500ドルを受け取るのですか、それとも各オークション(10ラウンド続く)ですか?
スティーヴィーグリフィン

1
@KamilDrakariコンテストは、問題のあるボットをリストから削除して再開されます。
コレラ蘇

4
@Shufflepants本当ですが、これは常にKotHチャレンジの場合です。過去に、一部の人々は実際に最後までボットを作成し、それまでのすべてのボットに対抗しました。しかし、これはKotHスタイルの課題の一部にすぎません。そして、これを含むほとんどのKotHチャレンジの動作方法では、利点はそれほど大きくはありません。同時に多くのボットにしか対抗することはできません。素敵な最初の挑戦、コレラスーPPCGへようこそ!結果を楽しみにしています。:)
ケビンクルーイッセン

4
以下は、現在のすべてのボットを使用したTIOでのテスト実行です。
Steadybox

2
それは...現時点でタイトなレースだ
ザイド

回答:


13

hard_coded

class hard_coded:
  def __init__(self):
    self.money = 0
    self.round = 0

  def play_round(self, did_i_win, amount):
    self.money += 500
    self.round += 1
    if did_i_win == 0:
      self.money -= amount
    prob = [500, 992, 1170, 1181, 1499, 1276, 1290, 1401, 2166, 5000][self.round - 1]
    if prob > self.money:
      return self.money
    else:
      return prob    

このボットは、他の多くの擬似ランダムボット(および他の回答のボットの一部)に対する遺伝子トレーニングの結果です。最後に微調整に時間を費やしましたが、その構造は実際には非常に単純です。

決定は、前のラウンドの結果ではなく、パラメーターの固定セットのみに基づいています。

キーが最初のラウンドのようです。オールインする必要があります。入札500は安全な動きです。499または498を入札して、最初の動きをしのいでいるボットが多すぎます。最初のラウンドに勝つと、残りのオークションで大きな利点が得られます。あなたはたった500ドル遅れており、回復する時間があります。

2回目のラウンドでの安全な賭けは990を少し超えていますが、0を入札しても良い結果が得られます。入札単価が高すぎて勝つことは、このラウンドを失うことよりも悪い場合があります。

3回目のラウンドでは、ほとんどのボットはエスカレートを停止します。それらの50%は今では1500ドル未満なので、このラウンドでお金を無駄にする必要はありません。1170は良いトレードオフです。第4ラウンドでも同じこと。最初の3つを失った場合、この1つを非常に安く獲得できますが、次の3つに十分なお金があります。

その後、ラウンドに勝つために必要な平均お金は1500ドルです(これは論理的な結論です:誰もが4つのうちのラウンドに勝ち、後で勝つために入札するのはお金を無駄にしているだけで、状況は安定しており、ただラウンドですこれからはロビン)。

最終ラウンドはオールインである必要があり、他のパラメーターは、それまで可能な限り低く入札して最終ラウンドに勝つように微調整されます。

多くのボットは、2000ドル以上の入札で9回戦に勝とうとするので、それを考慮に入れて、それらをオーバービッドしようとします(とにかく最後の2回のラウンドの両方に勝つことはできません。


1
まあ、それは勝つための一つの方法です。おめでとうございます!
ルカH

しかし、私は他の提案がもっと好きだと認めなければなりません。他のボットに勝つ方法は試していないが、ランダムなボットに対する良い戦術になる可能性があるもの。
ルカH

私は理解することができます、私はいくつかの他の提出物が好きで(そして賛成しました)、これは有限領域での問題であり、多くの提出物はあまりにも複雑です。問題の中心は10個の数字のシーケンスを生成することなので、一般的な手順を見つけるのではなく、特定のドメイン用に最適化することを選択しました。私はエンジニアであり、数学者ではありません。
GB

2
@LucaHアプローチの見かけの単純さは、この特定の数のセットに到達するために必要な作業量とは異なります。私は、統計的な観点から、私自身のボットと同じようなことをしようとしていた、そしてそれは容易ではありませんでした
ザイド

1
@Zaidにはもちろん多くの作業がありますが、ブルートフォーシングはまさにそうです...ブルート;)
ルカH

12

平均以上

他のプレイヤーが持っている平均金額を上回る入札。最終ラウンドですべてに入札します。

class above_average:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
    if self.round == 10:
      return self.player_money[0]
    bid = sum(self.player_money[1:]) / 3 + 1
    if bid > self.player_money[0]:
      return self.player_money[0]
    return min(self.player_money[0], bid)

12

私もしない

class I_Dont_Even:
	def __init__(self):
		self.money = 0
		self.round = 0
	def play_round(self, loser, bid):
		self.money += 500 - (not loser) * bid
		self.round += 1
		return self.money * (self.round & 1 or self.round == 10)

奇数ラウンドと最終ラウンドのみに参加します。


7

忘れっぽいボットは、自分がどれだけのお金を持っているかわからないので、このラウンドのために与えられたお金を入れるだけです。彼が最後にいくらかのお金を持っているとわかるならば、彼はただそれを慈善団体に寄付します。

class forgetful_bot:
  def play_round(self, winner, amt):
    return 500

15
私はdownvoterないんだけど、多分それはあなたが入れていない原因である任意のあなたのボットへの努力を
ミーシャ

9
これが最初の答えの1つです。ボールを転がすには何かが必要です。
クルドラエセスナバルヤ

私はダウン投票しませんでしたが、おそらくボールを転がすために何かが必要だったとしても、もう少し面白いことをしたからでしょうか?特に、これは一種の開始に使用されたOne Dollar Bobと実質的に同一であるため、
HyperNeutrino

7

ワンアッパー

私はPythonについてあまり知らないので、何らかのエラーを起こすかもしれません

class one_upper:
    def __init__(self): 
        self.money = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.money += 500
        if winner == 0: self.money -= win_amount
        self.round += 1
        bid = win_amount + 1
        if self.money < bid or self.round == 10:
            bid = self.money
        return bid

前回の落札価格よりも1高く入札するか、最終ラウンド中にオールインします。

将来的にwin_amountは-1の場合に異なる戦略を決定する可能性があります


7

患者ボット

class patient_bot:
    def __init__(self):
        self.round = 0
        self.money = 0
    def rand(self, seed, max):
        return (394587485 - self.money*self.round*seed) % (max + 1)
    def play_round(self, winner, amount):
        self.round += 1
        self.money += 500
        if winner == 0:
            self.money -= amount
        if self.round < 6:
            return 0
        else:
            bid = 980 + self.rand(amount, 35)
            if self.money < bid or self.round == 10:
                bid = self.money
            return bid

最初の5ラウンドには何も入札せず、次の4ラウンドには約1000ドルを入札し、最後のラウンドには最終的にすべての入札を行います。


7

模倣または悲しい

3番目と最後のボット。
このボットは、以前の勝者(それ自体を含む)とまったく同じ金額で入札します。ただし、現金が足りない場合は悲しいことになり、代わりに涙を浮かべてわずか1ドルの紙幣を入札します。最終ラウンドではオールインします。

class copycat_or_sad:
  def __init__(self):
    self.money = 0
    self.round = -1
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # If it's the final round: bid all-in
    if self.round == 9:
      return self.money
    # Else-if there was no previous winner, or it doesn't have enough money left: bid 1
    if win_amount < 1 or self.money < win_amount:
      return 1
    # Else: bid the exact same as the previous winner
    return win_amount

Pythonでプログラミングすることはありませんので、間違いがあったら教えてください。


2
これ-1は最初のオークションに入札します。
Okx

7

試運転

Steadyboxによってまとめられた前回のテスト実行を編集して、最新の提出を追加しました。

ここに投稿しているので、リンクをより新しいバージョンに更新できる場所があります。この投稿はコミュニティWikiですので、新しい投稿を投稿したり、古い投稿を変更したり、単に何かを見る場合は気軽に更新してください他の投稿から新しい!

これがテスト実行へのリンクです!(TIO)


破壊的であることが意図されていたボットが2つの「本物の」提出物を打ち負かすことに落ち込んでいるはずですか?
thegreatemu

@thegreatemuボットが互いにどのように相互作用するかを見るのは興味深いです。単一の新しいボットがランキングを劇的に変える可能性があります。私が見つけた興味深いことは、histoccratの削除されたブラックリストボットが参加すると、私の2つのボットがランキングのトップに移動することです。:)
ジョー。

6

ハーフイン

このボットは、最後のラウンドを除いて、常に残っているものの半分を入札します。

class half_in:
  def __init__(self):
    self.money = 0
    self.round = -1
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # If it's the final round: bid all in
    if self.round == 9:
      return self.money
    # Else: Bid half what it has left:
    return self.money / 2

Pythonでプログラミングすることはありませんので、間違いがあったら教えてください。


6

グレーリスト

class Graylist:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
    self.ratios = {1}
    self.diffs = {0}
  def play_round(self, winner, winning_bid):
    self.round += 1
    if winner != -1:
      if winner >0 and winning_bid>0:
        self.ratios.add(self.player_money[winner]/winning_bid)
        self.diffs.add(self.player_money[winner]-winning_bid)
      self.player_money[winner] -= winning_bid
    self.player_money = [x+500 for x in self.player_money]
    tentative_bid = min(self.player_money[0],max(self.player_money[1:])+1, winning_bid+169, sum(self.player_money[1:])//3+169)
    while tentative_bid and (tentative_bid in (round(m*r) for m in self.player_money[1:] for r in self.ratios)) or (tentative_bid in (m-d for m in self.player_money[1:] for d in self.diffs)):
      tentative_bid = tentative_bid - 1
    return tentative_bid

histocratによるブラックリストの提出に触発されて、このボットは、他のプレーヤーの以前の勝ちの賭け金すべてを、彼らが賭けたお金と彼らの賭け金との比、および賭け金と全額の差として記憶します。同点で負けないようにするため(これは実際にこの競争で大きな要因になります)、対戦相手の現在のお金を考えると同じ結果をもたらす数字を賭けることを避けます。

編集:入札の開始値は、現在のお金、最も裕福な相手のお金よりも1多い、最後の勝ちの賭けよりもX大きい、または相手の平均お金より多いYの間の最小値を使用するようになりました。XとYは、おそらく競技終了前に変更される定数です。


6

AverageMine

このプレイヤーは、各ラウンドの勝者の割合(入札/合計金額)を計算し、他のすべてのプレイヤーよりも多くのお金がない限り、(合計金額*平均勝率+ 85)を入札します。 。開始金額の99.0%の入札で始まります。

class AverageMine:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0
        self.average = 0
    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            if i == winner:
                self.average = (self.average * (self.round - 2) + (win_amt / self.money[i])) / (self.round - 1)
                self.money[i] -= win_amt
                self.wins[i] += 1
            self.money[i] += 500
        if self.round == 1:
            return int(0.990 * self.money[0])
        elif self.round < self.maxrounds:
            if self.money[0] > self.money[1] + 1 and self.money[0] > self.money[2] + 1 and self.money[0] > self.money[3] + 1:
                return max(self.money[1],self.money[2],self.money[3]) + 1
            bid = int(self.average * self.money[0]) + 85
            return min(self.money[0],bid)
        else:
            bid = self.money[0]
            return bid

6

イーニー・ミーニー・モア

このプレーヤーは、1つの変数を除いてMeanieと同じです。このバージョンはより積極的に入札し、一部のプレーヤーはオークションが価値があると思うよりも多くを費やすことになります。

class eenie_meanie_more:
    def __init__(self):
        self.money = [0] * 4
        self.rounds = 11
        self.total_spent = 0

    def play_round(self, winner, winning_bid):
        self.money = [x+500 for x in self.money]
        self.rounds -= 1
        if winner != -1:
            self.money[winner] -= winning_bid
            self.total_spent += winning_bid
        bid = 500
        if self.rounds > 0 and self.total_spent < 20000:
            bid = int((20000 - self.total_spent)/self.rounds/4)+440
        return min(bid, max(self.money[1:])+1, self.money[0])

5

ディストリビューター

このボットがラウンドに負けると、彼は次のすべてのラウンドに余分な現金を分配します。彼は、他の人が500ドルと結びついて排除されると考えて、最初のラウンドに499ドルを投入します。

class distributer:
  def __init__(self):
    self.money = 0
    self.rounds = 11
  def play_round(self, winner, amt):
    self.money += 500
    self.rounds -= 1
    if self.rounds == 10:
      return 499
    if winner == 0:
      self.money -= amt
    return ((self.rounds - 1) * 500 + self.money) / self.rounds

1
rounds代わりに使用self.roundsするとエラーが発生します。と同じmoney
ジェレミーワイリッヒ

5

ミーニー

このプレーヤーは、プレーヤーの数と残りのラウンドで平均入札額を得るためにプレーに入る合計金額を受け取ります。このターゲットが現在保持している他のすべてのプレーヤーよりも大きい場合、最大の競合他社と1のバランスまで入札を引き下げます。プレーヤーがターゲットを買う余裕がない場合、オールインです。

class meanie:
    def __init__(self):
        self.money = [0] * 4
        self.rounds = 11
        self.total_spent = 0

    def play_round(self,winner,winning_bid):
        self.money = [x+500 for x in self.money]
        self.rounds -= 1
        if winner != -1:
            self.money[winner] -= winning_bid
            self.total_spent += winning_bid
        bid = 500
        if self.rounds > 0 and self.total_spent < 20000:
            bid = int((20000 - self.total_spent)/self.rounds/4)+1
        return min(bid,max(self.money[1:])+1,self.money[0])

5

勝者を倒す

これまでで最も勝ったプレーヤーよりも1多い入札

class BeatTheWinner:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        mymoney = self.money[0]
        for w,m in sorted(zip(self.wins, self.money),reverse=True):
            if mymoney > m:
                return m+1
        #if we get here we can't afford our default strategy, so
        return int(mymoney/10)

4
あなたのあるm,w正しい順序で?
ジョー。

5

マイナスワン

class minus_one:
    def __init__(self):
        self.money = 0
    def play_round(self, winner, amount):
        self.money += 500
        if winner == 0:
            self.money -= amount
        return self.money - 1

5

より高い入札

class bid_higher:
    def __init__(self):
        self.dollar = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.dollar += 500
        self.round += 1
        inc = 131
        if winner == 0: self.dollar -= win_amount
        if self.round == 10: return self.dollar
        if win_amount == 0: win_amount = 500
        if self.dollar > (win_amount + inc):
            return win_amount + inc
        else:
            if self.dollar > 1:
                return self.dollar -1
            else:
                return 0

まだPythonを学習しています。最後の勝者より少し高い入札。


PPCGへようこそ!に変更inc = 100すると、ボットのスコアがさらに向上するようですinc = 101
-Steadybox

私はここで自分の興味に反していますが、ターンを追跡し、最終ラウンドでオールインすることで簡単にスコアを向上させることができます;)
レオ

提案をありがとう; 最終ラウンドオールインを追加し、増分を微調整し、このボットにブーストを与えるためにウィングマンボットをいくつか追加しました
。– rancid_banana

こんにちは、私はあなたが気にしないことを望みますが、私は現在のすべての提出でテストベンチをまとめていました、そしてあなたのコードが最後のラウンドで時々無効な値を返すことがわかったので、再配置することでバグを修正しました注文数行。持っていないものを変更した場合は申し訳ありません。変更を元に戻し、別の方法でバグを修正してください。
レオ

@レオ:問題はありません、興味をお持ちいただきありがとう
ござい

4

ファイブファイブファイブ

最初のラウンドをスキップし、残りのラウンドで555ドルを入札します。最後のラウンドでは、他の2つのボットの量が同じでない限り、オールインします(おそらくタイアウトします)。

class FiveFiveFive:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        if self.round == 1:
            return 0
        elif self.round < self.maxrounds:
            return min(555, self.money[0])
        else:
            bid = self.money[0]
            return bid if self.money.count(bid) < 3 else bid-1

4

ほとんどすべて

class Almost_All_In:
	def __init__(self):
		self.money = 0
		self.round = 0
	def play_round(self, loser, bid):
		self.money += 500 - (not loser) * bid
		self.round += 1
		return self.money - self.round % 3 * 3 - 3

入札単価は常にそれよりわずかに低くなります。


4

迅速なエスカレーション

毎回、そのお金の割合を増やして入札します(Pythonを使用してからしばらくの間、エラーがある場合はお知らせください)

class escalating:
  def __init__(self):
    self.money = 0
    self.round = 0
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # bid round number in percent times remaining money, floored to integer
    return self.money * self.round // 10

4

平均以下の

上記の平均に似ていますが、少し低くなります

class below_average:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
    if self.round == 10:
      return self.player_money[0]
    bid = sum(self.player_money[1:]) / 3 - 2
    if bid > self.player_money[0]:
      return self.player_money[0]
    return min(self.player_money[0], bid)

4

ハイホース

このプレイヤーは、最後のラウンドを除き、すべてのお金から現在のラウンド数を引いた額を入札します。

class HighHorse:
    maxrounds = 10
    def __init__(self):
        self.money = 0
        self.round = 0
    def play_round(self, winner, win_amt):
        self.round += 1
        if 0 == winner:
            self.money -= win_amt
        self.money += 500
        if self.round < self.maxrounds:
            return self.money - self.round
        else:
            bid = self.money
            return bid

4

スワッパー

彼の最大値以下で入札することと、オールインすることを交互に行います。

class Swapper:
    def __init__(self):
        self.money = 0
        self.round = 0
    def play_round(self, loser, bid):
        self.money += 500 - (not loser) * bid
        self.round += 1
        if self.round & 1:
            return self.money - 1
        return self.money

Steadyboxのminus_oneを打ち負かすことができる何かを見つける必要があると考えました。:)


4

モジュラーブラックリスト

class blacklist_mod:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
    self.blacklist = {0, 499}
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
      self.blacklist.add(winning_bid % 500)
      self.blacklist |= {x % 500 for x in self.player_money[1:]}
    tentative_bid = self.player_money[0]
    autowin = max(self.player_money[1:])+1
    if tentative_bid < autowin:
      while tentative_bid and (tentative_bid % 500) in self.blacklist:
        tentative_bid = tentative_bid - 1
    else:
      tentative_bid = autowin
    self.blacklist.add(tentative_bid % 500)
    return tentative_bid

500を法とする合同でない最高額を、以前に見られた数字にベットします。

保証された勝利を得ることができるときにブラックリストを適用しないように編集されました。


興味深いことに、他のボットの最新の更新がこのボットに悪影響を及ぼしているようです。現在、blacklist_mod第五でリーダーボード上のに対し、blacklist第二位です。blacklist代わりにの古いバージョンが使用されている場合、blacklist6位になりblacklist_mod ますが、リードします!
-Steadybox

投げるblacklist完全にアウトしているようだ与えるためにblacklist_modも、より強固なリードを、それは決定的です。
Steadybox

ああ、ありがとう、それは理にかなっています-彼らは古い特別なケースのロジックなしで早い段階で同じアルゴリズムに近いので、お互いの足指を踏みます。元のボットを削除するだけだと思います。私はそれを維持する正当な理由を考えることができません。
-histocrat

4

発見者

Heuristは、それがどこのラインを描画するために知っているので、再現性の確率の一つとしてこのゲームを扱います。

また、それは悲惨であるため、可能な場合に勝つために必要な最低限を入札します。

class heurist:
    def __init__(self):
        self.money = 0
        self.round = -1
        self.net_worth = [0] * 4
    def play_round(self, winner, bid):
        self.round += 1
        self.money += 500
        if winner == 0: self.money -= bid
        if winner != -1: self.net_worth[winner] -= bid
        self.net_worth = [x+500 for x in self.net_worth]
        max_bid = [498,1000,1223,1391,1250,1921,2511,1666,1600,5000][self.round]
        if self.money > max_bid:
            return 1 + min(max_bid,max(self.net_worth[1:3]))
        else:
            return self.money

免責事項:max_bid変更される場合があります


4

bob_hater

このボットはボブを好まないため、ボブに勝つために常に2ドルを入札します。

class bob_hater:
    def play_round(bob,will,loose):
        return 2

4

見せびらかす

これは、それほど複雑なものを本当に必要としない状況で数学の能力を誇示する男です。彼がオールインする最後のラウンドまで、彼は敵がより多くのお金を残している場合は、ロジスティックモデルを使用して入札を決定します。

class Showoff:
  def __init__(self):
      self.moneys = [0, 0, 0]
      self.roundsLeft = 10
  def play_round(self, winner, winning_bid):
      import math
      self.moneys = [self.moneys[0] + 500,
                     self.moneys[1] + 1500,
                     self.moneys[2] + 1500]
      self.roundsLeft -= 1
      if winner > 0:
          self.moneys[1] -= winning_bid
      if winner == 0:
          self.moneys[0] -= winning_bid
      if self.roundsLeft == 0:
          return self.moneys[0]
      ratio = self.moneys[1] / self.moneys[2]
      logisticized = (1 + (math.e ** (-8 * (ratio - 0.5)))) ** -1
      return math.floor(self.moneys[0] * logisticized)

使用されるロジスティック曲線はf(x)= 1 /(1 + e -8(x-0.5))です。ここで、xは、ラウンドの潜在的な敵マネーの合計に対する現在の敵マネーの比率です。他の人が多いほど、彼はより多くの入札をします。これには、1回目のラウンドでほぼ500ドルの入札が可能なメリットがあります。


3

アンチマックス

すべてのプレーヤーのお金の余裕がある最高額に一致します。そのラウンドでオールインするボットはすべてタイアウトします。

class AntiMaxer:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        return max((m for m in self.money[1:] if m<=self.money[0]),
                   default=0)    

3

シンプルボット

class simple_bot:
    def __init__(self):
        self.round = 0
        self.money = 0
    def rand(self, seed, max):
        return (394587485 - self.money*self.round*seed) % (max + 1)
    def play_round(self, winner, amount):
        self.round += 1
        self.money += 500
        if winner == 0:
            self.money -= amount
        bid = 980 + self.rand(amount, 135)
        if self.money < bid or self.round == 10:
            bid = self.money
        return bid

患者ボットとほぼ同じですが、患者ではありません。しかし、それよりもはるかに良いスコアを取得します。


3

ウィングマン2

1人のウィングマンが良ければ、2人がより良いに違いない?

class wingman_2:
    def __init__(self):
        self.dollar = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.round += 1
        self.dollar += 500
        inc = 129
        if win_amount == 0: win_amount = 500
        if winner == 0: self.dollar -= win_amount
        if self.round == 10: return self.dollar
        if self.dollar > win_amount + inc:
            return win_amount + inc
        else:
            if self.dollar > 1: return self.dollar -1
            else:
                return 0

クラスの内容にインデントが必要なため、コードが機能しません
-HyperNeutrino

興味深いことに、両方のウィングマンが元のボットに勝っているようです(pastebinリンクにはTIOリンクが含まれており、コメントに投稿するには長すぎ、URL短縮サービスには長すぎます...)
Steadybox

1
結果は他のボットのプールに非常に敏感であることがわかりました。増分値の小さな変更は、不均衡な結果をもたらすようです。
rancid_banana
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.