1 차 봉인 입찰 경매


32

최종 결과

경쟁은 끝났습니다. 축하합니다 hard_coded!

몇 가지 흥미로운 사실 ​​:

  • 40920 개 경매 중 31600 개 (77.2 %)에서 첫 번째 라운드의 승자가 해당 경매에서 가장 많은 라운드를 차지했습니다.

  • 예를 들어, 로봇이 대회에 포함 된 경우, 상단 아홉 곳은 제외하고는 변경되지 않습니다 AverageMineheurist자신의 위치를 교환합니다.

  • 경매에서 상위 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 명의 플레이어가 400400300200을 입찰하면 300 명이 이깁니다. 그들이 400 400 300 300을 입찰하면 아무도 이길 수 없습니다. 승자는 입찰 한 금액을 지불해야합니다.

"밀봉 된 입찰"경매이기 때문에 입찰에 대해 유일하게 정보 플레이어는 입찰자가 승자와 다음 라운드가 시작될 때 지불 한 금액을 알 수 있습니다.


채점

가능한 모든 4 인 조합마다 한 번의 경매가 진행됩니다. 즉, 총 N 개의 봇이 있으면 N C 4 경매가 이루어집니다. 가장 많은 라운드에서이기는 봇이 최종 우승자가됩니다. 동점이있는 경우, 가장 적은 금액을 지불 한 봇이 승리합니다. 입찰과 같은 방식으로 동점 인 경우 해당 동점은 제거됩니다.


코딩

멤버 함수 ( 필요한 경우 다른 클래스)로 Python 3 클래스를 구현 해야합니다. 3 가지 주장을 취해야한다 (자기 포함). 두 번째 및 세 번째 인수는 순서대로 진행됩니다. 이전 라운드의 승자 ID, 지불 금액. 아무도 이기지 않거나 첫 번째 라운드이면 모두 -1이됩니다. 귀하의 ID는 항상 0이며, ID 1–3은이 게시물의 위치에 따라 결정된 순서대로 다른 플레이어가됩니다.play_round__init__play_round


추가 규칙

1. 결정 론적 : 함수의 동작은 경매 내의 입력 인수에만 의존해야합니다. 즉, 파일, 시간, 전역 변수 또는 다른 경매 또는 봇간에 상태 저장하는 모든 항목에 액세스 할 수 없습니다 . 의사 난수 생성기를 사용하려면 직접 작성하여 ( random파이썬 lib 와 같은 다른 사람의 프로그램에 영향을주지 않도록 ) 고정 된 시드 __init__또는 첫 번째 라운드로 재설정해야합니다 .

2. 1 인당 3 개의 봇 : 최대 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_botfortytwo_bot그들이 제거하고, 그래서 같은 점수와 총을 가지고있다.

이 봇은 대회에 포함되지 않습니다. 그들이 좋다고 생각하면 사용할 수 있습니다.


최종 경기는 2017/11/23 14:00 (UTC)에 개최됩니다 . 그 전에 봇을 변경할 수 있습니다.


5
그들은 매 라운드마다 500 달러를 받습니까, 아니면 매 경매마다 (10 라운드 지속)?
Stewie Griffin

1
@KamilDrakari 경쟁은 해당 봇이 목록에서 제거되면서 다시 시작됩니다.
Colera Su

4
@Shufflepants True이지만 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조차도 좋은 결과를 제공합니다. 이 라운드를 잃는 것보다 입찰이 너무 높고이기는 것이 더 나을 수 있습니다.

3 라운드에서 대부분의 봇은 에스컬레이션을 중단합니다. 현재 50 %는 1500 달러 미만이므로이 라운드에서 돈을 낭비 할 필요가 없습니다. 1170은 좋은 트레이드 오프입니다. 네 번째 라운드에서도 마찬가지입니다. 처음 세 개를 잃어버린 경우,이 중 하나를 매우 싸게 얻을 수 있으며 다음을 위해 충분한 돈을 가질 수 있습니다.

그 후, 한 라운드에서 승리하는 데 필요한 평균 돈은 1500 달러입니다. 이제부터 로빈).

마지막 라운드는 올인이어야하며 다른 매개 변수는 그 때까지 가능한 한 낮게 입찰하여 마지막 라운드에서이기도록 미세 조정됩니다.

많은 봇은 2000 달러 이상을 입찰하여 9 번째 라운드에서이기려고합니다.


1
글쎄, 그것은이기는 방법 중 하나입니다. 축하합니다!
Luca H

그러나 나는 다른 형태의 생각이 들어갔 기 때문에 다른 제출물을 더 좋아한다는 것을 인정해야합니다. 내가 다른 봇들과 어떻게 이길 지 시험해 보지 않고, 임의의 봇들에 대한 좋은 전술이 될 수있는 것은 무엇입니까?
Luca H

이해할 수는 있지만 다른 제출물을 좋아하고 찬성했지만 이것은 유한 한 도메인의 문제이며 많은 제출물이 너무 복잡합니다. 문제의 핵심은 10 개의 숫자 시퀀스를 생성하는 것이므로 일반적인 절차를 찾는 대신 특정 도메인에 맞게 최적화하기로 결정했습니다. 저는 수학자가 아닌 엔지니어입니다.
GB

