囚人のジレンマv.3-ペトリジレンマ


17

気違いの科学者がバクテリアの新種を作成しました!彼はそれをNoblus Gentlemanus名付けることにしました、その挙動を観察した後。しかし、彼のバクテリアは食料を使い果たし、戦争を宣言しました。彼らは他のバクテリアの死体を収穫して、自分のコピーを作成するのに十分な食料を得ることができるからです。この細菌には、お気に入りのゲームであるPrisoner's Dilemmaをプレイする上で異なる戦略を持っている多くの異なる亜種があります。それぞれ異なる亜種から5つの細菌があります。Prisoner's Dilemmaでは、2人のプレイヤーのそれぞれが同時に欠陥または協力を選択します。1人のプレイヤーが協力を選択し、もう1人がデフォルトを選択した場合、デフォルト者は2ポイントを獲得し、協力者は3ポイントを失います。両方のプレイヤーが協力することを選択した場合、両方のプレイヤーが1ポイントを獲得します。両方のプレイヤーがデフォルトを選択した場合、両方のプレイヤーが1ポイントを失います。

貴族の紳士であるバクテリアは、反復囚人のジレンマの200ラウンドの長いゲームをプレイすることにより、この戦争と戦うことに決めました。各決闘の敗者は自殺し、勝者は自分自身をクローンできます。同点の場合、両方の細菌は生きたままですが、どちらも自身をクローン化することはできません。さらに、試合のすべてのバクテリアは、ポイントの10%以上を次の試合に持ち込みます。クローンは、クローンされた細菌のポイントを引き継ぎます。また、毎ターン10分の1の確率で、1つのバクテリアが別の亜種に変異し、ボーナスポイントが0になります(このランダム性に関する苦情があれば、削除できます)。細菌が細菌の亜種の数に10を掛けた数に等しい数のこれらの決闘を行った後、気違いの科学者は細菌が存在するペトリ皿を誤って落とし、そしてすべてのバクテリアは新しい食物源を獲得し、決闘を終えます。これは通常の反復囚人のジレンマコンテストとは異なります。これは、全体で最も多くのポイントを獲得しようとするのではなく、キャリーオーバーポイントとの1対1の決闘を伴うためです。これにより、特定の戦略の効果が大きく変わります。

各バクテリアは、ターンの開始時に次の形式で入力を受け取ります:(ターン番号、現在のポイント、敵ポイント、あなたの以前の動き]、敵の前の動き[同じ形式で])。

入力する4つのサンプル戦略を以下に示します。実際、Defectorは非常に単純ですが、勝つ可能性があると思います。

Tatのシジュウカラ

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

ランダムピック

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"

Defector

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

すべての提出は、Python 2.7関数の形式である必要があります。名前はfunc、末尾にスペースを含まない提出の名前です。誰かが別の言語で回答を送信したい場合は、擬似コードで入力してください。時間があれば、回答の編集でPythonに変換するか、言語をコントローラーとインターフェースする手順を教えてください6月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]

いくつかの値は、テストされた代替案で任意に選択されたものであり、ここでの値はこの時点で最適に近いものです。対立する派factの現在の広がりに対して、パーフェクトジェントルマンは、時間の約90%(プラスまたはマイナス3パーセントポイント)の完全な支配(バクテリア人口の100%)を達成します。

私はまだ数学者をテストに追加していませんが、これら2つは既存の戦略を養うためだけに役立ち、結果を大きく変えることはありません。

Defectorをサポートすることでコントロールのかなりの部分を管理しますが、ルールごとに許可されていました(戦略の例はターゲティングに公平なゲームでした)。Game of Thronesをサポートするという副作用もありますが、2つは私が選択した基準に基づいて区別できないため、意図的ではありませんでした。これらの「ディフェンダータイプ」はラウンド2でポイントアドバンテージを持ち、結果としていくつかの厄介な隣人(N-T4Tタイプ)を取り除きます。

約5%の確率で、すべてのPerfect Gentlemenが最初のラウンドでDefectorタイプとペアになり、最終的に大量自殺を犯します。その場合、n-T4tタイプの1つが完全な支配を達成します(196の196​​セル)。他のタイプ(Game of Thrones、Boy、Grimace、Sore Loser ...)の1つが完全に絶滅せずに1〜2ポイントを獲得することはほとんどありません。

