Дилемма заключенного v.3 - Дилемма Петри


17

Безумный ученый только что создал новый вид бактерий! Он решил назвать это Noblus Gentlemanusпосле наблюдения его поведения. Тем не менее, у его бактерий закончилась еда, и они объявили войну, поскольку они способны собирать трупы других бактерий, чтобы иметь достаточно еды для создания своих копий. Есть несколько различных подвидов этой бактерии, которые имеют разные стратегии в игре Prisoner's Dilemma, их любимой игре. Есть пять бактерий от каждого отдельного подвида. В Dilemma Prisoner's каждый из двух игроков одновременно выбирает либо дефект, либо сотрудничество. Если один игрок выбирает сотрудничество, а другой выбирает по умолчанию, неплательщик получает 2 очка, а сотрудник теряет 3 очка. Если оба игрока выбирают сотрудничество, оба игрока получают 1 очко. Если оба игрока выбирают по умолчанию, оба игрока теряют 1 очко.

Будучи благородными джентльменами, бактерии решили вступить в эту войну, сыграв 200 раундов в длинных играх «Дилемма повторного заключенного». Проигравший каждого поединка совершит самоубийство, позволяя победителю клонировать себя. В случае связи обе бактерии останутся живыми, но ни одна из них не сможет клонировать себя. Кроме того, все бактерии из матча переносят более 10% своих очков к следующему матчу. Клон переносит точки бактерии, которой он был клонирован. Кроме того, в каждом ходу существует один шанс из десяти, что одна бактерия мутирует в другой подвид, с 0 бонусными баллами (если я получаю жалобы на случайность этого, я могу удалить ее). После того, как бактерии сыграли число этих поединков, равное числу подвидов бактерий, умноженному на десять, безумный ученый случайно уронил чашку Петри, в которой живут бактерии, и все бактерии приобретают новые источники пищи, заканчивая их поединки. Это отличается от обычного повторного конкурса дилеммы заключенного, так как в нем участвуют дуэли 1 на 1 с очками переноса, а не просто попытка набрать наибольшее количество очков в целом. Это имеет большое значение в том, насколько эффективна данная стратегия.

Каждая бактерия будет получать информацию в начале своего хода в формате: (номер хода, текущие очки, очки врагов, ваши предыдущие ходы [в строке, используя символ «c» для сотрудничества и символ «d» для дефекта) ], враги предыдущими ходами [в том же формате]).

Вот четыре примера стратегий, которые будут введены. Я на самом деле думаю, что Дефектор может победить, хотя это очень просто.

Синица для Тат

def titfortatfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter==0 or enlist[counter-1] == "c":
        return "c"
    else:
        return "d"

RandomPick

from random import choice
def randompickfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter == 199:
        return "d"
    else:
        return choice(["d", "c"])

кооператор

def cooperatorfunc(counter, mypoints, enpoints, mylist, enlist):
    return "c"

перебежчик

def defectorfunc(counter, mypoints, enpoints, mylist, enlist):
    return "d"

Все представления должны быть в форме функции Python 2.7, где имя является именем представления без пробелов, с funcконцом. Если кто-то хочет отправить ответ на другом языке, пожалуйста, введите его в псевдокоде, чтобы я смог преобразовать его в Python при редактировании вашего ответа, как только у меня будет время, или дайте мне инструкции по взаимодействию вашего языка с моим контроллером, который находится ниже, настроен для всех представлений по состоянию на 4 июня.

from titfortat import titfortatfunc
from randompick import randompickfunc
from cooperator import cooperatorfunc
from defector import defectorfunc
from luckytitfortat import luckytitfortatfunc
from randomtitfortat import randomtitfortatfunc
from remorsefulaggressor import remorsefulaggressorfunc
from everyother import everyotherfunc
from niceguy import niceguyfunc
from titfortatbackstab import titfortatbackstabfunc
from gentleDefector import gentleDefectorfunc
from anticapitalist import anticapitalistfunc
from grimtrigger import grimtriggerfunc
from bizzaro import bizzarofunc
from neoanticapitalist import neoanticapitalistfunc
from bittertat import bittertatfunc
from teamer import teamerfunc
from copyfirst import copyfirstfunc
from exploitivetat import exploitativetatfunc
from defectorv2 import defectorv2func
from crazytat import crazytatfunc
from randomchoicev2 import randomchoicev2func
from twotitsforatat import twotitsforatatfunc
from threetitsforatat import threetitsforatatfunc
from fourtitsforatat import fourtitsforatatfunc
from fivetitsforatat import fivetitsforatatfunc
from sixtitsforatat import sixtitsforatatfunc
from tentitsforatat import tentitsforatatfunc
from theelephant import theelephantfunc
from xbittertat import xbittertatfunc
from fifteentitsforatat import fifteentitsfortatfunc
from twentytitsforatat import twentytitsforatatfunc
from fox import foxfunc
from onehundredfortysixtitsforatat import onehundredfourtysixtitsforatatfunc
from gameofthrones import gameofthronesfunc
from boy import boyfunc
from grimace import grimacefunc
from fiftytitsforatat import fiftytitsfortatfunc
from soreloser import soreloserfunc
from everyotherd import everyotherdfunc
from fiftythreetitsfortat import fiftythreetitsfortatfunc
from twentyfivetitsfortat import twentyfivetitsfortatfunc
from handshake import handshakefunc
from anty import antyfunc
from fiftyfourtitsforatat import fiftyfourtitsfortatfunc
from kindatitsfortat import kindatitsfortatfunc

import random

players = 38

rounds = players*10

