一口价密封式拍卖


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,然后自行出价。出价可以是小于或等于它们的金额的任何非负整数。通常,出价最高的人会赢得一轮。但是,为了使事情变得更有趣,如果几个玩家出价相同的价格,则不会考虑他们的出价(因此无法赢得该回合)。例如,如果四名玩家出价400 400 300 200,则一者出价300获胜。如果他们出价400400300300,没有人赢。获胜者应支付他们的出价。

由于这是一次“密封竞价”拍卖,因此玩家唯一会知道出价的信息是中标者,以及下一轮开始时他们支付了多少钱(因此玩家可以知道每个人有多少)。


计分

每种可能的4人组合将举行一次拍卖。也就是说,如果总共有N个机器人,那么将有N C 4个拍卖。赢得最多回合的机器人将成为最终的获胜者。如果出现平局,则支付总额最少的机器人将获胜。如果仍然存在平局,则与出价相同,这些平局将被删除。


编码

您应该使用成员函数(和其他需要的成员函数)实现Python 3类。应该接受3个参数(包括self)。第二和第三个参数依次为:上一轮的获胜者ID,然后是他们支付了多少。如果没有人获胜,或者这是第一轮比赛,他们俩均为-1。您的ID将始终为0,而​​ID 1–3将是其他玩家,其顺序仅取决于此职位的位置。play_round__init__play_round


附加规则

1.确定性的: 函数的行为应仅取决于拍卖中的输入参数。也就是说,您无法访问文件,时间,全局变量或任何将在不同拍卖或漫游器之间存储状态的内容。如果要使用伪随机数生成器,最好自己编写(以防止影响其他程序,如randomPython lib),并确保__init__在第一轮或第一轮中使用固定种子重置它。

2.每人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_bot并且fortytwo_bot得分和总分相同,因此将其删除。

这些漫游器不会包含在比赛中。如果您认为它们很棒,可以使用它们。


决赛将于2017/11/23 14:00(UTC)举行。在此之前,您可以对机器人进行任何更改。


5
他们每回合或每次拍卖会(持续10回合)可获得500美元吗?
Stewie Griffin

1
@KamilDrakari竞赛将重新启动,并将有问题的机器人从列表中删除。
Colera Su

4
@Shufflepants是的,但是KotH挑战总是如此。过去,确实有人在接近尾声的地方制造了一个漫游器,以对抗到目前为止的所有漫游器。但这只是KotH风格挑战的一部分。而且大多数KotH挑战的工作方式(包括这一点)的优势不会那么大。您只能同时对抗这么多机器人。.很好的第一个挑战,Colera Su,欢迎来到PPCG!期待结果。:)
凯文·克鲁伊森

4
这是在TIO上使用所有当前机器人进行的测试。
Steadybox '17

2
目前这是一场激烈的比赛……
Zaid

Answers:


13

硬编码

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%的机器人的资产不足1500美元,因此在这一轮中无需浪费金钱,1170是一个不错的权衡。第四轮也一样。如果您输掉了前三个,则可以很便宜地赢得这个,而下一个仍然有足够的钱。

在那之后,赢得一轮比赛所需的平均金钱为1500美元(这是合乎逻辑的结论:每个人现在都赢得四分之一的回合,后来为赢得胜利而少出价只是浪费钱,情况稳定了,只是一轮而已-从现在开始)。

最后一轮必须全押,而其他参数则需要进行微调以通过在此之前尽可能低的出价来赢得最后一轮。

许多机器人试图通过出价超过2000美元来赢得第九轮比赛,因此我考虑了这一点,并试图高价竞标(无论如何我都无法赢得最后两轮比赛,最后一轮会更艰难)。


1
好吧,那是赢的一种方法。恭喜你!
卡H

但是我必须承认,我更喜欢其他意见,因为有了另一种思想形式。没有尝试如何与其他机器人一较高下,但是对付任何随机机器人这可能是一个很好的策略。
卡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
我不是拒绝投票的人,但这也许是因为您没有对机器人进行任何努力
Mischa

