Lelang penawaran tertutup rapat harga pertama


32

Hasil akhir

Persaingan berakhir. Selamat untuk hard_coded!

Beberapa fakta menarik:

  • Dalam 31600 dari 40.920 lelang (77,2%), pemenang putaran pertama memenangkan putaran terbanyak dalam lelang itu.

  • Jika contoh bot disertakan dalam kompetisi, sembilan tempat teratas tidak akan berubah kecuali itu AverageMinedan heuristakan bertukar posisi mereka.

  • 10 hasil teratas dalam pelelangan:

[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 count (jumlah lelang bahwa i th putaran tidak pemenang): [719, 126, 25, 36, 15, 58, 10, 7, 19, 38].

  • Rata-rata tawaran yang menang dari i th putaran: [449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1].

Papan angka

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

Dalam game ini, kami akan mensimulasikan lelang penawaran tertutup.

Setiap lelang adalah permainan untuk 4 pemain, terdiri dari 10 putaran. Awalnya, pemain tidak punya uang. Di awal setiap putaran, setiap pemain akan mendapatkan $ 500, dan kemudian membuat tawaran mereka sendiri. Tawaran dapat berupa bilangan bulat non-negatif yang kurang atau sama dengan jumlah yang mereka miliki. Biasanya, orang yang mengajukan penawaran tertinggi memenangkan ronde. Namun, untuk membuat segalanya lebih menarik, jika beberapa pemain menawar harga yang sama, tawaran mereka tidak akan diperhitungkan (sehingga tidak dapat memenangkan putaran). Misalnya, jika empat pemain menawar 400 400 300 200, yang satu menawar 300 menang; jika mereka menawar 400 400 300 300, tidak ada yang menang. Pemenang harus membayar apa yang mereka tawaran.

Karena ini adalah lelang "penawaran tertutup", satu-satunya pemain informasi yang akan tahu tentang penawaran adalah pemenang dan berapa banyak yang mereka bayarkan ketika putaran berikutnya dimulai (sehingga pemain dapat mengetahui berapa banyak yang dimiliki setiap orang).


Mencetak gol

Satu lelang akan diadakan untuk setiap kemungkinan kombinasi 4 pemain. Artinya, jika ada N bot di total, akan ada N C 4 lelang. Bot yang memenangkan putaran terbanyak akan menjadi pemenang akhir. Jika ada dasi, bot yang membayar paling sedikit secara total akan menang. Jika masih ada ikatan, dengan cara yang sama seperti penawaran, ikatan tersebut akan dihapus.


Coding

Anda harus mengimplementasikan kelas Python 3 dengan fungsi anggota play_round(dan __init__atau lainnya jika Anda membutuhkan). play_roundharus mengambil 3 argumen (termasuk diri sendiri). Argumen kedua dan ketiga adalah, secara berurutan: id pemenang dari putaran sebelumnya, diikuti oleh berapa banyak mereka membayar. Jika tidak ada yang menang atau ini adalah babak pertama, keduanya akan -1. Id Anda akan selalu 0, dan id 1–3 akan menjadi pemain lain hanya dalam urutan yang ditentukan oleh posisi pada posting ini.


Aturan tambahan

1. Deterministik: Perilaku fungsi Anda seharusnya hanya bergantung pada argumen input dalam pelelangan. Artinya, Anda tidak dapat mengakses file, waktu, variabel global atau apa pun yang akan menyimpan status di antara berbagai lelang atau bot . Jika Anda ingin menggunakan generator pseudorandom, lebih baik menulisnya sendiri (untuk mencegah memengaruhi program orang lain seperti randomdi Python lib), dan pastikan Anda menyetelnya kembali dengan seed tetap di __init__atau babak pertama.

2. Tiga Bot per Orang: Anda diperbolehkan mengirimkan paling banyak 3 bot, sehingga Anda dapat mengembangkan strategi untuk membuat bot Anda "bekerja sama" dengan beberapa cara.

3. Tidak Terlalu Lambat: Karena akan ada banyak lelang, pastikan bot Anda tidak akan berjalan terlalu lambat. Bot Anda harus dapat menyelesaikan setidaknya 1.000 lelang dalam satu detik.


Pengendali

Ini controller yang saya gunakan. Semua bot akan diimpor dan ditambahkan ke bot_listdalam urutan pada posting ini.

# 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))

Contohnya

Jika Anda membutuhkan generator pseudorandom, berikut ini sederhana.

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

Hasil

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

Pemenangnya adalah all_in_bot. Perhatikan itu zero_botdan fortytwo_botmemiliki skor dan total yang sama, jadi semuanya dihapus.

Bot ini tidak akan termasuk dalam kompetisi. Anda dapat menggunakannya jika Anda pikir mereka hebat.


Kompetisi final akan diadakan pada 2017/11/23 14:00 (UTC) . Anda dapat mengubah bot Anda sebelum itu.


5
Apakah mereka mendapatkan 500 dolar setiap putaran, atau setiap lelang (yang berlangsung 10 putaran)?
Stewie Griffin

1
Kompetisi @KamilDrakari akan dimulai kembali dengan bot yang menyinggung dihapus dari daftar.
Colera Su

4
@Shufflepants Benar, tetapi ini selalu terjadi dengan tantangan KotH. Di masa lalu beberapa orang memang membuat bot di dekat ujung untuk melawan semua bot sampai saat itu. Tapi itu hanya bagian dari tantangan gaya KotH. Dan cara sebagian besar tantangan KotH bekerja, ini termasuk, keuntungannya tidak akan sebesar itu. Anda hanya dapat melawan begitu banyak bot pada saat yang sama .. Tantangan pertama yang bagus, Colera Su , dan selamat datang di PPCG! Menantikan hasilnya. :)
Kevin Cruijssen