def runcode(num, points1, points2, history1, history2, cell):
    ans = ""
    if cell == 0:
        ans = titfortatfunc(num, points1, points2, history1, history2)
    elif cell == 1:
        ans = randompickfunc(num, points1, points2, history1, history2)
    elif cell == 2:
        ans = cooperatorfunc(num, points1, points2, history1, history2)
    elif cell == 3:
        ans = defectorfunc(num, points1, points2, history1, history2)
    elif cell == 4:
        ans = luckytitfortatfunc(num, points1, points2, history1, history2)
    elif cell == 5:
        ans = randomtitfortatfunc(num, points1, points2, history1, history2)
    elif cell == 6:
        ans = remorsefulaggressorfunc(num, points1, points2, history1, history2)
    elif cell == 7:
        ans = everyotherfunc(num, points1, points2, history1, history2)
    elif cell == 8:
        ans = niceguyfunc(num, points1, points2, history1, history2)
    elif cell == 9:
        ans = titfortatbackstabfunc(num, points1, points2, history1, history2)
    elif cell == 10:
        ans = gentleDefectorfunc(num, points1, points2, history1, history2)
    elif cell == 11:
        ans = anticapitalistfunc(num, points1, points2, history1, history2)
    elif cell == 12:
        ans = grimtriggerfunc(num, points1, points2, history1, history2)
    elif cell == 13:
        ans = bizzarofunc(num, points1, points2, history1, history2)
    elif cell == 14:
        ans = neoanticapitalistfunc(num, points1, points2, history1, history2)
    elif cell == 15:
        ans = tentitsforatatfunc(num, points1, points2, history1, history2)
    elif cell == 16:
        ans = bittertatfunc(num, points1, points2, history1, history2)
    elif cell == 17:
        ans = copyfirstfunc(num, points1, points2, history1, history2)
    elif cell == 18:
        ans = exploitativetatfunc(num, points1, points2, history1, history2)
    elif cell == 19:
        ans = sixtitsforatatfunc(num, points1, points2, history1, history2)
    elif cell == 20:
        ans = fifteentitsfortatfunc(num, points1, points2, history1, history2)
    elif cell == 21:
        ans = fivetitsforatatfunc(num, points1, points2, history1, history2)
    elif cell == 22:
        ans = twentytitsforatatfunc(num, points1, points2, history1, history2)
    elif cell == 23:
        ans = threetitsforatatfunc(num, points1, points2, history1, history2)
    elif cell == 24:
        ans = fiftyfourtitsfortatfunc(num, points1, points2, history1, history2)
    elif cell == 25:
        ans = theelephantfunc(num, points1, points2, history1, history2)
    elif cell == 26:
        ans = xbittertatfunc(num, points1, points2, history1, history2)
    elif cell == 27:
        ans = foxfunc(num, points1, points2, history1, history2)
    elif cell == 28:
        ans = gameofthronesfunc(num, points1, points2, history1, history2)
    elif cell == 29:
        ans = boyfunc(num, points1, points2, history1, history2)
    elif cell == 30:
        ans = grimacefunc(num, points1, points2, history1, history2)
    elif cell == 31:
        ans = soreloserfunc(num, points1, points2, history1, history2)
    elif cell == 32:
        ans = everyotherdfunc(num, points1, points2, history1, history2)
    elif cell == 33:
        ans = twentyfivetitsfortatfunc(num, points1, points2, history1, history2)
    elif cell == 34:
        ans = fiftythreetitsfortatfunc(num, points1, points2, history1, history2)
    elif cell == 35:
        ans = handshakefunc(num, points1, points2, history1, history2)
    elif cell == 36:
        ans = antyfunc(num, points1, points2, history1, history2)
    elif cell == 37:
        ans = kindatitsfortatfunc(num, points1, points2, history1, history2)


    return ans

def fight(l1,l2):
    num1,num2=l1[0],l2[0]
    points1,points2=l1[1],l2[1]
    history1 = ""
    history2 = ""

    for num in range(200):
        p1 = runcode(num, points1, points2, history1, history2, num1)
        p2 = runcode(num, points2, points1, history2, history1, num2)

        history1+=p1
        history2+=p2

        if p1 == "c" and p2 == "c":
            points1 += 1
            points2 += 1
        elif p1 == "c" and p2 == "d":
            points1 -= 3
            points2 += 2
        elif p1 == "d" and p2 == "c":
            points1 += 2
            points2 -= 3
        elif p1 == "d" and p2 == "d":
            points1 -= 1
            points2 -= 1

    if points1 > points2:
        return [l1[0], points1/10], [l1[0], points1/10]
    elif points1 < points2:
        return [l2[0], points2/10], [l2[0], points2/10]
    else:
        return [l1[0], points1/10], [l2[0], points2/10]

def rounddoer(bots):
    bots2=[]
    for x in range(len(bots)):
        if x%2==0:
            out1, out2 = fight(bots[x], bots[x-1])
            bots2.append(out1)
            bots2.append(out2)

    return bots2

def gamedoer():

    bots=[[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,0],[16,0],[17,0],[18,0],[19,0],[20,0],[21,0],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0],[29,0],[30,0],[31,0],[32,0],[33,0],[34,0],[35,0],[36,0],[37,0],[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,0],[16,0],[17,0],[18,0],[19,0],[20,0],[21,0],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0],[29,0],[30,0],[31,0],[32,0],[33,0],[34,0],[35,0],[36,0],[37,0],[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,0],[16,0],[17,0],[18,0],[19,0],[20,0],[21,0],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0],[29,0],[30,0],[31,0],[32,0],[33,0],[34,0],[35,0],[36,0],[37,0],[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,0],[16,0],[17,0],[18,0],[19,0],[20,0],[21,0],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0],[29,0],[30,0],[31,0],[32,0],[33,0],[34,0],[35,0],[36,0],[37,0],[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,0],[16,0],[17,0],[18,0],[19,0],[20,0],[21,0],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0],[29,0],[30,0],[31,0],[32,0],[33,0],[34,0],[35,0],[36,0],[37,0]]
    random.shuffle(bots)
    counter=0

    while counter < rounds:

        counter += 1
        bots = rounddoer(bots)

        if random.randint(0,10) == 9:
            bots[random.randint(0, players*5)-1] = [random.randint(0, players-1), 0]

        random.shuffle(bots)