現在のシミュレーション(合計200ゲームに向けて進行中)。スコア0のすべてのエントリが削除されました。PGが除去された後、ゲームオブスローンズと54-T4Tがラウンド(195ポイント)を分割したように見えます。

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

Tat(許しがある)のためのシジュウカラ

これは基本的に、TatのLucky Tit(「赦しのあるTatのTit」とも呼ばれます)です。ゲームが何ラウンド続くかを正確知っているので、このバクテリアは最終ラウンドでバックスタブするため、TatおよびCooperatorバクテリアの他のTitに対してネット有益な結果を保証します(それ自体に対して、ネットゼロで終了します。協力)。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"

ビタータット

ビター・タットは、敵がポイントで進んでいるときに敵から与えられた協力の試みを利用します。ほとんどのバクテリアは200ラウンドの間に少なくとも1回オリーブの枝を提供し、ビター・タットが全体的に遅れているため、回復のための必死の入札でこれらの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は、Tat 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 Whoops、申し訳ありませんが、私はそれをやったことに気づきませんでした。私は実際にPythonでコーディングするのではなく、2ビットのコードを一緒に壊しました。
Draco18sは、

1
I suspect it will outperform NeoAnticapitalist by a small margin。30,000ポイント以上のようです。
グリフォン-モニカの復活


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は新しいボットを追加しました(そして、他の2つのボットをマージしました)
Masclins

@Gryphonは両方のエディションに感謝します
-Masclins

問題ありません、@ AlbertMasclans
グリフォン-モニカの復活

私が実行しているシミュレーションから、NeoAnticapitalistはTatのBackstabbing Titをリードしていたようです。
グリフォン-モニカの復活

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"

これは、Defectorに「追いつく」ように設計されており、Defectorに対抗するたびに反撃し、Tat-for-Tatベースの戦略に勝ちます。

基本的な考え方は、離反から始めることですが、相手がターン1に協力した場合、2回協力して相互の差別サイクルを回避し、ポイントペナルティが大きくなりすぎないようにします。(ただし、対戦相手が後で欠陥を起こした場合、私たちは自分でサイクルを壊すことはありません。彼らにそれをさせ、結果としてゲームを失う可能性があります。)その後、ゲームの終わりに、ランダムな時間を選びます最後の5ターン以内に敵をバックスタブし、彼らよりも1つ多くの離反を与えます。したがって、キャリーオーバーポイントに遅れがなければ、その過程でキャリーオーバーをあまり犠牲にすることなく勝ちます。 。(期間をランダム化するということは、バックスタブを最初に取得する可能性が非常に高いことを意味します。また、この戦略は、1ターン前にバックスタブを目指しても「調整」できません。)


おめでとうございます!+1
グリフォン-モニカの復活

6

グリムトリガー

単純なボット、競争を埋める

敵が欠陥しない限り協力します。その場合、それは容赦なく欠陥します

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

まあ、これは初期の欠陥のntitsfortatメタのために機能しないようです


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が遅れているかによって完全に異なります、その場合、初期の裏切り者が勝ちます。


3位入賞おめでとうございます!+1
グリフォン-モニカの復活

そして今、秒まで!
グリフォン-モニカの復活

Game of Thronesは、私が現在テストしているボットとかなり戦います。単純な戦略はそれでうまく機能しています。
Draco18sは、

4

ラッキーティットフォータット

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"

私はどこかでtatのシジュウカラが最高の戦略だったことを読んだと確信しています。私は、他のプログラムがさまざまな種類を追加するために自分自身を引き換えることを可能にすることにしました。これで、適切な乱数ジェネレーターを使用できます(利点はありますか?)。


基本的に、これは勝利戦略であり、常に言及されているように、 ウィキペディアに勝ち残るです。唯一の違いは、tat-for-tat欠陥サイクル(他のすべてのエントリの一致に依存)から抜け出す可能性にあります。
Draco18sは、

1
@ Draco18sこれは、別のスコアリングシステム、合計ポイントスコアリングシステムの勝利戦略です。基本的な報復は、ラウンドにポイントを持ち込まない場合、ラウンドに勝てないため、うまくいかないでしょう。
isaacg