4
Berikut ini adalah uji coba pada TIO dengan semua bot saat ini.
Steadybox

2
Ini balapan yang ketat saat ini ...
Zaid

Jawaban:


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    

Bot ini adalah hasil pelatihan genetik terhadap banyak bot pseudo-acak lainnya (dan beberapa bot dalam jawaban lain). Saya telah menghabiskan beberapa waktu untuk memperbaiki pada akhirnya, tetapi strukturnya sebenarnya sangat sederhana.

Keputusan hanya didasarkan pada seperangkat parameter tetap dan bukan pada hasil putaran sebelumnya.

Kuncinya tampaknya adalah putaran pertama: Anda harus melakukan segalanya, menawar 500 adalah langkah aman. Terlalu banyak bot yang mencoba mengakali langkah awal dengan menawar 499 atau 498. Memenangkan babak pertama memberi Anda keuntungan besar untuk sisa lelang. Anda hanya tertinggal 500 dolar, dan Anda punya waktu untuk pulih.

Taruhan yang aman di babak kedua sedikit di atas 990, tetapi bahkan penawaran 0 memberikan hasil yang baik. Penawaran terlalu tinggi dan menang bisa lebih buruk daripada kalah di babak ini.

Di babak ketiga, sebagian besar bot berhenti meningkat: 50% dari mereka memiliki kurang dari 1500 dolar sekarang, jadi tidak perlu membuang uang untuk putaran ini, 1170 adalah tradeoff yang baik. Hal yang sama di babak keempat. Jika Anda kehilangan tiga yang pertama, Anda bisa memenangkan yang satu ini dengan sangat murah, dan masih punya cukup uang untuk yang berikutnya.

Setelah itu, uang rata-rata yang diperlukan untuk memenangkan satu putaran adalah 1500 dolar (yang merupakan kesimpulan logis: sekarang semua orang memenangkan satu putaran dari empat, menawar lebih sedikit untuk menang nanti hanya membuang-buang uang, situasinya telah stabil dan itu hanya putaran- Robin mulai sekarang).

Babak terakhir harus all-in, dan parameter lainnya disesuaikan untuk memenangkan babak terakhir dengan penawaran serendah mungkin sampai saat itu.

Banyak bot mencoba untuk memenangkan ronde kesembilan dengan menawar lebih dari 2.000 dolar, jadi saya memperhitungkannya dan mencoba untuk melarang mereka (saya tidak bisa memenangkan kedua ronde terakhir, dan yang terakhir akan lebih sulit).


1
Ya, itu salah satu cara untuk menang. Selamat!
Luca H

Tetapi saya harus mengakui bahwa saya lebih menyukai karya-karya lain, karena ada bentuk pemikiran lain. Tidak mencoba bagaimana saya akan menang melawan bot lain, tetapi apa yang bisa menjadi taktik yang bagus melawan bot acak.
Luca H