##        for item in bots:
##            print str(item[0]) + " with " + str(item[1]) + " bonus points."

    return bots

a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,mycounter=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

while mycounter < 1000:
    mycounter += 1
    bots = gamedoer()

    print "Game: " + str(mycounter)

    for item in bots:
        if item[0]==0:
            a0 += 1
        if item[0]==1:
            a1 += 1
        if item[0]==2:
            a2 += 1
        if item[0]==3:
            a3 += 1
        if item[0]==4:
            a4 += 1
        if item[0]==5:
            a5 += 1
        if item[0]==6:
            a6 += 1
        if item[0]==7:
            a7 += 1
        if item[0]==8:
            a8 += 1
        if item[0]==9:
            a9 += 1
        if item[0]==10:
            a10 += 1
        if item[0]==11:
            a11 += 1
        if item[0]==12:
            a12 += 1
        if item[0]==13:
            a13 += 1
        if item[0]==14:
            a14+=1
        if item[0]==15:
            a15+=1
        if item[0]==16:
            a16+=1
        if item[0]==17:
            a17+=1
        if item[0]==18:
            a18 += 1
        if item[0]==19:
            a19+=1
        if item[0]==20:
            a20+=1
        if item[0]==21:
            a21+=1
        if item[0]==22:
            a22+=1
        if item[0]==23:
            a23+=1
        if item[0]==24:
            a24+=1
        if item[0]==25:
            a25+=1
        if item[0]==26:
            a26+=1
        if item[0]==27:
            a27+=1
        if item[0]==28:
            a28+=1
        if item[0]==29:
            a29+=1
        if item[0]==30:
            a30+=1
        if item[0]==31:
            a31+=1
        if item[0]==32:
            a32+=1
        if item[0]==33:
            a33+=1
        if item[0]==34:

Этот конкурс завершен

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

ЗАКЛЮЧИТЕЛЬНЫЕ СЧЕТЫ !!!!!

Tit for Tat: 18
Random Pick: 28
Cooperator: 19
Defector: 24
Lucky Tit for Tat: 23
Random Tit for Tat: 23
Remorseful Aggressor: 22
Every Other C: 23
Nice Guy: 18
Tit for Tat Backstab: 15
Gentle Defector: 22
Anticapitalist: 27
Grim Trigger: 19
Bizzaro: 21
NeoAnticapitalist: 24
Ten Tits for a Tat: 240
Bitter Tat: 12
Copy First: 30
Exploitative Tat: 19
Six Tits for a Tat: 16
Thirty Tits for Tat: 4129
Five Tits for a Tat: 22
Forty Tits for a Tat: 1972
Three Tits for a Tat: 22
Fifty Four Tits for a Tat: 25805
The Elephant: 31
Extra Bitter Tat: 28
Fox: 35
Game of Thrones: 11297
The Boy: 31
Grimace: 26
Sore Loser: 39
Every Other D: 18
Twenty Five Tits for a Tat: 2399
Fifty Three Tits for a Tat: 5487
Handshake: 28
Anty: 26
Kinda Tits for Tat: 20
Prudent Defector: 154539
Bizzarro Trigger: 25
Young Mathematician: 21
Older Mathematician: 16
Perfect Gentleman: 1953341

Итак, похоже, что Perfect Gentleman является победителем. Поздравляем Draco18, который определенно заслуживает своей зеленой галочки.


Комментарии не для расширенного обсуждения; этот разговор был перемещен в чат .
Деннис

1
ПРИМЕЧАНИЕ: ЕСЛИ ВЫ РЕДАКТИРУЕТЕ СВОЮ ПРОГРАММУ, ПОЖАЛУЙСТА, ДАЙТЕ МНЕ КОММЕНТАРИЙ, ПОЭТОМУ Я УВЕДОМЛЯЮ, ИЛИ НЕ МОЖЕТ БЫТЬ ПОСТАВЛЕНО НА ДОКУМЕНТУ !!!!!!!!!!!!!!!!!!!! !!!
Грифон - Восстановить Монику

Хлоп! Я только что понял, сколько это импорта.
Грифон - Восстановить Монику

1
Эй, Грифон, ты работаешь над этими окончательными рейтингами? ;)
Draco18s больше не доверяет SE

Извините, я забыл об этом. Дайте мне немного, чтобы запустить его.
Грифон - Восстановить Монику

Ответы:


8

Идеальный джентльмен

У меня нет хорошего описания для этого бота. Я наткнулся на пару потенциальных оптимизаций, проверил их, точно настроил, и в итоге получил бактерии, которые полностью уничтожают конкурентов. Вместо этого я прокомментировал сам код, чтобы объяснить, что он делает.

import random
def perfectgentlemanfunc(num, i, d, c, en):
    if num>0 and i < 0 and d > 0 and -i%3 == 0 and d%2 == 0 and en[0] == "d":
        #probably very first iteration, probably facing a defector: feed it free points
        #    defector cannot be beaten by *any* bot unless that bot
        #    entered with a point lead. defector does some of our work for us
        if num >= 140:
            #140 threshold restricts how much we feed
            return "d"
        return "c"
    turn_to_betray = 130
    if num > turn_to_betray and en[turn_to_betray -2] == "c" and
     en[turn_to_betray -1] == "c" and en[turn_to_betray] == "d":
        #if self, then sacrifice the lower point bot to raise the points of the higher
        #(better net outcome than "c/c" cooperation)
        #    Handshake independently arrived at this same optimization
        if i == d:
            #max 50% probability of choosing different possible. May as well take it
            #    "ccd" has a 55% chance of choosing the same
            #    better outcomes for splitting early
            return "cd"[random.randint(0,1)]
        if i > d:
            return "d"
        return "c"
    #betray after betray point, or if behind by >200
    #performs 6 percentage points better than not having the condition
    if num >= turn_to_betray or i + 200 < d
        return "d"
    else:
        #be nice the first turn
        if num == 0:
            return "c";
        #finally, be tit-for-tat
        return en[-1]

