การประมูลที่ปิดผนึกราคาแรก


32

ผลสุดท้าย

การแข่งขันสิ้นสุดแล้ว ขอแสดงความยินดีด้วยhard_coded!

ข้อเท็จจริงที่น่าสนใจ:

  • ในการประมูล 31600 จาก 40920 การประมูล (77.2%) ผู้ชนะรอบแรกชนะการประมูลมากที่สุดในรอบนั้น

  • หากบอทตัวอย่างถูกรวมอยู่ในการแข่งขันเก้าอันดับแรกจะไม่เปลี่ยนแปลงยกเว้นว่า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
  • นับ Tie (จำนวนการประมูลที่ i-TH [719, 126, 25, 36, 15, 58, 10, 7, 19, 38]รอบไม่มีชนะ):

  • ชนะประมูลเฉลี่ยของ i-TH [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 จากนั้นทำการประมูลของตนเอง การเสนอราคาสามารถเป็นจำนวนเต็มแบบไม่ลบใด ๆ น้อยกว่าหรือเท่ากับจำนวนเงินที่มี โดยปกติคนที่เสนอราคาสูงสุดจะเป็นผู้ชนะในรอบนั้น อย่างไรก็ตามเพื่อให้สิ่งที่น่าสนใจยิ่งขึ้นหากผู้เล่นหลายคนเสนอราคาเดียวกันการเสนอราคาของพวกเขาจะไม่ถูกนำมาพิจารณา ตัวอย่างเช่นหากผู้เล่นสี่คนเสนอราคา 400 400 300 200 ผู้ชนะการประมูลคนหนึ่งจะชนะ 300 หากพวกเขาเสนอราคา 400 400 300 300 ไม่มีใครชนะ ผู้ชนะควรจ่ายในสิ่งที่เสนอราคา

เนื่องจากเป็นการประมูลแบบ "ผนึกราคาประมูล" ผู้เล่นข้อมูลเพียงคนเดียวเท่านั้นที่รู้เกี่ยวกับการเสนอราคานั้นคือผู้ชนะและจำนวนเงินที่จ่ายเมื่อรอบต่อไปเริ่มต้น


เกณฑ์การให้คะแนน

การประมูลหนึ่งครั้งจะจัดขึ้นสำหรับการรวมกันของผู้เล่น 4 คนที่เป็นไปได้ นั่นคือหากมีบอททั้งหมดที่NจะมีการประมูลN C 4 บอทที่ชนะรอบมากที่สุดจะเป็นผู้ชนะรอบสุดท้าย ในกรณีที่มีเน็คไทบอทที่จ่ายน้อยที่สุดจะชนะ หากยังมีเน็คไทเช่นเดียวกับการประมูลความสัมพันธ์เหล่านั้นจะถูกลบออก


การเข้ารหัส

คุณควรนำคลาสPython 3ไปใช้กับฟังก์ชั่นสมาชิกplay_round(และ__init__อื่น ๆ หากคุณต้องการ) play_roundควรใช้ 3 ข้อโต้แย้ง (รวมถึงตัวเอง) อาร์กิวเมนต์ที่สองและสามจะเป็นไปตามลำดับ: id ของผู้ชนะของรอบก่อนหน้าตามด้วยจำนวนเงินที่จ่าย หากไม่มีใครชนะหรือเป็นรอบแรกพวกเขาทั้งคู่จะเป็น -1 ID ของคุณจะเป็น 0 เสมอและ id 1–3 จะเป็นผู้เล่นคนอื่นตามลำดับที่กำหนดโดยตำแหน่งในโพสต์นี้เท่านั้น


กฎเพิ่มเติม

1. กำหนด: พฤติกรรมของฟังก์ชั่นของคุณควรขึ้นอยู่กับการโต้แย้งการป้อนข้อมูลภายในการประมูล นั่นคือคุณสามารถเข้าถึงไฟล์ไม่ได้เวลาตัวแปรทั่วโลกหรือสิ่งที่จะเก็บรัฐระหว่างการประมูลที่แตกต่างกันหรือบอท หากคุณต้องการใช้เครื่องกำเนิดไฟฟ้าเทียมหลอกคุณควรเขียนด้วยตัวเอง (เพื่อป้องกันไม่ให้เกิดผลกระทบต่อโปรแกรมของผู้อื่นเช่นrandomใน Python lib) และตรวจสอบให้แน่ใจว่าคุณได้รีเซ็ตเมล็ดพันธุ์ที่กำหนดไว้แล้ว__init__หรือรอบแรกแล้ว

2. สามบอทต่อคน: คุณได้รับอนุญาตให้ส่งได้ไม่เกิน 3 บอทดังนั้นคุณสามารถพัฒนากลยุทธ์เพื่อให้บอทของคุณ "ร่วมมือ" ในบางวิธี

3. ไม่ช้าเกินไป: เนื่องจากจะมีการประมูลจำนวนมากตรวจสอบให้แน่ใจว่าบ็อตของคุณจะไม่ทำงานช้าเกินไป บอทของคุณควรจะสามารถทำการประมูลอย่างน้อย 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 รอบ) หรือไม่?
Stewie Griffin