@isaacgは、(。18日のプログラムは鉱山の一つであるように私はこのためにAH Lを非難する権利はありませんが)、この戦略は、18のうち、14日に今ある理由である、権利である
グリフォン-復活モニカ

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ポイント未満または正確に6ポイントしかリードしていない場合、彼は敗北し、足場を獲得します。

そして最後に、相手が協力すると考え、彼が強いリードを持っている場合、彼は協力します。


私はこのようなナイスガイよりもうまくいくものを待っていました。ただし、8時間ほどテストすることはできないので、12〜13に更新できるはずです。
グリフォン-モニカの復活

4

54おっぱいのためのおっぱい

def fiftyfourtitsfortatfunc(num、more、fun、me、en):
    おっぱい= 54
    en [-tits:]の「d」またはnum> =(200-tits)の場合:
        「d」を返す
    「c」を返す

これでまだ勝てるのかな?
グリフォン-モニカの復活

これは今勝っているようです!
グリフォン-モニカの復活

おめでとうございます、あなたは私のトップボットの両方にわずかに勝ちました!
グリフォン-モニカの復活

@Gryphon私が他のボットにそれほど愛着していなかった場合、私はtatのために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

ハックマン [予想通り失格]

OK、これはおそらくコンテストから除外されますが、私はそれを試してみたい気がします。

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人のハックマンが協力するようにします。

2番目:別のボットに対して負けた場合、少なくとも彼にできるだけ多くのポイントを失わせるので、その後は大きな敵にはなりません。

3番目:1ターン前に裏切るので、勝利対バックスタビング

「d」の代わりに「#」を使用すると、-1ではなく0ポイントが取得され、ポイントの少ない他のハックマンとも通信するため、彼はディフェンスを停止します。


2
申し訳ありませんが、失格となりました。これは、審査のプロセスをいじることとしてカウントされます。毎ターン「c」または「d」を返さなければなりません。
グリフォン-モニカの復活

2
しかし、これは非常に独創的ですので、失格になったのは残念です。
グリフォン-モニカの復活

3

ビザロ

tatのtitとは正反対です。誰かが彼に親切なとき、彼は悪であることによって彼の愛を示し、誰かが意地悪であるとき、彼は良いことによって復byを示します。tatのtitに大きく基づいています。

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

面白い。しかし、これはDefectorによって殺されるでしょう。
グリフォン-モニカの復活

@Gryphon Lmao、実際にはそれを理解していませんでした。しかし、ちょっと、ビザロは善と悪の違いを知らない、勝ち負け。
タイタスルクレティウス

ええ、これは協力者への脱北者であり、脱北者への協力者であり、いくつかの興味深い可能性をもたらします。それ自体を含む他のものと共存することはできません。
グリフォン-モニカの復活

@Gryphon、うん、それは自分自身を再生するときに0を取得するはずです。Gentle Defectorで何が起こるか疑問に思います。
タイタスルクレティウス

tatの強烈なシジュウカラに直面したときに何が起こるか、これはこの提出前に勝っていたものです。
グリフォン-モニカの復活

3

6ティットフォーアタット

def sixtitsforatatfunc(num、more、fun、me、en):
    en [-6:]またはnum> = 194の「d」の場合:
        「d」を返す
    「c」を返す

Tat軍拡競争のTitが起こっています:)


私たちは船外に出ようとしていると感じ、Defectorはトップの座を奪います。
グリフォン-復活モニカ

3

十代のおっぱい

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

先に欠陥があり、また相手が最後の10ターンに欠陥を持っている場合も欠陥があります。

CopyFirst

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

これは最初のラウンドに欠陥があり、その後、相手が最初のラウンドを実行した後、197ラウンド目までバックスタブします。

40ティッツフォーアタット

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

相手が最後の40ターンで敗北した場合、敗北するか、協力します。過去50ターンのバックスタブ。

Tatの3つのおっぱい

相手が最後の3ターンで敗北した場合、敗北するか、そうでなければ協力します。最後の5ターンのバックスタブ。このプログラムは、Tut for Two Tatsからわずかな差でリードを奪いました。

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"

これが何をするのか理解できないなら、あなたはバカです。また、1ラウンド前にバックスタブします。


IMO、あなた自身のエントリを提出してください。
Draco18sは、

それが一般的に公正と見なされるかどうかだけではわかりませんでした。
グリフォン-モニカの復活