Несколько значений были произвольно выбраны с проверенными альтернативами, и значения здесь почти оптимальны в этой точке. Против нынешнего распространения противоборствующих фракций The Perfect Gentleman достигает полного доминирования (100% популяции бактерий) примерно в 90% случаев (плюс или минус 3 процентных пункта).

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

Он управляет значительной частью своего контроля посредством поддержки Defector, но это было разрешено в соответствии с правилами (примеры стратегий были честной игрой для таргетинга). У этого есть побочный эффект также поддержки Game of Thrones, но это было непреднамеренным, поскольку эти два неразличимы на основе критериев, которые я выбрал. Эти «типы-перебежчики» получают преимущество во втором раунде и в результате убирают нескольких проблемных соседей (типы N-T4T), а когда они заменяют «Идеальный джентльмен», они израсходовали свое преимущество в очках и быстро расходуются.

Приблизительно 5% -ная вероятность того, что все совершенные джентльмены в первом раунде окажутся в паре с типами Дефекторов, в конечном итоге совершат массовое самоубийство. В этом случае один из типов n-T4t достигает полного доминирования (196 клеток из 196). Очень редко один из других типов (Игра престолов, Мальчик, Гримаса, Больной неудачник ...) не может полностью исчезнуть и набрать одно или два очка.

Текущий симулятор (все еще продолжается около 200 игр). Все записи с оценкой 0 удалены. Похоже, Game of Thrones и 54-T4T разделили раунд (195 очков между ними) после того, как PG был ликвидирован.

Game: 90

Cooperator: 1
Remorseful Aggressor: 1
Copy First: 1
Six Tits for a Tat: 1
Thirty Tits for Tat: 393
Five Tits for a Tat: 1
Fifty Four Tits for a Tat: 538
Game of Thrones: 248
Perfect Gentleman: 16456 (93.2)%

##Simulation Terminated: Adding new bots

Backstabbing Синица для Tat (с прощением)

Это в основном Lucky Tit for Tat (он же Tit for Tat with Progiveness), который является «решенным» оптимальным решением (для некоторого значения «счастливчик») с поворотом. Поскольку мы точно знаем, сколько раундов длится игра, эти бактерии наносят удар в последнем раунде, таким образом обеспечивая чистый выгодный результат против любых других бактерий Tit for Tat и Cooperator (против себя он заканчивается чистым нулем, как если бы он имел сотрудничал). Из-за переноса на 10% это дает долгосрочное преимущество.

from random import randint
def titfortatbackstabfunc(num, i, d, c, enlist):
    if num == 199:
        return "d";
    lucky = randint(0, 200)
    if lucky == 0:
        return "c"
    if num == 0 or enlist[-1] == "c":
        return "c"
    else:
        return "d"

Горький Тат

Bitter Tat использует в своих интересах любые попытки сотрудничества, данные противником, когда противник впереди в точках. Большинство бактерий предлагают оливковую ветвь по крайней мере один раз в течение 200 раундов, и, поскольку Bitter Tat отстает в общем, они будут доить эти 5 очков в отчаянной попытке выздоровления.

В противном случае, это сиськи в соответствии с обычной доминирующей стратегией. Кроме того, это немного больше придурок, чем его двоюродный брат и удар в спину раунд ранее и не предлагает прощения.

def bittertatfunc(num, i, d, c, enlist):
    if i < d:
        return "d";
    if num >= 198:
        return "d";
    if num == 0 or enlist[-1] == "c":
        return "c"
    else:
        return "d"

Bitter Tat был разработан с учетом поведения других ботов против Tit for Tat и паттернов, выраженных в этих результатах, но не предназначен для явного противодействия этим стратегиям: это все еще универсальная формула.

Экстра Горький Тат

def xbittertatfunc(num, i, d, c, enlist):
    if i < d:
        return "d";
    if num >= 188:
        return "d";
    if num == 0 or enlist[-1] == "c":
        return "c"
    else:
        return "d"

Чрезвычайно горький, рано уходя.


1
Пожалуйста, измените название вашей функции, так как это уже занято.
Грифон - Восстановить Монику

@Gryphon Ой, простите, я не осознавал, что сделал это. На самом деле я не пишу код на Python, я просто разбил два кусочка кода вместе.
Draco18s больше не доверяет SE

1
I suspect it will outperform NeoAnticapitalist by a small margin, Больше похоже на более чем 30000 очков.
Грифон - Восстановить Монику


2
Я ценю, что вы создали бота, чтобы этот кот больше не был шуткой
Разрушаемый лимон

8

антикапиталистической

Еще один простой. Для четных матчей (начиная с одного и того же счета) ведет себя почти так же, как TitForTat, но основная идея - выжить в матче.

def anticapitalistfunc(counter, mypoints, enpoints, mylist, enlist):
    if mypoints >= enpoints:
        return "c"
    else:
        return "d"

Нежный Перебежчик

Моя идея здесь состоит в том, чтобы уйти, кроме случаев, когда мой враг обычно сотрудничает. Тем не менее, он начинает сотрудничать.

def gentleDefectorfunc(counter, mypoints, enpoints, mylist, enlist):
    if enlist.count("d") * 4 > len(enlist):
        return "d"
    else:
        return "c"

NeoAnticapitalist

