Аукцион с первичной ценой


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 (количество аукционов , которые я-го тура не было победителя): [719, 126, 25, 36, 15, 58, 10, 7, 19, 38].

  • Средняя выигрышная ставка И -го тура: [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 аргумента (включая себя). Второй и третий аргументы будут по порядку: идентификатор победителя предыдущего раунда, после чего будет указана сумма, которую они заплатили. Если никто не выиграет или это первый раунд, они оба будут равны -1. Ваш id всегда будет 0, а id 1–3 будут другими игроками в порядке, определяемом только позицией в этом посте.


Дополнительные правила

1. Детерминированный: поведение вашей функции должно зависеть только от входных аргументов в рамках аукциона. То есть вы не можете получить доступ к файлам, времени, глобальным переменным или чему-либо, что будет хранить состояния между различными аукционами или ботами . Если вы хотите использовать генератор псевдослучайных данных, лучше написать его самостоятельно (чтобы не влиять на программы других пользователей, например, randomв Python lib), и убедиться, что он сброшен с фиксированным начальным числом __init__или в первом раунде.

2. Три бота на человека: вам разрешено представить не более 3-х ботов, поэтому вы можете разработать стратегию, чтобы ваши боты каким-то образом «сотрудничали».

3. Не слишком медленно: поскольку будет много аукционов, убедитесь, что ваши боты не будут работать слишком медленно. Ваши боты должны быть в состоянии завершить по крайней мере 1000 аукционов в секунду.


контроллер

Вот контроллер, который я использую. Все боты будут импортированы и добавлены bot_listв порядке в этом посте.

# from some_bots import some_bots

bot_list = [
    #one_bot, another_bot, 
]

import hashlib

def decide_order(ls):
    hash = int(hashlib.sha1(str(ls).encode()).hexdigest(), 16) % 24
    nls = []
    for i in range(4, 0, -1):
        nls.append(ls[hash % i])
        del ls[hash % i]
        hash //= i
    return nls

N = len(bot_list)
score = [0] * N
total = [0] * N

def auction(ls):
    global score, total
    pl = decide_order(sorted(ls))
    bots = [bot_list[i]() for i in pl]
    dollar = [0] * 4
    prev_win, prev_bid = -1, -1
    for rounds in range(10):
        bids = []
        for i in range(4): dollar[i] += 500
        for i in range(4):
            tmp_win = prev_win
            if prev_win == i: tmp_win = 0
            elif prev_win != -1 and prev_win < i: tmp_win += 1
            bid = int(bots[i].play_round(tmp_win, prev_bid))
            if bid < 0 or bid > dollar[i]: raise ValueError(pl[i])
            bids.append((bid, i))
        bids.sort(reverse = True)
        winner = 0
        if bids[0][0] == bids[1][0]:
            if bids[2][0] == bids[3][0]: winner = -1
            elif bids[1][0] == bids[2][0]: winner = 3
            else: winner = 2
        if winner == -1:
            prev_win, prev_bid = -1, -1
        else:
            prev_bid, prev_win = bids[winner]
            score[pl[prev_win]] += 1
            total[pl[prev_win]] += prev_bid
            dollar[prev_win] -= prev_bid

for a in range(N - 3):
    for b in range(a + 1, N - 2):
        for c in range(b + 1, N - 1):
            for d in range(c + 1, N): auction([a, b, c, d])

res = sorted(map(list, zip(score, total, bot_list)), key = lambda k: (-k[0], k[1]))

class TIE_REMOVED: pass

for i in range(N - 1):
    if (res[i][0], res[i][1]) == (res[i + 1][0], res[i + 1][1]):
        res[i][2] = res[i + 1][2] = TIE_REMOVED
for sc, t, tp in res:
    print('%-20s Score: %-6d Total: %d' % (tp.__name__, sc, t))

Примеры

Если вам нужен генератор псевдослучайных, вот простой.

class myrand:
    def __init__(self, seed): self.val = seed
    def randint(self, a, b):
        self.val = (self.val * 6364136223846793005 + 1) % (1 << 64)
        return (self.val >> 32) % (b - a + 1) + a

class zero_bot:
    def play_round(self, i_dont, care): return 0

class all_in_bot:
    def __init__(self): self.dollar = 0
    def play_round(self, winner, win_amount):
        self.dollar += 500
        if winner == 0: self.dollar -= win_amount
        return self.dollar

class random_bot:
    def __init__(self):
        self.dollar = 0
        self.random = myrand(1)
    def play_round(self, winner, win_amount):
        self.dollar += 500
        if winner == 0: self.dollar -= win_amount
        return self.random.randint(0, self.dollar)

class average_bot:
    def __init__(self):
        self.dollar = 0
        self.round = 11
    def play_round(self, winner, win_amount):
        self.dollar += 500
        self.round -= 1
        if winner == 0: self.dollar -= win_amount
        return self.dollar / self.round

class fortytwo_bot:
    def play_round(self, i_dont, care): return 42

Результат

all_in_bot           Score: 20     Total: 15500
random_bot           Score: 15     Total: 14264
average_bot          Score: 15     Total: 20000
TIE_REMOVED          Score: 0      Total: 0
TIE_REMOVED          Score: 0      Total: 0

Побеждает all_in_bot. Обратите внимание, что zero_botиfortytwo_bot имеют одинаковые баллы и общее количество, поэтому они удалены.

Эти боты не будут включены в соревнование. Вы можете использовать их, если считаете, что они великолепны.


Финальные соревнования пройдут в 2017/11/23 14:00 (UTC) . Вы можете внести любые изменения в своих ботов до этого.


5
Они получают 500 долларов каждый раунд или каждый аукцион (который длится 10 раундов)?
Стьюи Гриффин

1
Соревнование @KamilDrakari возобновится, и бот-нарушитель будет удален из списка.
Колера Су

4
@Shufflepants Правда, но это всегда так с вызовами KotH. В прошлом некоторые люди действительно делали бот в конце, чтобы противостоять всем ботам до этого момента. Но это только часть проблемы в стиле KotH. И то, как работает большинство KotH-задач, включая этот, не будет таким большим преимуществом. Вы можете противостоять так много ботов одновременно. Хорошая первая задача, Colera Su , и добро пожаловать в PPCG! Ждем результатов. :)
Кевин Круйссен