2
@LucaH의 접근 방식의 명백한 단순성은이 특정 숫자 집합에 도달하는 데 필요한 작업량에 달려 있습니다. 나는 통계적인 관점에서 내 자신의 봇과 비슷한 것을 시도하고 있었고 쉽지 않았습니다
Zaid

1
@Zaid 물론 많은 작업이 진행되고 있지만, 무차별 강제는 너무나 무례합니다.)
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가 아니지만 어쩌면 당신이 당신의 봇 에 아무런 노력을 기울이지 않았기
Mischa

9
이것은 첫 번째 답변 중 하나입니다. 볼을 굴리기 위해 무언가가 필요합니다.
Khuldraeseth na'Barya

나는 공감하지는 않았지만 공을 굴리기 위해 무언가가 필요하지만 약간 더 흥미로운 것을 할 수 있기 때문일 수 있습니다. 특히 이것은 실제로 시작하는 데 사용 된 One Dollar Bob과 거의 동일하기 때문에
HyperNeutrino

7

하나의 위

파이썬에 대해 잘 모르므로 일종의 오류가 발생할 수 있습니다.

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

모방 또는 슬픈

세번째이자 마지막 봇.
이 봇은 이전 승자와 정확히 같은 금액으로 입찰합니다 (자체 포함). 그러나 현금이 충분하지 않으면 슬프고 대신 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

나는 파이썬으로 프로그래밍하지 않으므로 실수가 있으면 알려주십시오 ..


2
이 입찰 -1처음 경매에.
Okx

7

시운전

최신 제출물 에 Steadybox를 추가 하여 이전 테스트 실행을 편집했습니다 .

여기에 게시하고 있으므로 링크를 최신 버전으로 업데이트 할 수있는 곳이 있습니다.이 게시물은 커뮤니티 위키이므로 새 제출을 게시하거나 이전 게시물을 수정하거나 간단히 볼 경우 언제든지 업데이트하십시오. 다른 제출에서 새로운!

테스트 실행에 대한 링크는 다음과 같습니다! (TIO)


파괴적인 내 봇이 두 개의 "실제"제출을 능가한다는 것에 우울해야합니까?
thegreatemu

@thegreatemu 봇이 서로 상호 작용하는 방식을 보는 것은 흥미 롭습니다. 하나의 새로운 봇이 순위를 크게 바꿀 수 있습니다. 내가 찾은 흥미로운 점은 히스 토크 라트의 삭제 된 블랙리스트 봇이 참여하면 내 두 봇이 순위의 최상위로 이동한다는 것입니다. :)
조.

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

나는 파이썬으로 프로그래밍하지 않으므로 실수가 있으면 알려주십시오 ..


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)에 입찰 한 다음 최고 경쟁자보다 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 더보기

이 플레이어는 하나의 변수를 제외하고 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

배급 자

이 봇이 한 라운드를 잃으면 그는 다음 라운드에 초과 현금을 분배합니다. 그는 첫 번째 라운드에서 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

이 플레이어는 플레이어 수와 남은 라운드에서 평균 입찰가를 얻기 위해 플레이에 들어갈 총 현금을받습니다. 이 목표가 현재 보유하고있는 다른 모든 선수보다 많은 경우, 가장 큰 경쟁자에 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

빼기 1

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

제안에 감사드립니다. 나는이 봇에게 활력을주고 윙맨 봇의, 미세 조정 증가 모두의 마지막 라운드, 그리고 추가 된 몇 가지 추가 ..
rancid_banana

안녕하세요, 나는 당신이 신경 쓰지 않기를 희망하지만, 나는 모든 현재 제출과 함께 테스트 벤치를 만들고 있었고, 당신의 코드가 때로는 마지막 라운드에서 유효하지 않은 값을 반환한다는 것을 알았습니다. 몇 줄 주문. 내가 가지고 있지 않은 것을 변경 한 경우 죄송합니다. 변경 사항을 되돌리고 다른 방식으로 버그를 수정하십시오!
Leo

@Leo : 문제 없습니다. 관심을 가져 주셔서 감사합니다 ..
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

빠르게 이관

매 라운드마다 돈의 일부를 늘리는 입찰 (파이썬을 사용한 이후로 오류가 있으면 알려주세요)

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_mod5 위인 반면 2 위입니다. 대신 이전 버전을 사용하는 경우 6 위로 떨어지지 만 선두를 차지합니다 ! blacklistblacklistblacklistblacklist_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

이 봇은 Bob을 좋아하지 않으므로 Bob과의 승리를 위해 항상 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

한 명의 윙맨이 좋으면 두 사람이 더 낫습니까?

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

흥미롭게도 두 윙맨 이 원래 봇을이기는 것 같습니다 (pastbin 링크에는 주석을 게시하기에는 너무 길고 URL 단축기에는 너무 깁니다 ...)
Steadybox

1
결과는 다른 봇의 풀에 매우 민감하다는 것을 알았습니다. 증분 값의 작은 변화는 결과가 불균형 한 것으로 보입니다.
rancid_banana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.