Улучшение антикапиталистов (или я так думаю). Не вижу смысла сотрудничать в последнем повороте. Я также не вижу причин для сотрудничества, когда я уверен, что мой противник не будет.

def neoanticapitalistfunc(counter, mypoints, enpoints, mylist, enlist):
    if mypoints >= enpoints:
        if counter > 1:
            if counter == 199 or (enlist[-1] != "c" and enlist[-2] != "c"):
                return "d"
        return "c"
    else:
        return "d"

Я на самом деле удивлен, что не думал об этом, но это великолепно. Я не знаю, победит ли это, но я думаю, что это должно работать очень хорошо.
Грифон - Восстановить Монику

@Gryphon добавил нового бота (и объединил два моих других)
Masclins

@Gryphon спасибо за оба издания
Masclins

Нет проблем, @AlbertMasclans
Gryphon - Восстановить Монику

Судя по симуляциям, которые я проводил, NeoAnticapitalist, похоже, взял на себя инициативу Backstabbing Tit for Tat.
Грифон - Восстановить Монику

6

Агрессор покаяния

from random import randint
def remorsefulaggressorfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter == 0:
        return "d"
    if (counter > 195 and mylist[-1] == "d"):
        return "d"
    if ((counter == 1 or counter > 2) and enlist[-1] == "d"):
        return "d"
    if (counter == 2 and enlist[-1] == "d" and enlist[-2] == "d"):
        return "d"
    if (counter >= 195 and randint(0, 200 - counter) == 0):
        return "d"
    else:
        return "c"

Это разработано для того, чтобы «идти в ногу» с Дефектором, каждый раз отступая от него, а также для того, чтобы победить стратегии, основанные на сиськах.

Основная идея состоит в том, что мы начинаем с дефекта, но если противник сотрудничал с ходом 1, мы сотрудничаем дважды, чтобы избежать цикла взаимных обвинений, избегая, таким образом, слишком большого штрафного очка. (Если, однако, оппонент позже выйдет из строя, мы сами не нарушим цикл; мы заставим их сделать это и, вероятно, проиграем в результате.) Затем в конце игры мы выбираем случайное время. в течение последних 5 оборотов нанести удар врагу в спину, что дает нам еще одно отступление, чем у них, и, таким образом, означает, что, пока мы не слишком отстаем по очкам переноса, мы в конечном итоге выигрываем, не жертвуя при этом переносом в плане переноса. , (Рандомизация периода времени означает, что мы, скорее всего, войдем первыми с ударом в спину, а также, что эту стратегию нельзя «настроить», стремясь нанести удар назад одним ходом раньше.)


Поздравляю с номером 3! +1
Грифон - Восстановить Монику

6

Grim Trigger

Упрощенный бот, чтобы попытаться заполнить конкурс

Он будет сотрудничать, если только у врага не будет дефектов, и в этом случае он будет прощать

def grimtriggerfunc(I, Do, Not, Care, enlist): return "d" if "d" in enlist else "c"

ну, похоже, это не работает из-за мета-нта


Поздравляю с номером 5 место, +1.
Грифон - Восстановить Монику

@Sleafar Мне было интересно, кто будет таким подлым; _; хорошо
Разрушаемый Лимон

5

Игра престолов

def gameofthronesfunc(counter, mypoints, enpoints, mylist, enlist):
    turn_to_betray = 140
    if counter >= turn_to_betray or mypoints > enpoints or "d" in enlist:
        return "d"
    else:
        return "c"

Идея здесь в том, что вы никогда не сможете проиграть, предав, поэтому единственная причина для сотрудничества - если вы позади. У этого также есть общая структура других ответов T4T (без всякого прощения, потому что я не уверен, есть ли много смысла с другими претендентами здесь).

Ход, чтобы предать, возможно, должен быть изменен, чтобы выиграть, так как в равной гонке выигрывает T4Ter, который предает первым, но против очень кооперативного бота вы потеряете некоторые очки жизни. Я не уверен, что вершина вершина для этого холма, поэтому я просто иду на 140. Я бы не удивился, если бы это было намного раньше.

Если это заканчивается в чашке Петри с T4Ter, который предает ранее, или с перебежчиком (то есть с 146 T4T), то это полностью зависит от того, идет ли GoT впереди (он будет оставаться впереди) или если они равны / GoT отстает , в этом случае ранний предатель победит.


Поздравляю с третьим местом! +1
Грифон - Восстановить Монику

А теперь до второй!
Грифон - Восстановить Монику

Game of Thrones сражается с ботом, которого я сейчас тестирую. Простая стратегия работает хорошо для этого.
Draco18s больше не доверяет SE

4

Lucky Tit For Tat

import os
def luckytitfortatfunc(num, i, d, c, enlist):
    lucky = ord(os.urandom(1))
    lucky = int(round(200 * float(lucky - 0) / 255.0))
    if lucky == 0:
        return "c"
    if num == 0 or enlist[-1] == "c":
        return "c"
    else:
        return "d"

Я почти уверен, что где-то читал, что синица для ТАТ была лучшей стратегией. Я решил сделать так, чтобы другие программы могли использовать их просто для того, чтобы добавить разнообразия. Теперь с правильным генератором случайных чисел (это дает мне преимущество, верно?).


По сути, это выигрышная стратегия, все время, как отмечалось в википедии . Единственное отличие заключается в вероятности выхода из цикла дефектов «один за другим» (который зависит от совпадения всех других записей).
Draco18s больше не доверяет SE

1
@ Draco18s Это выигрышная стратегия для другой системы начисления очков, системы начисления очков. Базовая команда «синица за зубом» никогда не сможет выиграть раунд, если она не принесет несколько очков в раунд, поэтому это не будет хорошо.
Исаак

@isaacg прав, именно поэтому эта стратегия сейчас в 14-м из 18-ти (хотя я не имею права обвинять AHL в этом, так как 18-я программа - моя).
Грифон - Восстановить Монику