9
这是第一个答案。需要一些东西来使球滚动。
库尔德拉西斯·纳巴里亚

我没有拒绝投票,但这也许是因为即使需要一些帮助使事情顺利进行,也许还有一些更有趣的事情吗?特别是由于这实际上与用来启动它的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

在前五轮中没有任何出价,然后在接下来的四轮中出价〜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

我从不使用Python编程,所以如果您发现任何错误,请告诉我。


2
-1在第一次拍卖中出价。
Okx

7

测试运行

我已经编辑了Steadybox进行的以前的测试运行,添加了最新的提交内容。

我将其发布在此处,以便在某个地方可以使用最新版本来更新链接,该帖子是社区Wiki,因此如果您发布新的提交,修改旧的提交或只是看到一些内容,请随时进行更新其他提交中的新功能!

这是测试运行的链接!(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

灰名单

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

普通矿山

该球员计算每一轮获胜者的百分比(出价/总金额),并出价(总金额*平均获胜百分比+ 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
杰里米·维里希

5

ie

该球员拿走将要进入比赛的总现金,以获得球员数量和剩余回合中的平均竞标价格。如果该目标的数量超过当前所有其他参与者的目标,则将其出价降低到其最大竞争对手加上一个的余额。如果玩家负担不起目标,那就全押了。

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

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

5

击败获胜者

出价比迄今为止获胜最多的玩家高1

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

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

4
m,w的顺序正确吗?

5

减一

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

5

更高出价

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

还在学习python; 出价比最后一位优胜者高一点。


欢迎来到PPCG!如果您更改inc = 100为,您的机器人似乎会获得更高的分数inc = 101
Steadybox

我确实在这里违背自己的利益,但是您可以通过跟踪转弯并在最后一轮全
Leo

感谢您的建议;我添加了最后一轮的全

嗨,希望您不要介意,但我将所有当前提交的测试台放在一起,发现您的代码有时在上一轮返回无效值,因此我通过重新排列修复了该错误。该命令几行。抱歉,如果我更改了您不需要的任何内容,请随时还原更改并以其他方式修复错误!
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

快速升级

每轮竞标增加其资金的比例(请问有什么错误,因为我使用Python已有一段时间)

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

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

4

低于平均水平

高于平均水平,但略低

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

4

高马

除最后一轮全押外,该玩家将所有钱减去当前轮数。

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

4

交换器

在低于最高出价的情况下出价并全押。

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

我认为我需要找到可以击败Steadybox的minus_one的东西。:)


4

模块化黑名单

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

押注最高的金额,该金额与之前看到的任何数字都不等于500。

已编辑为在可以保证获胜时不应用黑名单。


奇怪的是,您其他机器人的最新更新似乎对该机器人产生了负面影响。目前,在排行榜上排名blacklist_mod第五,而排在第二位。如果改用旧版本,则跌至第六位,但领先blacklistblacklistblacklistblacklist_mod
Steadybox

投掷blacklist干脆出去似乎blacklist_mod甚至更多的固体铅等,但是这没有定论。
Steadybox

哦,谢谢,这很有道理-他们很早就采用了相同的算法,没有旧的特殊情况逻辑,因此它们会互相踩脚趾。我想我将删除原来的机器人;我想不出保留它的充分理由。
历史学家

4

启发式

启发式把这个游戏可重复的概率之一,因此它知道在哪里画线。

它也是不幸的,因此它会尽可能地赢得胜利所需的最低限度。

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

反Maxer

匹配所有玩家所能负担的最高金额。将导致该阶段所有机器人进入全押。

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

有趣的是,您的两个机翼兵似乎都击败了您原来的机器人(pastebin链接包含TIO链接,该链接太长了,无法在评论中发布,甚至对于URL缩短器来说也太长...)
Steadybox

1
我发现结果对其他机器人池非常敏感。增量值的微小变化似乎会产生不成比例的结果。
rancid_banana
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.