Saya dapat mengerti, saya menyukai (dan meningkatkan) beberapa kiriman lainnya, tetapi ini merupakan masalah pada domain yang terbatas, dan banyak kiriman yang terlalu rumit. Inti dari masalah ini adalah menghasilkan urutan 10 angka, jadi saya memilih untuk mengoptimalkan untuk domain tertentu daripada mencari prosedur umum. Saya seorang insinyur, bukan ahli matematika.
GB

2
@ LucaH kesederhanaan yang tampak dari pendekatan memungkiri jumlah pekerjaan yang diperlukan untuk sampai pada set angka tertentu. Saya mencoba hal yang sama dengan bot saya sendiri dari sudut pandang statistik, dan itu tidak mudah
Zaid

1
@ Zaid tentu saja ada banyak pekerjaan yang masuk ke dalamnya, tetapi memaksa kasar begitu ... kasar;)
Luca H

12

Diatas rata-rata

Tawaran di atas jumlah rata-rata uang yang dimiliki pemain lain. Tawaran semuanya di babak terakhir.

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

Aku bahkan tidak

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)

Hanya berpartisipasi dalam putaran aneh dan babak terakhir.


7

Bot pelupa tidak tahu berapa banyak uang yang dia miliki, jadi dia hanya memasukkan uang yang dia berikan untuk putaran ini. Jika dia menemukan uang pada akhirnya, dia hanya menyumbangkannya untuk amal.

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

15
Saya bukan downvoter, tapi mungkin itu karena Anda tidak melakukan upaya apa pun ke bot Anda
Mischa

9
Ini adalah salah satu jawaban pertama. Sesuatu dibutuhkan untuk membuat bola bergulir.
Khuldraeseth na'Barya

Saya tidak downvote, tapi mungkin itu karena meskipun sesuatu diperlukan untuk membuat bola bergulir, mungkin melakukan sesuatu yang sedikit lebih menarik? Terutama karena ini praktis identik dengan One Dollar Bob yang digunakan untuk memulai
HyperNeutrino

7

Satu atas

Saya tidak tahu banyak tentang Python, jadi saya mungkin membuat kesalahan

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

mengajukan penawaran 1 lebih tinggi dari penawaran pemenang sebelumnya, atau masuk all-in selama putaran terakhir.

Saya mungkin di masa depan memutuskan strategi yang berbeda untuk kapan win_amount-1


7

Bot Pasien

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

Tawaran apa pun untuk lima putaran pertama, kemudian tawaran ~ 1000 dolar untuk empat putaran berikutnya, dan akhirnya tawaran semua yang ada di babak terakhir.


7

Copycat Atau Sedih

Bot ketiga dan terakhir.
Bot ini akan menawar jumlah yang persis sama dengan pemenang sebelumnya (termasuk dirinya sendiri). Namun, jika tidak memiliki cukup uang untuk melakukannya, itu akan menyedihkan, dan akan menawar tagihan 1 dolar sangat sedikit dengan air mata di atasnya sebagai gantinya. Di babak final itu akan masuk all-in.

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

Saya tidak pernah memprogram dengan Python, jadi jika Anda melihat kesalahan, beri tahu saya ..


2
Ini tawaran -1pada lelang pertama.
Okx

7

Uji coba

Saya telah mengedit uji coba sebelumnya yang disatukan oleh Steadybox menambahkan dalam kiriman terbaru.

Saya mempostingnya di sini sehingga ada tempat di mana tautan dapat diperbarui dengan versi yang lebih baru, posting ini adalah wiki komunitas, jadi jangan ragu untuk memperbaruinya jika Anda mengirim kiriman baru, memodifikasi yang lama, atau sekadar melihat sesuatu baru dari beberapa pengiriman lainnya!

Inilah tautan ke percobaan! (TIO)


haruskah saya merasa depresi bahwa bot saya yang dimaksudkan untuk mengganggu mengalahkan dua kiriman "asli" saya?
thegreatemu

@thegreatemu Sangat menarik untuk melihat bagaimana bot berinteraksi satu sama lain. Satu bot baru bisa secara dramatis mengubah peringkat. Sesuatu yang menarik yang saya temukan adalah bahwa jika bot blacklist yang dihapus histocrat ikut serta, dua bot saya pindah ke peringkat teratas. :)
Jo.

6

Setengah In

Bot ini selalu menawarkan setengah dari yang tersisa, kecuali di babak final ke mana ia akan pergi semua.

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