4

Слон

Слон никогда не забудет!

import re
def theelephantfunc(counter, mypoints, enpoints, mylist, enlist):
    interwoven = "".join(i for j in zip(mylist, enlist) for i in j)
    backwoven = interwoven[::-1]
    predict = re.match("^((?:..)*).*?(.).\\1(?:..)*$",backwoven)
    if(predict is None):
        return "c"
    predict = predict.groups()[1]
    if(predict == "d"):
        return "d"
    if(mypoints - enpoints >= 6):
        return "c"
    return "d"

Слон смотрит на историю боя и пытается выяснить, что планировал враг. Он смотрит как на свои ходы, так и на своих врагов!

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

Если он не может решить это, Слон просто Сотрудничает, поскольку дружба - всегда ответ.

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

Если он думает, что его противник будет сотрудничать, но его лидерство меньше или равно 6 точкам, то он отступит, чтобы закрепиться.

И, наконец, если он думает, что его противник будет сотрудничать, и у него сильное лидерство, он будет сотрудничать.


Я ждал чего-то подобного, что сработало лучше, чем Nice Guy. Тем не менее, я не смогу протестировать его около 8 часов, поэтому я смогу обновить примерно через 12-13.
Грифон - Восстановить Монику

4

54 сиськи для тат

def fiftyfourtitsfortatfunc (ну, больше, веселье, я, en):
    сиськи = 54
    если "d" в en [-tits:] или num> = (200-tits):
        возврат "д"
    возврат "с"

Интересно, это все равно победит?
Грифон - Восстановить Монику

Это выглядит как победа прямо сейчас!
Грифон - Восстановить Монику

Поздравляю, вы едва победили обоих моих лучших ботов!
Грифон - Восстановить Монику

@ Грифон Я бы сделал 5 сисек за тату, если бы не был так привязан к другим своим ботам :)
Алекс

Я думаю, что это будет за другой стороной кривой. Я мог бы проверить один сам, хотя!
Грифон - Восстановить Монику

3

Хороший парень

def niceguyfunc(counter, mypoints, enpoints, mylist, enlist):
  if counter < 2:
    return "c"

  mylast = mylist[-1]
  enlast = enlist[-1]
  last_found_index = -1

  for i, item in enumerate(mylist):
    if i == counter - 1:
      break
    if mylist[i] == mylast and enlist[i] == enlast:
      last_found_index = i

  if last_found_index == -1:
    return "c"
  else:
    if enlist[last_found_index + 1] == "c":
      return "c"
    else:
      return "d"

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


3

Хэкман [дисквалифицирован, как и ожидалось]

Хорошо, этот, вероятно, будет исключен из конкурса, но я действительно хочу попробовать это:

def hackmanfunc(counter, mypoints, enpoints, mylist, enlist):
        if enlist.count("#") > 0:
                return "c"
        elif counter >= 2 and enpoints > mypoints:
                return "d"
        elif counter == 198:
                return "d"
        elif counter == 199:
                return "#"
        elif counter == 0 or enlist[-1] == "c":
                return "c"
        elif counter >= 2 and enlist[-2] != "c":
                return "#"
        else:
                return "d"

Здесь я беру за основу BackstabbingTitForTat, который оказался лучшим в моих симуляциях. Кроме того, он в значительной степени основан на использовании неиспользуемого символа "#"(поэтому я говорю, что он, вероятно, будет исключен).

Теперь позвольте мне объяснить условия здесь:

1-й: Убедитесь, что два Хэкмена сотрудничают, если что-то пошло не так.

2-й: если я собираюсь проиграть против другого бота, по крайней мере, заставьте его потерять как можно больше очков, чтобы потом он не был большим врагом.

3-й: предать один ход раньше, поэтому выигрывает у Backstabbing

использование «#» вместо «d» заставляет меня получить 0 баллов вместо -1, а также общаться с другим хакменом, у которого меньше очков, поэтому он прекращает уходить.


2
Извините, но дисквалифицирован. Это считается возиться с процессом оценки. Вы ДОЛЖНЫ возвращать «c» или «d» каждый ход.
Грифон - Восстановить Монику

2
Тем не менее, это довольно изобретательно, поэтому мне жаль, что пришлось дисквалифицировать его.
Грифон - Восстановить Монику

3

Bizzaro

Делает полную противоположность синица за тат. Когда кто-то добр к нему, он показывает свою любовь, будучи злым, а когда кто-то злой, он показывает месть, будучи добрым. Сильно основано на синицах за тат.

def bizzarofunc(counter, mypoints, enpoints, mylist, enlist):
    if counter==0 or enlist[counter-1] == "c":
        return "d"
    else:
        return "c"

Интересный. Это будет убито Дефектором.
Грифон - Восстановить Монику

@ Грифон Лмао, на самом деле не осознавал этого. Но эй, Биззаро не знает разницы между правильным и неправильным, побеждает и проигрывает.
Тит Лукреций

Да, это будет перебежчик по отношению к кооператору и кооператор к перебежчику, что может создать некоторые интересные возможности. Он не может сосуществовать ни с чем, в том числе и с самим собой.
Грифон - Восстановить Монику

@ Грифон, да, он должен получить 0, когда он играет сам. Интересно, что будет с Gentle Defector.
Тит Лукреций

Интересно, что происходит, когда он сталкивается с ударом в спину, который побеждает перед этим представлением.
Грифон - Восстановить Монику

3

6 сиськи для тат

def sixtitsforatatfunc (num, more, fun, me, en):
    если "d" в en [-6:] или num> = 194:
        возврат "д"
    возврат "с"

Тит для Тат гонка вооружений происходит :)


Я чувствую, что мы пойдем за борт, и Дефектор украдет первое место.
Грифон - Восстановить Монику

3