1
@ การแข่งขัน KamilDrakari จะเริ่มต้นใหม่เมื่อบอทที่ละเมิดถูกลบออกจากรายการ
Colera Su

4
@Shufflepants จริง แต่นี่เป็นกรณีที่มีความท้าทายของ KotH เสมอ ในอดีตบางคนทำ ธ ปท. ใกล้ถึงจุดจบเพื่อตอบโต้บอททั้งหมดจนถึงจุดนั้น แต่มันเป็นเพียงส่วนหนึ่งของความท้าทายสไตล์ KotH และวิธีที่ KotH ส่วนใหญ่ทำงานท้าทายสิ่งนี้รวมอยู่ด้วยประโยชน์จะไม่ยิ่งใหญ่ คุณสามารถตอบโต้บอทได้มากมายในเวลาเดียวกัน .. ความท้าทายครั้งแรกที่ดี, Colera Suและยินดีต้อนรับสู่ PPCG! มองไปข้างหน้าเพื่อผลลัพธ์ :)
Kevin Cruijssen

4
นี่คือการทดสอบการทำงานของ TIOกับบอตปัจจุบันทั้งหมด
Steadybox

2
เป็นการแข่งขันที่รัดกุมในขณะนี้ ...
Zaid

คำตอบ:


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 ดอลลาร์หลังและคุณมีเวลาในการกู้คืน

การเดิมพันที่ปลอดภัยในรอบที่สองนั้นมีค่ามากกว่า 990 เล็กน้อย แต่การเสนอราคา 0 ก็ให้ผลลัพธ์ที่ดี การเสนอราคาสูงเกินไปและการชนะอาจแย่กว่าการแพ้ในรอบนี้

ในรอบที่สามบอทส่วนใหญ่หยุดเพิ่มขึ้น: 50% ของพวกเขามีน้อยกว่า 1,500 ดอลลาร์ในตอนนี้ดังนั้นจึงไม่จำเป็นต้องเสียเงินในรอบนี้ 1170 เป็นการแลกเปลี่ยนที่ดี สิ่งเดียวกันในรอบที่สี่ หากคุณแพ้สามคนแรกคุณสามารถชนะได้ในราคาถูกมากและยังมีเงินเพียงพอสำหรับการต่อไป

หลังจากนั้นเงินเฉลี่ยที่ต้องใช้ในการชนะรอบคือ 1,500 ดอลลาร์ (ซึ่งเป็นข้อสรุปเชิงตรรกะ: ทุกคนชนะรอบสี่โดยตอนนี้การเสนอราคาน้อยกว่าที่จะชนะในภายหลังเป็นเพียงการเสียเงินสถานการณ์มีเสถียรภาพและเป็นเพียงรอบ - โรบินต่อจากนี้)

รอบสุดท้ายจะต้องเป็นแบบ all-in และพารามิเตอร์อื่น ๆ จะได้รับการปรับแต่งเพื่อให้ได้รอบสุดท้ายโดยการเสนอราคาต่ำที่สุดเท่าที่จะทำได้

บอทจำนวนมากพยายามที่จะชนะรอบที่เก้าโดยประมูลมากกว่า 2,000 ดอลลาร์ดังนั้นฉันจึงคำนึงถึงเรื่องนั้นและพยายามที่จะเสนอราคาเกินพวกเขา (ฉันไม่สามารถชนะได้ทั้งสองรอบสุดท้ายและสุดท้ายจะยากขึ้น)