Saya tidak pernah memprogram dengan Python, jadi jika Anda melihat kesalahan, beri tahu saya ..


6

Graylist

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

Terinspirasi oleh pengajuan daftar hitam oleh histokrat , bot ini menyimpan di dalam semua taruhan para pemain lain yang menang sebelumnya, baik rasio uang yang mereka bertaruh dibandingkan dengan uang penuh mereka dan perbedaan antara jumlah taruhan mereka dan jumlah penuh. Untuk menghindari kekalahan dari dasi (yang tampaknya sebenarnya merupakan faktor besar dalam kompetisi ini) maka ia menghindari taruhan sejumlah apa pun yang dapat memberikan hasil yang sama mengingat uang lawan saat ini.

EDIT: sebagai nilai awal untuk penawaran sekarang menggunakan minimum antara: uang saat ini, 1 lebih dari uang lawan terkaya, X lebih dari taruhan kemenangan terakhir, atau Y lebih dari uang rata-rata lawan-lawannya. X dan Y adalah konstanta yang mungkin akan dimodifikasi sebelum akhir kompetisi.


6

Tambang Rata-rata

Pemain ini menghitung persentase (tawaran / total uang) untuk pemenang setiap putaran dan menawar (total uang * persentase kemenangan rata-rata + 85) kecuali jika ia memiliki lebih banyak uang daripada semua pemain lain, maka ia menawar 1 lebih dari pesaing tertinggi . Mulai dengan tawaran 99,0% dari jumlah awal.

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

Eenie Meanie More

Pemain ini identik dengan Meanie, kecuali untuk satu variabel. Versi ini menawarkan lebih agresif dan menyebabkan beberapa pemain menghabiskan lebih dari pelit berpikir lelang bernilai.

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

Distributor

Ketika bot ini kehilangan satu ronde, ia membagikan kelebihan uang tunai di antara semua ronde berikutnya. Dia memasukkan $ 499 pada putaran pertama dengan berpikir bahwa yang lain akan mengikat dengan $ 500 dan dihilangkan.

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
Menggunakan roundsbukannya self.roundsakan menyebabkan kesalahan. Sama dengan money.
Jeremy Weirich

5

Pelit

Pemain ini mengambil total uang tunai yang akan memasuki permainan untuk mendapatkan tawaran rata-rata di seluruh jumlah pemain dan putaran yang tersisa. Jika target ini lebih dari semua pemain lain saat ini memegangnya menurunkan tawarannya ke saldo pesaing terbesarnya ditambah satu. Jika pemain tidak mampu mencapai targetnya, itu adalah all-in.

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

Kalahkan Pemenang

Tawaran 1 lebih dari pemain dengan kemenangan terbanyak sejauh ini

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
Apakah Anda m,wdalam urutan yang benar?
Jo.

5

Kurang satu

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

Tawaran Lebih Tinggi

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

Masih belajar python; menawar sedikit lebih tinggi dari pemenang terakhir.


Selamat datang di PPCG! Tampaknya bot Anda akan lebih baik skor jika Anda mengubah inc = 100ke inc = 101.
Steadybox

Saya benar-benar akan bertentangan dengan minat saya sendiri di sini, tetapi Anda dapat dengan mudah meningkatkan skor Anda dengan melacak belokan dan melakukan segalanya di babak final;)
Leo

Terima kasih atas sarannya; Saya menambahkan putaran terakhir all-in, menyempurnakan selisih, dan menambahkan beberapa bot wingmen untuk memberikan dorongan pada bot ini ..
rancid_banana

Hai, saya harap Anda tidak keberatan, tapi saya sedang menyusun testbench dengan semua pengiriman saat ini dan saya menemukan bahwa kode Anda kadang-kadang mengembalikan nilai yang tidak valid pada putaran terakhir, jadi saya telah memperbaiki bug dengan mengatur ulang urutan beberapa baris. Maaf jika saya mengubah apa pun yang tidak Anda miliki, jangan ragu untuk mengembalikan perubahan dan memperbaiki bug dengan cara lain!
Leo

@ Leo: Tidak masalah, terima kasih telah tertarik ..
rancid_banana

4

FiveFiveFive

Melewati babak pertama dan menawar $ 555 untuk putaran yang tersisa. Di babak terakhir, akan masuk semua kecuali 2 bot lain memiliki jumlah yang sama (dan mungkin akan mengikat).

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