Десять сиськи для тат

def tentitsforatatfunc(num, more, fun, me, en):
    if "d" in en[-10:] or num >= 190:
        return "d"
    return "c"

Дефекты ранее, а также дефекты, если его противник сбежал в последние десять ходов.

CopyFirst

def copyfirstfunc(num, mypoints, enpoints, myhistory, enhistory):        
    if num == 0 or num >= 197:
        return "d"
    else:
        return enhistory[0]

Это нарушает первый раунд, затем делает то, что делал противник в первом раунде, до 197-го раунда, когда он наносит удар в спину.

Сорок сисек для тата

def fourtytitsforatatfunc(num, mypoints, enpoints, myhistory, enhistory):
    if "d" in en[-40:] or num >= 150:
        return "d"
    return "c"

Если противник дезертировал в последние 40 ходов, дефект, иначе сотрудничать. Удар в спину за последние 50 ходов.

Три сиськи для тат

Если противник сбежал в последние 3 хода, дефект, иначе сотрудничать. Удар в спину за последние 5 ходов. Эта программа с небольшим отрывом похитила лидерство у Тита для двух татов.

def threetitsforatatfunc(num, mypoints, enpoints, myhistory, enhistory):
    if num == 0 or num==1 and enhistory[-1]=="c" or num==2 and enhistory[-1]=="c" and enhistory[-2]=="c":
        return "c"
    if enhistory[-1] == "d" or enhistory[-2] == "d" or enhistory[-3] == "d" or num >= 195:
        return "d"
    else:
        return "c"

Пять сисек для тата

def fivetitsforatatfunc(num, more, fun, me, en):
    if "d" in en[-5:] or num >= 194:
        return "d"
    return "c"

Если вы не можете понять, что это делает, вы идиот. Также нанесите удар в спину на один раунд раньше.


ИМО, не стесняйтесь представить свою собственную запись.
Draco18s больше не доверяет SE

Просто не был уверен, было ли это вообще справедливым.
Грифон - Восстановить Монику

Обычно, как правило, это лучший ответ - победивший бот.
Masclins

Это будет, я не просто выберу свой ответ. Это определенно не будет справедливым.
Грифон - Восстановить Монику

Я прошу прощения, я не понял, что я случайно принял мой ответ. Теперь он не принят, и я приму лучший ответ по состоянию на 1 июля.
Грифон - Восстановить Монику

3

гримаса

def grimacefunc(I, Do, Not, Care, enlist):
    if round < 123: return "d" if "d" in enlist else "c"
    return "d"

Похоже, что «оптимальное» решение для этого холма состоит в том, чтобы сделать что-то вроде этого (T4nT с n> 5 в основном так), и просто оптимизировать раунд, когда он выдает. Все более творческое будет уничтожено.
Роберт Фрейзер

3

Каждый другой D

def everyotherdfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter % 2 == 0:
        return "d"
    else:
        return "c"

Каждый другой

def everyotherdfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter % 2 == 0:
        return "c"
    else:
        return "d"

Может быть, вы должны подать еще одну запись, начиная с сотрудничать.
Грифон - Восстановить Монику

Просто подумал, что это может быть интересно.
Грифон - Восстановить Монику

3

Предсказуемые математики:

Молодой математик

Новое в суровости мира

import math
def ymathfunc(num, mpoints, enpoints, mlist, enlist):
  if(math.sin(num) + 0.8 > 0):
    return 'c'
  else:
    return 'd'

Старый математик

Более опытный в этих вопросах

import math
def omathfunc(num, mpoints, enpoints, mlist, enlist):
  if(math.cos(num) + 0.8 > 0):
    return 'd'
  else:
    return 'c'

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


Ничего из этого не получится, хе. Все, что они делают, по большей части кормят перебежчиков.
Draco18s больше не доверяет SE

2

Рандомизированная синица для тата

import os
def randomtitfortatfunc(forgot, ten, var, iables, enlist):
    luck = enlist.count("d") + 1
    choice = ord(os.urandom(1))
    choice = int(round(luck * float(choice - 0) / 255.0))
    if choice == 0:
        return "c"
    return "d"

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


2

Эксплуатирующий Тат

Экспериментальный Тат пытается играть в следующие стратегии:

  • Дефект, когда позади. Это единственный способ наверстать упущенное.

  • Сотрудничайте против сиськастых и подобных стратегий. Это единственный способ получить хороший долгосрочный счет.

  • Дефект против постоянных сотрудников и других болванов.

  • Дефект 5 раундов рано.

Вот код:

def exploitativetatfunc(num, mypoints, enpoints, mylist, enlist):
    if mypoints < enpoints:
        return "d"
    if num >= 195:
        return "d"
    if num == 0:
        return "c"
    # Test defect, and keep defecting as long as they'll allow
    if (num == 5 or num >= 8) and all(choice == "c" for choice in enlist):
        return "d"
    # Recover if that goes wrong, and they were nice.
    if (num == 6 or num == 7) and all(choice == "c" for choice in enlist[:4]):
        return "c"
    # Otherwise, tit for tat.
    return enlist[-1]

Я удивлен, что это не сработало лучше, чем ничья на восьмом, но я думаю, что это было как раз неподходящее время для этого, и, к сожалению, он был введен одновременно с Two Tits for Tat.
Грифон - Восстановить Монику

2

30 сисек для тата

def тридцатьtitsfortatfunc (ну, больше, веселье, я, en):
    сиськи = 30
    если "d" в en [-tits:] или num> = (200-tits):
        возврат "д"
    возврат "с"

2

но что, если ... следующий ответ не был мрачным спусковым крючком или что-то для тат

Я представляю

Анты

def antyfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter > 150: return "d"
    if not "c" in enlist[-2:]:
        return "d"
    if enpoints >= mypoints:
        return "d"
    else:
        return "c"