1
นั่นเป็นวิธีหนึ่งที่จะชนะ ขอแสดงความยินดี!
Luca H

แต่ฉันต้องยอมรับว่าฉันชอบผลงานอื่น ๆ มากกว่าเพราะมีความคิดในรูปแบบอื่น ไม่ลองว่าฉันจะเอาชนะบอทอื่น ๆ ได้อย่างไร แต่อาจเป็นกลยุทธ์ที่ดีในการบอทสุ่ม
Luca H

ฉันเข้าใจได้ว่าฉันชอบ (และอัปโหลด) การส่งอื่น ๆ แต่นี่เป็นปัญหาของโดเมนที่ จำกัด และการส่งจำนวนมากนั้นซับซ้อนเกินไป หลักของปัญหาคือการสร้างลำดับของตัวเลข 10 ตัวดังนั้นฉันเลือกที่จะปรับให้เหมาะสมสำหรับโดเมนที่ระบุแทนที่จะค้นหาขั้นตอนทั่วไป ฉันเป็นวิศวกรไม่ใช่นักคณิตศาสตร์
GB

2
@ LucaH ความเรียบง่ายที่ชัดเจนของวิธีการนี้ใช้ปริมาณงานที่ต้องใช้ในการมาถึงตัวเลขชุดนี้โดยเฉพาะ ฉันพยายามสิ่งที่คล้ายกันกับบอทของตัวเองจากมุมมองทางสถิติและมันก็ไม่ใช่เรื่องง่าย
Zaid

1
@ Zaid แน่นอนว่ามีงานจำนวนมากเข้ามาเกี่ยวข้อง แต่การบังคับเดรัจฉานก็เป็นเช่นนั้น ... brute;)
Luca 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
นี่เป็นหนึ่งในคำตอบแรก จำเป็นต้องมีบางสิ่งบางอย่างเพื่อให้ลูกบอลกลิ้ง
Khuldraeseth na'Barya

ฉันไม่ได้ลงคะแนน แต่อาจเป็นเพราะแม้ว่าบางสิ่งบางอย่างที่จำเป็นในการทำให้ลูกบอลกลิ้ง โดยเฉพาะอย่างยิ่งตั้งแต่นี้เป็นจริงเหมือนกับ 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

ไม่มีการเสนอราคาสำหรับห้ารอบแรกจากนั้นเสนอราคา ~ 1,000 ดอลลาร์สำหรับสี่รอบถัดไปและสุดท้ายเสนอราคาทุกอย่างที่มีในรอบสุดท้าย


7

Copycat Or Sad

บอทตัวที่สามและสุดท้าย
บอทนี้จะเสนอราคาเท่ากันกับผู้ชนะคนก่อนหน้า (รวมถึงตัวเอง) อย่างไรก็ตามหากไม่มีเงินสดเพียงพอที่จะทำเช่นนั้นมันจะน่าเศร้าและจะเสนอราคาบิล 1 ดอลล่าร์ที่ทรุดโทรมแทนเขา ในรอบสุดท้ายมันจะเป็นแบบ 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

ฉันไม่เคยเขียนโปรแกรมใน Python ดังนั้นหากคุณเห็นข้อผิดพลาดใด ๆ แจ้งให้เราทราบ ..


2
การเสนอราคานี้-1ในการประมูลครั้งแรก
Okx

7

ทดสอบการทำงาน

ฉันได้แก้ไขการทดสอบก่อนหน้านี้รวบรวมโดยSteadyboxเพิ่มในการส่งล่าสุด

ฉันโพสต์ไว้ที่นี่เพื่อให้มีสถานที่ที่สามารถอัปเดตลิงค์เป็นเวอร์ชันล่าสุดได้มากขึ้นโพสต์นี้เป็นวิกิชุมชนดังนั้นโปรดอัปเดตถ้าคุณโพสต์การส่งใหม่แก้ไขเก่าหรือเพียงแค่เห็นอะไรบางอย่าง ใหม่จากการส่งอื่น ๆ !

นี่คือลิงค์ไปสู่การทดสอบการทำงาน! (TIO)


ฉันควรจะมีความสุขหรือไม่ที่บอทของฉันซึ่งตั้งใจจะก่อกวนส่งผลงาน "ของจริง" สองอย่างของฉันออกมา?
thegreatemu