4
Вот тестовый запуск на TIO со всеми текущими ботами.
Steadybox

2
Сейчас жесткая гонка ...
Заид

Ответы:


13

hard_coded

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

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

Этот бот является результатом генетической тренировки против множества других псевдослучайных ботов (и некоторых ботов в других ответах). В конце я потратил некоторое время на тонкую настройку, но его структура на самом деле очень проста.

Решения основаны только на фиксированном наборе параметров, а не на результатах предыдущих раундов.

Ключ, похоже, в первом раунде: вы должны пойти ва-банк, ставки 500 - это безопасный ход. Слишком много ботов пытаются перехитрить начальный ход, предлагая цену 499 или 498. Победа в первом раунде дает вам большое преимущество для остальной части аукциона. Вы отстаете всего на 500 долларов, и у вас есть время на восстановление.

Безопасная ставка во втором раунде составляет чуть более 990, но даже ставка 0 дает хороший результат. Слишком высокая ставка и выигрыш могут быть хуже, чем проигрыш в этом раунде.

В третьем раунде большинство ботов перестают расти: 50% из них имеют менее 1500 долларов, поэтому нет необходимости тратить деньги в этом раунде, 1170 - хороший компромисс. То же самое в четвертом раунде. Если вы проиграли первые три, вы можете выиграть этот очень дешево, и при этом у вас будет достаточно денег для следующего.

После этого средняя сумма денег, необходимая для победы в раунде, составляет 1500 долларов (и это логичный вывод: все выигрывают в раунде из четырех к настоящему моменту, делая меньше ставок, чтобы выиграть позже, это просто тратить деньги, ситуация стабилизировалась, и это просто раунд). Робин отныне).

Последний раунд должен быть олл-ин, а остальные параметры настроены так, чтобы выиграть последний раунд, сделав ставки как можно ниже до тех пор.

Многие боты пытаются выиграть девятый раунд, предлагая цену более 2000 долларов, поэтому я принял это во внимание и стараюсь их перебить (в любом случае я не могу выиграть оба последних раунда, а последний будет сложнее).