ただし、通常よくあることは、ベストアンサーが勝利したボットであることです。
マスクリン

それは、自分の答えを選ぶだけではありません。それは間違いなく公平ではないでしょう。
グリフォン-復活モニカ

申し訳ありませんが、自分の答えを誤って受け入れたことに気付いていませんでした。現在は受け入れられていませんが、7月1日の時点でベストアンサーを受け入れます。
グリフォン-復活モニカ

3

しかめっ面

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

この丘の「最適な」解決策は、このようなこと(n> 5のT4nTは基本的にこれです)を行い、裏切り時にラウンドを最適化することです。それ以上のクリエイティブは破壊されます。
ロバートフレイザー

3

他のすべてのD

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

他のすべての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

Tatのランダム化されたシジュウカラ

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"

Tat For Tat、ただしランダム化。これは賞品を獲得するものではありません(私が本当に幸運でない限り)。これで、適切なソースから乱数が生成されました。


2

搾取的なデータ

Exploitative Tatは、次の戦略を試みます。

  • 背後にあるときの欠陥。それが追いつくための唯一の方法です。

  • tit-for-tatおよび同様の戦略に協力する。良い長期スコアを取得する唯一の方法です。

  • 常時協力者やその他の障害に対する欠陥。

  • 欠陥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]

私はこれが8位のタイよりも良くなかったことに驚いていますが、それはちょうどそれが間違った時期だったと思います、そしてそれは残念ながらTatのTwo Titsと同時に入力されました。
グリフォン-モニカの復活

2

30爆乳

def thirtytitsfortatfunc(num、more、fun、me、en):
    おっぱい= 30
    en [-tits:]の「d」またはnum> =(200-tits)の場合:
        「d」を返す
    「c」を返す

2

しかし、もし...次の答えが厳しいトリガーでもなければ、tatでもないものだったら

プレゼントする

アンティ

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"

最初のラウンドに協力し、最後の5ラウンドでtatのためにtitの代わりに行動しますが、10ポイント先でない場合はバックスタブします。

53おっぱい

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

あなたはすべてこれが何であるか知っています:)


2

二十五歩

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ボットと戦っていると仮定します。裏切られてまだ勝つスコアがある場合、他のボットに最初にヒットさせます(tatのtitとしてプレイします)。ボット。対戦相手の背後に多くのポイントがある場合、疑いを持たないボットのスコアを下げようとして脱走者を演じるだけです。


ハンドシェーク

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最初の5ラウンドをそれ自体と一致するかどうかを確認します。もしそうなら、それは、より多くのポイントを持つボットに常に欠陥を持たせることによってそのポイントを最大化しようとしますが、他方は常に協力します。敵と戦っていると判断した場合、脱走者をプレイします。

私のテストでは、それが人口のかなりの部分を占めている場合、それがうまく投与されることがわかります。それ自体と戦う機会がない場合、基本的には脱北者に還元されます。

編集:明らかにスコアから、彼らはこれがうまく機能するために多くのボットにあります。ほんの数人と戦えば勝ちます...


ビザロトリガー

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

相手があなたと協力しない限り、常に協力してください。常に。


痛い敗者であるグリフォンが削除され、新しいボットが追加されました!
メガトム

まだ投稿していないボットで実行しているテストでは、ハンドシェイクは390ゲーム(5338のボットを生き残っている)が54-T4Tを約1200で凌いで2位になっています。 。最初のテストでは、196のうち196を採点しましたが、長期的には平均で1ゲームあたり124を採点しています。興味深いことに、ハンドシェイクの背後にある基礎は、次に試みることでした。
Draco18sはSEを信頼しなくなりました

0

フェイクシェイク

ハンドシェイクを利用します-ハンドシェイクを行い、ハンドシェイクがそれを信頼している間に欠陥が発生します。ただし、自分自身と出会うと、「実際の」ハンドシェイクを行います。別のボットに出会うと、tatのシジュウカラを演じ、最後に裏切りをします。これはちょっと意地悪だ...

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"

これに関する1つの問題は、ハンドシェイクを満たし、より多くのポイントがある場合、自分自身でプレイしていると考えることです。私はpythonとこのサイトの初心者です(実際、これが私の最初の答えです)。


PPCGへようこそ!
ライコニ

@ライコニありがとう!
アルキン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.