@thegreatemu เป็นเรื่องที่น่าสนใจที่จะเห็นว่าบอทโต้ตอบกันอย่างไร บอทตัวใหม่เดียวสามารถเปลี่ยนการจัดอันดับได้อย่างมาก สิ่งที่น่าสนใจที่ฉันพบคือถ้าบอทบัญชีดำที่ถูกลบของ histocrat มีส่วนร่วมบอททั้งสองของฉันจะย้ายไปอยู่อันดับต้น ๆ :)
โจ

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

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

แรงบันดาลใจจากการส่งบัญชีดำโดยฮิสโทแคตบอทนี้จะจดจำการเดิมพันที่ชนะก่อนหน้านี้ของผู้เล่นคนอื่น ๆ ทั้งอัตราส่วนเงินที่พวกเขาเดิมพันเปรียบเทียบกับเงินเต็มและความแตกต่างระหว่างจำนวนเงินเดิมพันและจำนวนเต็ม เพื่อหลีกเลี่ยงการแพ้ (ซึ่งเห็นได้ชัดว่าเป็นปัจจัยใหญ่ในการแข่งขันครั้งนี้) จากนั้นหลีกเลี่ยงการเดิมพันหมายเลขใด ๆ ที่สามารถให้ผลเหมือนกันได้เนื่องจากเงินของฝ่ายตรงข้ามในปัจจุบัน

แก้ไข: ตามค่าเริ่มต้นของการเสนอราคาตอนนี้ใช้ขั้นต่ำระหว่าง: เงินปัจจุบัน, 1 มากกว่าเงินของคู่ต่อสู้ที่รวยที่สุด, X มากกว่าการเดิมพันที่ชนะครั้งสุดท้ายหรือ Y มากกว่าเงินเฉลี่ยของฝ่ายตรงข้าม X และ Y เป็นค่าคงที่ที่อาจถูกแก้ไขก่อนสิ้นสุดการแข่งขัน


6

AverageMine

ผู้เล่นนี้คำนวณเปอร์เซ็นต์ (การเสนอราคา / เงินทั้งหมด) สำหรับผู้ชนะในแต่ละรอบและเสนอราคาของเขา (เงินทั้งหมด * เปอร์เซ็นต์การชนะโดยเฉลี่ย +85) เว้นแต่เขาจะมีเงินมากกว่าผู้เล่นอื่นทั้งหมดจากนั้นเขาเสนอราคา 1 มากกว่าคู่แข่งสูงสุด . เริ่มด้วยการเสนอราคา 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

Eenie Meanie More

ผู้เล่นคนนี้เหมือนกับ 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

distributer

เมื่อบอทนี้แพ้รอบเขาจะจ่ายเงินสดส่วนเกินในรอบถัดไปทั้งหมด เขาใส่เงิน $ 499 ในการคิดรอบแรกว่าคนอื่น ๆ จะผูกกับ $ 500 และถูกกำจัด

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เช่นเดียวกันกับ
Jeremy Weirich

5

Meanie

ผู้เล่นนี้ใช้เงินสดทั้งหมดที่จะเข้าเล่นเพื่อรับการเสนอราคาเฉลี่ยตามจำนวนผู้เล่นและรอบที่เหลือ หากเป้าหมายนี้มากกว่าผู้เล่นคนอื่น ๆ ในปัจจุบันถือมันลดการเสนอราคาเพื่อความสมดุลของคู่แข่งที่ยิ่งใหญ่ที่สุดบวกหนึ่ง หากผู้เล่นไม่สามารถจ่ายได้เป้าหมายมันเป็นแบบ 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

เอาชนะผู้ชนะ

เสนอราคามากกว่าผู้เล่นที่ชนะมากที่สุดจนถึงตอนนี้

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

ยังคงเรียนรู้หลาม เสนอราคาสูงกว่าผู้ชนะคนสุดท้ายเล็กน้อย


ยินดีต้อนรับสู่ PPCG! มันดูเหมือนว่า ธ ปทของคุณได้รับคะแนนที่ดียิ่งขึ้นถ้าคุณเปลี่ยนไปinc = 100 inc = 101
Steadybox