1
Ну, это один из способов победить. Поздравляем!
Лука Х

Но я должен признаться, что мне больше нравятся другие представления, потому что там была другая форма мысли. Не пытаясь понять, как бы я победил против других ботов, но что может быть хорошей тактикой против любого случайного бота.
Luca H

Я могу понять, мне понравились (и проголосовали) некоторые другие материалы, но это проблема конечного домена, и многие материалы слишком сложны. Суть проблемы заключается в создании последовательности из 10 чисел, поэтому я выбрал оптимизацию для конкретного домена вместо поиска общей процедуры. Я инженер, а не математик.
ГБ

2
@ LucaH кажущаяся простота подхода опровергает объем работы, необходимый для достижения этого конкретного набора чисел. Я пытался сделать то же самое с моим собственным ботом со статистической точки зрения, и это было нелегко
Заид

1
@ Говорят, конечно, много работы уходит на это, но грубое принуждение - это просто ... грубое;)
Лука Х

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
Это один из первых ответов. Что-то нужно, чтобы мяч перекатился.
Хулдрасет на'Барья

Я не понизил голос, но, может быть, это потому, что, несмотря на то, что что-то нужно для того, чтобы раскрутить мяч, может быть, сделать что-то немного более интересное? Тем более, что он практически идентичен 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 добавив в него новейшие материалы.

Я публикую его здесь, чтобы было место, где ссылка может быть обновлена ​​более поздними версиями, этот пост является вики-сообществом, так что не стесняйтесь обновлять его, если вы публикуете новую заявку, изменяете старую или просто видите что-то новый из какой-то другой подачи!

Вот ссылка на тестовый прогон! (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

Я никогда не программирую на 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 Больше

Этот игрок идентичен 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

жадина

Этот игрок берет общую сумму денег, которая войдет в игру, чтобы получить среднюю ставку по числу игроков и оставшихся раундов. Если эта цель больше, чем у всех других игроков в настоящее время, она понижает ставку до баланса своего величайшего конкурента плюс один. Если игрок не может позволить себе свою цель, это олл-ин.

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

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

5

Победить победителя

Ставка на 1 больше, чем у игрока с наибольшим количеством побед

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

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

4
Вы m,wв правильном порядке?
Джо.

5

Минус один

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

5

Ставка выше

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

Все еще изучаю Python; Ставка чуть выше, чем у последнего победителя.


Добро пожаловать в PPCG! Кажется, что ваш бот становится еще лучше, если вы перейдете inc = 100на inc = 101.
Steadybox

Я действительно иду против своих собственных интересов, но вы можете легко улучшить свой счет, отслеживая ходы и
Лев

Спасибо за предложения; Я добавил олл-ин последнего раунда, отрегулировал приращение и добавил пару ботов-ведомых, чтобы дать этому боту поддержку ..
rancid_banana

Привет, надеюсь, вы не возражаете, но я собрал тестовый стенд со всей текущей отправкой, и я обнаружил, что ваш код иногда возвращал недопустимые значения в последнем раунде, поэтому я исправил ошибку, переставив порядок в пару строк. Извините, если я что-то изменил, чего бы у вас не было, не стесняйтесь отменить изменения и исправить ошибку другим способом!
Лев

@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

Я решил, что мне нужно найти что-то, что могло бы побить минус_единя 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

О, спасибо, это имеет смысл - они с самого начала близки к одному и тому же алгоритму без старой логики специального случая, поэтому они наступают друг другу на ноги. Я думаю, что я просто удалю оригинальный бот; Я не могу придумать вескую причину, чтобы держать это вокруг.
гистократ

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

Интересно, что оба ваших ведомых, кажется, побеждают вашего оригинального бота (ссылка для вставки содержит ссылку TIO, которая слишком длинна для публикации в комментарии и даже слишком длинна для сокращателей URL-адресов ...)
Steadybox

1
Я обнаружил, что результаты были очень чувствительны к пулу других ботов; незначительные изменения в величине приращения, кажется, имеют непропорциональные результаты.
rancid_banana
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.