Интересно, буду проверять, когда вернусь домой.
Грифон - Восстановить Монику

2

Лиса

def foxfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter > enpoints:
        return "d"
    return "c"

Дефекты, если число раундов больше очков противника, взаимодействует иначе.

Парень

def boyfunc(counter, mypoints, enpoints, mylist, enlist):
    if counter!=0 and enlist[-1]=="c" and counter <= 194 or enpoints+10<mypoints:
        return "c"
    return "d"

Сотрудничает в первом раунде, затем выступает за титул, но наносит удар в спину в последних пяти раундах и делает дефекты, если не впереди на десять очков.

53 сиськи за тату

def fiftythreetitsfortatfunc(num, more, fun, me, en):
    tits = 53
    if "d" in en[-tits:] or num >= (200-tits):
        return "d"
    return "c"

Вы все знаете, что это такое :)


2

Twentyfivetitsforatat

def twentyfivetitsfortatfunc(num, more, fun, me, en):
    tits = 25
    if "d" in en[-tits:] or num >= (200-tits):
        return "d"
    return "c"

Своего рода тицфоратат

def kindatitsfortatfunc(num, more, fun, me, en):
    tits = 54  
    if "c" in en[-tits:] or num >= (200-tits):
        return "c"
    return "d"

В следующий раз, когда вы будете редактировать, чтобы добавить программу, пожалуйста, добавьте комментарий, чтобы я был предупрежден. Благодарность!
Грифон - Восстановить Монику

@ Грифон ой извините
Кристофер

2

Благоразумный Предатель

def PrudentBetrayer(counter, mypoints, enpoints, mylist, enlist):
    # Am I ahead, even if he betrays first?
    if mypoints > enpoints + 5:
        if counter == 0:
            return "c"
        else:
            return enlist[-1]
    # Can I catch up if I betray first?
    elif mypoints + 5 > enpoints:
        if counter == 0:
            return "c"
        elif counter > 130:
            return "d"
        else:
            return "d" if "d" in enlist else "c"
    # can't win -> kill his score
    else:
        return "d"

Предполагается, что он борется с n-tits-for-a-tat ботом. Если у него есть счет, который будет предан и все еще выигран, он позволит другому боту ударить его первым (играя за титул.) Если он может выиграть только тогда, когда он предаст первый, он предаст в 130 раунде задолго до любого текущего бот. Если он на много очков отстает от своего противника, он просто сыграет перебежчика, пытаясь снизить количество ничего не подозревающих ботов.


Рукопожатие

import random
def handshakefunc(num, me, him, m, en):
    handshake = "cdccd"
    # For the first few rounds, give the handshake.
    if num < len(handshake):
        if m == en:
            return handshake[num]
        return "d"
    if en[:len(handshake)] == handshake:
        if me > him:
            return "d"
        if me == him:
            return "ccd"[random.randint(0,2)]
        return "c"
    return "d"

Использует шаблон cdccd на первых пяти раундах, чтобы выяснить, если это с собой. Если это так, он будет пытаться максимизировать свои очки, имея бота с большим количеством очков всегда в дефекте, в то время как другой всегда сотрудничает. Если он обнаружит, что сражается с врагом, он сыграет перебежчика.

В моих тестах я нахожу дозу хорошей, если она составляет значительную часть населения. Когда у него не будет возможности бороться с самим собой, оно будет в основном превращено в перебежчика.

РЕДАКТИРОВАТЬ: ясно из оценки, их много ботов, чтобы это работало хорошо. Он все равно победит, если сразится только с несколькими лучшими ...


Биззаро Триггер

def bizzaroTriggerfunc(round,ms,ts,mm,tm):
  if round==1:return 'c'
  if 'c' in tm:return'd'
  return 'c'

Всегда сотрудничайте, если только ваш оппонент не сотрудничает с вами, и в этом случае вы совершаете ошибку. Всегда.


@Gryphon больной неудачник был удален, и добавлен новый бот!
MegaTom

В тесте, который я сейчас запускаю на боте, которого я еще не опубликовал, Handshake находится на 2-м месте после 390 игр (5338 выживших ботов), превосходя 54-T4T примерно на 1200. Мой новый бот намного сильнее, чем этот. , Первоначальные тесты показали, что он набрал 196 баллов из 196, хотя в долгосрочной перспективе он набрал в среднем ~ 124 за игру. Интересно, что основой для Рукопожатия было то, что я собирался попробовать дальше, оказалось, что вы меня опередили, даже не осознавая этого.
Draco18s больше не доверяет SE

0

FakeShake

использует в своих интересах рукопожатие - делает рукопожатие тогда только дефекты, в то время как рукопожатие доверяет ему. Однако, когда он встречает себя, он делает «настоящее» рукопожатие. Если он встречает другого бота, он играет в оцепенение, с предательством в конце. Это кажется своего рода подлым ...

import random
def fakeshakefunc(num, i, d, m, enlist):
      secret_handshake="cdccdd"
      handshake= "cdccd"
      #checks if it is meeting itself
      if enlist[:len(secret_handshake)] == secret_handshake:
          if me > him:
            return "d"
          if me == him:
             return "ccd"[random.randint(0,2)]
          return "c"
      #does handshake's handshake,if the bot is not handshake or fakeshake it plays T4T
      if num < len(handshake):
            if m == enlist:
                return handshake[num]
            if i < d or num>= 198:
                return "d";
            if num == 0 or enlist[-1] == "c":
                return "c"
            else:
                return "d"
            if enlist[:len(handshake)] == handshake:
                return "d"
            if i < d or num>= 198:
                return "d";
            if num == 0 or enlist[-1] == "c":
                return "c"
            else:
                return "d"

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


Добро пожаловать в PPCG!
Лайкони

@Laikoni Спасибо!
аркин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.