ฉันจะขัดกับความสนใจของฉันที่นี่จริง ๆ แต่คุณสามารถปรับปรุงคะแนนของคุณได้อย่างง่ายดายโดยการติดตามการหมุนและไปรอบ ๆ ในรอบสุดท้าย;)
Leo

ขอบคุณสำหรับคำแนะนำ; ฉันเพิ่ม all-in รอบสุดท้ายปรับการเพิ่มขึ้นและเพิ่ม botmen wingmen สองตัวเพื่อให้บอทนี้เพิ่มขึ้น ..
rancid_banana

สวัสดีฉันหวังว่าคุณจะไม่รังเกียจ แต่ฉันได้รวบรวมการทดสอบกับการส่งปัจจุบันทั้งหมดและฉันพบว่าบางครั้งรหัสของคุณคืนค่าที่ไม่ถูกต้องในรอบสุดท้ายดังนั้นฉันจึงแก้ไขข้อผิดพลาดด้วยการจัดเรียงใหม่ คำสั่งสองสามบรรทัด ขออภัยหากฉันเปลี่ยนแปลงสิ่งใดก็ตามที่คุณไม่มีคุณสามารถยกเลิกการเปลี่ยนแปลงและแก้ไขข้อผิดพลาดด้วยวิธีอื่นได้!
Leo

@Leo: ไม่มีปัญหาขอบคุณที่ให้ความสนใจ ..
rancid_banana

4

FiveFiveFive

ข้ามรอบแรกและเสนอราคา $ 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

HighHorse

ผู้เล่นคนนี้ประมูลเงินทั้งหมดของเขาลบด้วยจำนวนรอบปัจจุบันยกเว้นในรอบสุดท้ายซึ่งเขาเข้ามาทั้งหมด

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

สลับระหว่างการเสนอราคาหนึ่งภายใต้แม็กซ์ของเขาและไปทั้งหมดมา

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

ฉันคิดว่าฉันต้องค้นหาสิ่งที่สามารถเอาชนะ minus_one ของ Steadybox ได้ :)


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แทนblacklistให้ไปยังอันดับที่หก แต่blacklist_mod เป็นผู้นำ !
Steadybox

โยนblacklistออกมาพร้อมกันดูเหมือนว่าจะให้blacklist_modแม้กระทั่งนำไปสู่การที่มั่นคงมากขึ้นแต่ที่ค้างคา
Steadybox

โอ้ขอบคุณที่เข้าท่า - พวกมันใกล้เคียงกับอัลกอริธึมเดียวกันตั้งแต่เนิ่นๆโดยไม่มีตรรกะกรณีพิเศษแบบเก่าดังนั้นพวกเขาจึงเหยียบนิ้วเท้าของกันและกัน ฉันคิดว่าฉันจะลบบอทดั้งเดิมออกไป ฉันไม่สามารถคิดเหตุผลที่ดีที่จะเก็บมันไว้
ประวัติศาสตร์ 24

4

Heurist

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 คืออัตราส่วนของเงินศัตรูปัจจุบันต่อจำนวนเงินศัตรูที่มีศักยภาพทั้งหมด ยิ่งคนอื่นมีมากกว่าเขาก็ยิ่งเสนอราคามากขึ้น นี่เป็นประโยชน์ที่เป็นไปได้ของการเสนอราคารอบแรก แต่ไม่มากนัก $ 500


3

AntiMaxer

จับคู่กับจำนวนเงินสูงสุดที่เราสามารถจ่ายได้จากเงินของผู้เล่นทุกคน จะทำให้บอทใด ๆ ก็ตามที่กำลังจะเข้าร่วมในรอบนั้น

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

Wingman 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

น่าสนใจ Wingmen ของคุณทั้งคู่ดูเหมือนจะเอาชนะบอตดั้งเดิมของคุณ (ลิงก์ pastebin มีลิงค์ TIO ซึ่งยาวเกินไปสำหรับการโพสต์ในความคิดเห็นและยาวเกินไปสำหรับ URL ย่อ ... )
Steadybox

1
ฉันพบว่าผลลัพธ์นั้นอ่อนไหวต่อกลุ่มของบอทอื่น ๆ การเปลี่ยนแปลงเล็กน้อยในมูลค่าที่เพิ่มขึ้นดูเหมือนว่าจะมีผลลัพธ์ที่ไม่สมส่วน
rancid_banana
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.