Hampir Semua Masuk

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

Tawaran selalu sedikit kurang dari yang dimilikinya.


4

Meningkat dengan Cepat

Tawaran meningkatkan pecahan uangnya setiap putaran (beri tahu saya jika ada kesalahan, sejak saya menggunakan 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

Dibawah rata-rata

Mirip dengan di atas rata-rata, tetapi sedikit lebih rendah

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

Kuda Tinggi

Pemain ini menawar semua uangnya dikurangi angka putaran saat ini, kecuali pada putaran terakhir, di mana ia masuk semua.

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

Swapper

Bergantian antara menawar satu di bawah maksnya dan masuk semua.

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

Saya pikir saya perlu menemukan sesuatu yang bisa mengalahkan minus_one Steadybox. :)


4

Daftar Hitam Modular

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

Taruhan jumlah tertinggi yang bisa dilakukan yang tidak kongruen modulo 500 ke nomor yang pernah dilihat sebelumnya.

Diedit untuk tidak menerapkan daftar hitam saat itu bisa mendapatkan kemenangan yang dijamin.


Anehnya, tampaknya pembaruan terkini untuk bot Anda yang lain memengaruhi bot ini secara negatif. Saat ini, blacklist_modberada di urutan kelima di papan peringkat , sedangkan blacklistdi tempat kedua. Jika versi yang lebih lama blacklistdigunakan sebagai gantinya, blacklistjatuh ke tempat keenam, tetapi blacklist_mod memimpin !
Steadybox

Melemparkan blacklistkeluar sama sekali tampaknya untuk memberikan blacklist_modbahkan memimpin lebih solid , tapi itu tidak meyakinkan.
Steadybox

Oh, terima kasih, itu masuk akal - mereka dekat dengan algoritma yang sama sejak awal tanpa logika kasus-khusus yang lama, jadi mereka menginjak kaki masing-masing. Saya pikir saya hanya akan menghapus bot asli; Saya tidak bisa memikirkan alasan yang baik untuk mempertahankannya.
histokrat

4

Heurist

The Heurist memperlakukan game ini sebagai salah satu probabilitas berulang, sehingga tahu di mana untuk menarik garis.

Ini juga kikir, sehingga tawaran minimum yang diperlukan untuk menang ketika itu bisa.

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

Penafian: max_biddapat berubah


4

bob_hater

Bot ini tidak menyukai Bob dan karenanya akan selalu menawar 2 $ untuk menang melawan Bob.

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

4

Pamer

Ini adalah pria yang memamerkan kemampuan matematika dalam situasi yang benar-benar tidak memerlukan sesuatu yang rumit. Sampai babak terakhir (di mana ia melakukan semua-dalam), ia menggunakan model logistik untuk menentukan tawarannya, lebih banyak jika musuh-musuhnya memiliki bagian yang lebih besar dari sisa uang mereka.

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)

Kurva logistik yang digunakan adalah f (x) = 1 / (1 + e -8 (x-0,5) ), di mana x adalah rasio antara uang musuh saat ini dengan total uang musuh yang potensial. Semakin banyak yang lain miliki, semakin banyak yang ia tawarkan. Ini memiliki kemungkinan manfaat penawaran hampir-tetapi-tidak-cukup $ 500 pada putaran pertama.


3

AntiMaxer

Cocokkan jumlah tertinggi yang kami mampu dari semua uang pemain. Akan menyebabkan bot apa pun untuk all-in pada ronde itu mengikat.

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

Bot sederhana

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

Hampir sama dengan Bot Pasien, tetapi tidak sebagai pasien. Mendapat skor yang jauh lebih baik daripada itu.


3

Wingman 2

Jika satu wingman baik, dua pasti lebih baik?

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

Kode Anda tidak akan berfungsi karena Anda memerlukan lekukan untuk barang-barang di kelas
HyperNeutrino

Menariknya, kedua wingmen Anda tampaknya mengalahkan bot asli Anda (tautan pastebin berisi tautan TIO, yang terlalu panjang untuk diposkan dalam komentar dan bahkan terlalu lama untuk penyingkat URL ...)
Steadybox

1
Saya menemukan hasilnya sangat sensitif terhadap kumpulan bot lain; perubahan kecil dalam nilai kenaikan tampaknya memiliki hasil yang tidak proporsional.
rancid_banana
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.