СТАТУС ВЫЗОВА: ОТКРЫТ
Прокомментируй, открой пиар или иначе на меня кричи, если я скучаю по твоему боту.
Дилемма заключенного ... с тремя вариантами. Сумасшедший, а?
Вот наша матрица выплат. Игрок А слева, В сверху
A,B| C | N | D
---|---|---|---
C |3,3|4,1|0,5
N |1,4|2,2|3,2
D |5,0|2,3|1,1
Матрица выплат разработана таким образом, что обоим игрокам лучше всегда сотрудничать, но вы можете получить (обычно), выбрав «Нейтральный» или «Дефект».
Вот несколько (конкурирующих) примеров ботов.
# turns out if you don't actually have to implement __init__(). TIL!
class AllC:
def round(self, _): return "C"
class AllN:
def round(self, _): return "N"
class AllD:
def round(self, _): return "D"
class RandomBot:
def round(self, _): return random.choice(["C", "N", "D"])
# Actually using an identically-behaving "FastGrudger".
class Grudger:
def __init__(self):
self.history = []
def round(self, last):
if(last):
self.history.append(last)
if(self.history.count("D") > 0):
return "D"
return "C"
class TitForTat:
def round(self, last):
if(last == "D"):
return "D"
return "C"
Ваш бот - это класс Python3. Новый экземпляр создается для каждой игры и round()
вызывается каждый раунд, с выбором вашего оппонента из прошлого раунда (или None, если это первый раунд)
В награду за награду 50 представителей.
конкретика
- Каждый бот играет каждого другого бота (1 на 1), включая самого себя, в раундах [УДАЛЕНО].
- Стандартные лазейки запрещены.
- Не связывайтесь ни с чем вне вашего класса или другими закулисными махинациями.
- Вы можете отправить до пяти ботов.
- Да, вы можете реализовать рукопожатие.
- Любой ответ, кроме
C
,N
илиD
будет принят как молчаN
. - Очки каждого бота из каждой игры, в которую они играют, будут суммироваться и сравниваться.
контроллер
Другие языки
Я скину API, если кому-то это нужно.
Результаты: 2018-11-27
27 bots, 729 games.
name | avg. score/round
----------------|-------------------
PatternFinder | 3.152
DirichletDice2 | 3.019
EvaluaterBot | 2.971
Ensemble | 2.800
DirichletDice | 2.763
Shifting | 2.737
FastGrudger | 2.632
Nash2 | 2.574
HistoricAverage | 2.552
LastOptimalBot | 2.532
Number6 | 2.531
HandshakeBot | 2.458
OldTitForTat | 2.411
WeightedAverage | 2.403
TitForTat | 2.328
AllD | 2.272
Tetragram | 2.256
Nash | 2.193
Jade | 2.186
Useless | 2.140
RandomBot | 2.018
CopyCat | 1.902
TatForTit | 1.891
NeverCOOP | 1.710
AllC | 1.565
AllN | 1.446
Kevin | 1.322
king-of-the-hill
python
SIGSTACKFAULT
источник
источник
while len(botlist) > 1:
сbotlist.remove(lowest_scoring_bot)
в нижней части цикла, вы получите элиминации турнир с интересными результатами.Ответы:
EvaluaterBot
Выигрывает против всех ранее представленных ботов, за исключением (возможно) случайного бота (но он может иметь преимущество, потому что он выбирает D при ничьей, а D должен оптимально) и играет постоянную ничью против себя.
источник
Равновесие по Нэшу
Этот бот взял курс теории игр в колледже, но был ленив и не пошел в класс, где они освещали повторяющиеся игры. Таким образом, он играет только в смешанном равновесии Нэша. Оказывается, 1/5 2/5 2/5 - смешанный NE для выплат.
Постоянное злоупотребление равновесием по Нэшу
Этот бот взял один или два урока от своего ленивого брата. Проблема его ленивого брата состояла в том, что он не использовал фиксированные стратегии. Эта версия проверяет, является ли противник постоянным игроком или титфортом, и играет соответственно, иначе она играет в обычном равновесии Нэша.
Единственным недостатком является то, что в среднем он получает 2,2 очка за ход, играя против самого себя.
источник
class NashEquilibrium: def round(self, _): a = random.random() for k, v in [(0.2, "C"), (0.6, "N"), (1, "D")]: if a <= k: return v
TatForTit
Этот бот будет чередовать выбор DNDN, в то время как TitForTat чередует CDCD, для среднего чистого выигрыша в 3 очка за раунд, если я правильно прочитал матрицу выплат. Я думаю, что это может быть оптимальным против TitForTat. Очевидно, что это может быть улучшено, чтобы обнаружить противника без TFT и принять другие стратегии, но я просто стремился к первоначальной награде.
источник
PatternFinder
Этот бот просматривает предыдущие вхождения недавнего игрового состояния, чтобы увидеть, как противник отреагировал на эти вхождения, с предпочтением более длинных матчей и более недавних матчей, а затем выполняет ход, который «превзойдет» предсказанный ход оппонента. Есть много возможностей для того, чтобы он был умнее со всеми данными, которые он отслеживает, но у меня не хватило времени поработать над этим.
источник
нефрит
Начинается оптимистично, но становится все более и более горьким, поскольку противник отказывается сотрудничать. Множество магических констант, которые, вероятно, могут быть изменены, но это, вероятно, не будет достаточно хорошо, чтобы оправдать время.
источник
Ансамбль
Это работает множество связанных моделей. Отдельные модели учитывают разные объемы истории и имеют возможность либо всегда выбирать ход, который оптимизирует ожидаемую разницу выплат, либо случайным образом выбирать ход пропорционально ожидаемой разнице выплат.
Затем каждый член ансамбля голосует за свой предпочтительный ход. Они получают количество голосов, равное тому, сколько они выиграли больше, чем противник (что означает, что ужасные модели получат отрицательные голоса). Какой бы ход ни выиграл, тогда выбирается голос.
(Вероятно, им следует распределить свои голоса между ходами пропорционально тому, насколько они одобряют каждый, но мне все равно, чтобы сделать это прямо сейчас.)
Он превосходит все, что опубликовано до сих пор, кроме EvaluaterBot и PatternFinder. (Один на один, он побеждает EvaluaterBot и проигрывает PatternFinder).
Тестовая структура
В случае, если кто-то еще найдет это полезным, вот тестовая структура для просмотра отдельных матчей. Python2. Просто поместите всех оппонентов, которые вас интересуют, в oppents.py и измените ссылки на Ensemble на свои собственные.
источник
OldTitForTat
Игроку старой школы лень обновляться по новым правилам.
источник
NeverCOOP
Если противоположный бот имеет дефект или является нейтральным, выберите дефект. В противном случае, если это первый ход или бот противника сотрудничает, выберите нейтральный. Я не уверен, насколько хорошо это будет работать ...
источник
if(last):
ваш бот Grudger, и определяет, был ли предыдущий раунд.None in "ND"
ошибки.if last and last in "ND":
было слишком сложно?LastOptimalBot
Предполагается, что бот-противник всегда будет снова играть один и тот же ход, и выбирает тот, который имеет лучшую отдачу от него.
Сред:
источник
return last
.return last
, LOB пошел бы 18-9 за 6 раундов, а не 13-10 за 5 раундов, которые он получает в настоящее время. Я думаю, что все в порядке - не беспокойтесь об оптимизации примера ботов.return last
я думаю, что T4T будет лучше для этого испытанияif(last): return last; else: return "C"
хуже.CopyCat
Копирует последний ход противника.
Я не ожидаю, что это будет хорошо, но никто еще не реализовал эту классику.
источник
Улучшенная игра в кости Дирихле
Это улучшенная версия Dirichlet Dice. Вместо того, чтобы брать ожидаемое мультиномиальное распределение из распределения Дирихле, оно выбирает мультиномиальное распределение случайным образом из распределения Дирихле. Затем вместо того, чтобы рисовать из многочлена и давать на него оптимальный ответ, он дает оптимальный ожидаемый ответ на данный многочлен, используя точки. Таким образом, случайность существенно сместилась с многочленного тиража к тиражу Дирихле. Кроме того, приоры теперь более плоские, чтобы стимулировать исследования.
Он «улучшен», потому что теперь он учитывает систему баллов, давая наилучшее ожидаемое значение по отношению к вероятностям, в то же время сохраняя ее случайность, рисуя сами вероятности. Раньше я пытался просто получить наилучшую ожидаемую отдачу от ожидаемых вероятностей, но это плохо сработало, потому что он просто застрял и не исследовал достаточно, чтобы обновить свои кости. Также это было более предсказуемым и пригодным для использования.
Исходное представление:
Dirichlet Dice
По сути, я предполагаю, что ответ оппонента на мой последний выходной сигнал является многочленной переменной (взвешенная игральная кость), по одной для каждого из моих выходных данных, поэтому есть игральная кость для «C», одна для «N» и одна для «D» , Так что, если мой последний бросок был, например, «N», то я бросаю «N-кубик», чтобы угадать, каким будет их ответ на мой «N». Я начинаю с предварительного Дирихле, который предполагает, что мой оппонент несколько «умен» (более вероятно, что он сыграет тот, кто лучше всех выиграл по сравнению с моим последним броском, с наименьшей вероятностью сыграет тот, кто выиграл хуже). Я генерирую «ожидаемое» мультиномиальное распределение из соответствующего предварительного Дирихле (это ожидаемое значение распределения вероятностей по весам их игральных костей). Я бросаю взвешенные кости из моего последнего выхода,
Начиная с третьего раунда, я делаю байесовское обновление соответствующего Dirichlet перед последним ответом моего оппонента на то, что я сыграл два раунда назад. Я пытаюсь итеративно узнать их веса.
Я мог бы также просто выбрать ответ с наилучшим «ожидаемым» результатом, когда генерировал кости, вместо того, чтобы просто бросать кости и отвечать на результат. Однако я хотел сохранить случайность, чтобы мой бот был менее уязвим к тем, кто пытается предсказать паттерн.
источник
Kevin
Выбирает худший выбор. Худший бот сделан.
Бесполезный
Он просматривает последние два хода, сделанные противником, и выбирает самое незавершенное, иначе он выбирает что-то случайное. Вероятно, есть лучший способ сделать это.
источник
Исторический Средний
Рассматривает историю и находит действие, которое было бы лучше всего в среднем. Начинается кооператив.
источник
Средневзвешенное
Поведение оппонента моделируется как прямоугольный треугольник с углами для CND в 0,0 0,1 1,0 соответственно. Каждое движение противника сдвигает точку в пределах этого треугольника к этому углу, и мы играем, чтобы побить ход, обозначенный точкой (с C, дающим регулируемо маленький срез треугольника). Теоретически я хотел, чтобы это имело более длинную память с большим весом к предыдущим ходам, но на практике текущая мета предпочитает быстро меняющихся ботов, так что это превращается в приближение LastOptimalBot против большинства врагов. Размещение для потомков; может быть, кто-то будет вдохновлен.
источник
слово из четырех букв
Попытайтесь найти образец в движениях противника, предполагая, что они также наблюдают наш последний ход.
источник
Рукопожатие
Признает, когда он играет против себя, а затем сотрудничает. В противном случае имитирует LastOptimalBot, который выглядит как лучшая однострочная стратегия. Работает хуже, чем LastOptimalBot, на величину, обратно пропорциональную количеству раундов. Очевидно, было бы лучше, если бы в поле было больше копий * кашель ** подмигивание *.
источник
ShiftingOptimalBot
Этот бот использует алгоритм LastOptimalBot, пока он выигрывает. Однако, если другой бот начинает предсказывать это, он начинает играть с того хода, который его противник сыграл последним (это ход, который превосходит ход, который побьет LastOptimalBot). Он перебирает простые транспонирования этих алгоритмов до тех пор, пока он продолжает проигрывать (или когда ему надоедает много рисовать).
Честно говоря, я удивлен, что LastOptimalBot находится на пятом месте, когда я публикую это. Я вполне уверен, что это будет лучше, если я правильно написал этот питон.
источник
HandshakePatternMatch
Почему шаблон соответствует самому себе? Рукопожатие и сотрудничество.
источник
import PatternFinder
обманывает в моих книгах.Запрограммированный
Просто воспроизводит жестко запрограммированную последовательность ходов, оптимизированных для победы над некоторыми из лучших детерминированных ботов.
источник