1P5: Tekrarlanan Mahkumun İkilemi


35

Bu görev, Birinci Periyodik Premier Programlama Yapboz Baskısının bir parçasıdır ve yeni bir meydan okuma önerisinin kanıtı olarak tasarlanmıştır .

Görev, yinelenen mahkumun ikilemini diğer katılımcılardan daha iyi oynamak için bir program yazmaktır.

Bak Vinny. Hücre arkadaşını biliyoruz --- adı ne? Evet McWongski, Nippo-İrlanda-Ukraynalı mafyası - bir şeylere kalmış ve ne olduğunu biliyorsunuz.

Burada kibar olmaya çalışıyoruz, Vinnie. Sana bir şans veriyorum.

Bize ne planladığını söylersen, iyi bir iş atama yaptığını görürüz.

Ve eğer yapmazsan ...

Oyunun kuralları

  • Yarışma, aynı anda iki yarışmacının (kendi kendine oynanan oyunlar dahil) tam bir turdan (olası tüm eşleşme) oluşmasından oluşur.
  • Her çift arasında oynanan 100 tur var
  • Her turda, her oyuncudan, diğer oyuncu ile işbirliği yapma veya onlara ihanet etme arasından seçim yapması istenir, bu konudaki diğer oyuncuların niyetlerini bilmeden, ancak bu rakibe karşı oynanan önceki turların sonuçlarının bir hatırası ile.
  • Kombine seçim bazında her tur için puan verilir. Her iki oyuncu da işbirliği yaparsa her ikisi de 2 puan alır. Karşılıklı ihanet, her birine 1 puan kazandırır. Karışık durumda, ihanet eden oyuncuya 4 puan verilir ve işbirlikçi 1 ile cezalandırılır.
  • "Resmi" bir maç yayınlanacak en geç 10 gün içerisinde yayınlanacak ve tüm başvuruları ile birlikte çalışmaya başladım ve "kabul edilen" birinciyi seçmek için kullanılacağım. Bir Mac OS 10.5 kutum var, bu yüzden POSIX çözümleri işe yaramalı, ama işe yaramayan linuxism var. Aynı şekilde, win32 API için desteğim yok. Bir şeyler kurmak için temel bir çaba göstermeye istekliyim, ancak bir sınır var. Sistemimin sınırları hiçbir şekilde kabul edilebilir cevapların sınırlarını, sadece “resmi” eşleşmeye dahil edilecekleri temsil etmiyor.

Programcı arayüzü

  • Girişler, komut satırından çalıştırılabilen programlar biçiminde olmalıdır; Karar, programın standart çıktıdaki (tek!) çıktısını almalıdır. Bu rakiple önceki turların geçmişi, bir komut satırı argümanı olarak sunulacak.
  • Çıktı ya "c" ( istiridye için ) ya da "t" ( hepsini anlatmak için ).
  • Tarihçe, önceki turları temsil eden tek bir karakter dizisidir ve en son tur dizgede en erken gelir. Karakterler
    • "K" ( karşılıklı işbirliği anlamına gelen inancı sürdürdüğü için )
    • "R" ( fare b @ st @ rd için beni sattı! )
    • "S" ( enayi için! İhanetten faydalandığın anlamına gelir)
    • "E" ( herkes için karşılıklı ihanette bir numarayı arıyor )

Dirsek

Dört oyuncu yazar tarafından sağlanacaktır

  • Angel - her zaman işbirliği yapar
  • Şeytan - her zaman konuşur
  • TitForTat - İlk rauntta işbirliği yapar, sonra son rauntta olduğu gibi yapar
  • Rastgele - 50/50

Çalıştırmak için tüm girişleri ekleyeceğim.

Toplam puan, tüm rakiplere karşı toplam puan olacaktır (yalnızca bir kez kendi kendine oynama ve ortalama puanı kullanma dahil).

Katılımcılar

(2 Mayıs 2011, 07:00 itibariyle geçerli)

Gizli El Sıkışma | Anti-T42T Füze | Güvensizlik (değişken) | Anti-El Sıkışma | Küçük Lisper | Yakınsama | Köpekbalığı | Probabimatik | Pavlov - Win Stay, Geçiş Anahtarı | Hırsızlar Arasında Onur | Yardım Vampir | Druid | Küçük Schemer | Bygones | İki Tat Baştankara | Simpleton |

Golcü

#! /usr/bin/python
#
# Iterated prisoner's dilemma King of Hill Script Argument is a
# directory. We find all the executables therein, and run all possible
# binary combinations (including self-plays (which only count once!)).
#
# Author: dmckee (https://codegolf.stackexchange.com/users/78/dmckee)
#
import subprocess 
import os
import sys
import random
import py_compile

###
# config
PYTHON_PATH = '/usr/bin/python' #path to python executable

RESULTS = {"cc":(2,"K"), "ct":(-1,"R"), "tc":(4,"S"), "tt":(1,"E")}

def runOne(p,h):
    """Run process p with history h and return the standard output"""
    #print "Run '"+p+"' with history '"+h+"'."
    process = subprocess.Popen(p+" "+h,stdout=subprocess.PIPE,shell=True)
    return process.communicate()[0]

def scoreRound(r1,r2):
    return RESULTS.get(r1[0]+r2[0],0)

def runRound(p1,p2,h1,h2):
    """Run both processes, and score the results"""
    r1 = runOne(p1,h1)
    r2 = runOne(p2,h2)
    (s1, L1), (s2, L2) = scoreRound(r1,r2), scoreRound(r2,r1) 
    return (s1, L1+h1),  (s2, L2+h2)

def runGame(rounds,p1,p2):
    sa, sd = 0, 0
    ha, hd = '', ''
    for a in range(0,rounds):
        (na, ha), (nd, hd) = runRound(p1,p2,ha,hd)
        sa += na
        sd += nd
    return sa, sd


def processPlayers(players):
    for i,p in enumerate(players):
        base,ext = os.path.splitext(p)
        if ext == '.py':
            py_compile.compile(p)
            players[i] = '%s %sc' %( PYTHON_PATH, p)
    return players

print "Finding warriors in " + sys.argv[1]
players=[sys.argv[1]+exe for exe in os.listdir(sys.argv[1]) if os.access(sys.argv[1]+exe,os.X_OK)]
players=processPlayers(players)
num_iters = 1
if len(sys.argv) == 3:
    num_iters = int(sys.argv[2])
print "Running %s tournament iterations" % (num_iters)
total_scores={}
for p in players:
    total_scores[p] = 0
for i in range(1,num_iters+1):
    print "Tournament %s" % (i)
    scores={}
    for p in players:
        scores[p] = 0
    for i1 in range(0,len(players)):
        p1=players[i1];
        for i2 in range(i1,len(players)):
            p2=players[i2];
#        rounds = random.randint(50,200)
            rounds = 100
            #print "Running %s against %s (%s rounds)." %(p1,p2,rounds)
            s1,s2 = runGame(rounds,p1,p2)
            #print (s1, s2)
            if (p1 == p2):
                scores[p1] += (s1 + s2)/2
            else:
                scores[p1] += s1
                scores[p2] += s2

    players_sorted = sorted(scores,key=scores.get)
    for p in players_sorted:
        print (p, scores[p])
    winner = max(scores, key=scores.get)
    print "\tWinner is %s" %(winner)
    total_scores[p] += 1
print '-'*10
print "Final Results:"
players_sorted = sorted(total_scores,key=total_scores.get)
for p in players_sorted:
    print (p, total_scores[p])
winner = max(total_scores, key=total_scores.get)
print "Final Winner is " + winner
  • Korkunç pitonumla ilgili şikayetler açıktır, çünkü bunun birden fazla yoldan berbat olduğundan eminim.
  • Hata düzeltmeleri hoş geldiniz

Golcü Değişimi:

  • Sıralanan oyuncuları ve puanları yazdırın ve kazanan ilan edin (4/29, Casey)
  • İsteğe bağlı olarak çoklu turnuvalar ./score warriors/ num_tournaments)yürütün ( ) default = 1, python kaynaklarını algıla ve derle (4/29, Casey)
  • İkinci oyuncunun yanlış bir tarihçeden geçtiği aptalca hatayı düzelt. (4/30, dmckee; teşekkürler Josh)

İlk savaşçılar

Örnek olarak ve sonuçların doğrulanabilmesi için

melek

#include <stdio.h>
int main(int argc, char**argv){
  printf("c\n");
  return 0;
}

veya

#!/bin/sh
echo c

veya

#!/usr/bin/python
print 'c'

şeytan

#include <stdio.h>
int main(int argc, char**argv){
  printf("t\n");
  return 0;
}

rasgele

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char**argv){
  srandom(time(0)+getpid());
  printf("%c\n",(random()%2)?'c':'t');
  return 0;
}

Golcü, savaşçıyı bir saniyede birçok kez tekrar başlatabilir; bu nedenle, PRNG'yi tohumlamak için zaman kullanılıyorsa, sonuçların rasgele olmasını sağlamak için ciddi bir çaba sarf edilmesi gerekmektedir.

TitForTat

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char**argv){
  char c='c';
  if (argv[1] && (
          (argv[1][0] == 'R') || (argv[1][0] == 'E')
          ) ) c='t';
  printf("%c\n",c);
  return 0;
}

İlk olarak tarihle ilgili bir şey yapan var.

Golcüyü sadece verilen savaşçıların veriminde kullanmak

Finding warriors in warriors/
Running warriors/angel against warriors/angel.
Running warriors/angel against warriors/devil.
Running warriors/angel against warriors/random.
Running warriors/angel against warriors/titfortat.
Running warriors/devil against warriors/devil.
Running warriors/devil against warriors/random.
Running warriors/devil against warriors/titfortat.
Running warriors/random against warriors/random.
Running warriors/random against warriors/titfortat.
Running warriors/titfortat against warriors/titfortat.
('warriors/angel', 365)
('warriors/devil', 832)
('warriors/random', 612)
('warriors/titfortat', 652)

O şeytan, o bir zanaat biri ve görünüşe göre en iyi adamlar geldi.

Sonuçlar

"resmi" koşunun

('angel', 2068)
('helpvamp', 2295)
('pavlov', 2542)
('random', 2544)
('littleschemer', 2954)
('devil', 3356)
('simpleton', 3468)
('secrethandshake', 3488)
('antit42t', 3557)
('softmajo', 3747)
('titfor2tats', 3756)
('convergence', 3772)
('probabimatic', 3774)
('mistrust', 3788)
('hyperrationalwasp', 3828)
('bygones', 3831)
('honoramongthieves', 3851)
('titfortat', 3881)
('druid', 3921)
('littlelisper', 3984)
('shark', 4021)
('randomSucker', 4156)
('gradual', 4167)
        Winner is ./gradual

2
Hücre arkadaşım Nippo-İrlanda-Ukrayna ise, neden adı Hiberno-Çin-Rus görünüyor?
Peter Taylor

2
@Peter: LOL. Doğrusu? Peki, (1) soy kütleleri açık değil, ama muhtemelen İskoçluğumdan dolayı benim iyiliğimle geliyorum ; (2) "Nippo" yazdıktan sonra, arkadaşlarımın isimlerini, yükselen güneşin diyarından almayı denedim ve taranma yöntemlerini beğenmedim, bu yüzden devam ettim ve seslendiren bir Çin soyadı kullandım. Bunun yerine iyi ve (3) Beni lastik ütülerle dövdüklerinde sırayla farkı bilmem. Bu şartlar altında muhtemel görünüyor.
dmckee

1
@Josh: misiniz basit değiştirmek olmak return (s1, L1+h1), (s2, L2+h1)için return (s1, L1+h1), (s2, L2+h2)[Not L2+h2yerine L2+h1sonunda]? // Cut-n-paste hatası veya eşit derecede aptalca bir şey. Sheesh!
dmckee

2
Test senaryosunda biraz zaman geçirdim ve burada bir güncelleme duyurmaktan memnuniyet duyuyorum . Bu güncelleme, test betiğine, kullanıcının bu botu elle çalıştırmasını, sınırlı alanlarla turnuvaları ve bazı diğer harika şeyleri çalıştırmasını sağlayan basit bir kabuk ekler. Önerilerinizi yapmaktan çekinmeyin! Ah. Ve bot-vs-bot fikri için @josh borcum var. Gerçekten de "antrenör" senaryosunun meraklısı bir uygulaması.
arrdem

2
İlginç: 23 yarışması vardı, bu yüzden her biri 22 tur oynadı. Eğer herkes "Melek" oynasaydı, her skor 4400 olurdu, ama en iyi 4167 skoru bile eşleşmedi. Keşke mükemmel bir dünyada
yaşayabilseydik

Yanıtlar:


11

kademeli

Bu strateji Beaufils, Delahaye ve Mathieu tarafından hazırlanan bir makaleye dayanmaktadır . Benim C gerçekten en iyisi değil, bu yüzden herhangi biri kodu geliştirmek / hızlandırmak için herhangi bir önerisi varsa, bana bildirin!

[Düzenleme] Unutulmaya değer, Kademeli'nin Tat for Tit'i geride bırakan bir strateji olarak tasarlandığı. Benzer bir özelliğe sahip olup, savunucu bir rakibe karşı işbirliği yapma ve misilleme yapma konusunda isteklidir. Sadece oynanan son turun hafızasına sahip olan Tat for Tit'in aksine Gradual, etkileşimin tamamını hatırlayacak ve rakibin şimdiye kadar kaç kez attığını saptayacaktır. Yine de, daha sonra karşılıklı işbirliği sunacak.

Her zaman olduğu gibi, stratejinin performansı biraz diğer stratejilerin sıralanmasına bağlıdır. Ayrıca orjinal kağıt bazı detaylarda net değildi.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[]) {
    if(argc == 1){
        printf("c\n");
        return 0;
    }

    size_t l = strlen(argv[1]);
    int i;
    size_t currentSequence = 0;
    size_t totalDefects = 0;
    size_t lastDefects = 0;

    for(i = l-1; i >= 0; i--){
        if(argv[1][i] == 'E' || argv[1][i] == 'R'){
            totalDefects++;
            currentSequence = 0;
        } else if(argv[1][i] == 'S') {
            currentSequence++;
        }
    }

    if(currentSequence < totalDefects)
        // continue defect sequence
        printf("t\n");
    else if(argv[1][0] == 'S' || argv[1][0] == 'E' ||
            argv[1][1] == 'S' || argv[1][1] == 'E')
        // blind cooperation
        printf("c\n");
    else if(argv[1][0] == 'R')
        // start new defect sequence
        printf("t\n");
    else
        printf("c\n");

    return 0;
}

11

Gizli El Sıkışma

#!/usr/bin/python
import sys
import random

def main():
    if len(sys.argv) == 1:
        hist = ""
    else:
        hist = sys.argv[1]
    if len(hist) <= len(TAG) and hist == TAGMATCH[len(TAG) - len(hist):]:
        print TAG[len(TAG) - len(hist) - 1]
        return
    if hist[-len(TAG):] == TAGMATCH:
        print 'c'
        return
    print "t"

def getTag():
    global TAG
    filename = sys.argv[0]
    filename = filename.replace(".pyc", ".py")
    f = open(filename, 'r')
    code = f.read().split('\n')
    f.close()
    if len(code[1]) == 0 or code[1][0] != '#':
        random.seed()
        newtag = 't' * 10
        cs = 0
        while cs < 3:
            pos = random.randint(0, 8)
            if newtag[pos] == 't':
                newtag = newtag[:pos] + 'c' + newtag[pos+1:]
                cs += 1
        code.insert(1, '#%s' % newtag)
        f = open(filename, 'w')
        f.write('\n'.join(code))
        f.close()
        TAG = newtag
    else:
        TAG = code[1][1:]
    global TAGMATCH
    TAGMATCH = TAG.replace('c', 'K').replace('t', 'E')

if __name__ == "__main__":
    getTag()
    main()

Buradaki strateji, "gizli" bir el sıkışma gerçekleştirmek için ilk 10 turu feda etmektir. Kendime hücum edersem, ilk 10 hamlenin tarihini tanırım ve oyunun geri kalanı için Angel başlığımı giyerim. Hücre arkadaşımın kendim olmadığını farkettiğimde, aşırı kooperatif hücre arkadaşlarından yararlanmak için bir Şeytan'a dönüşüyorum.

İlk 10 raunttan fedakarlık etmemin Şeytan'ın dışına çıkmama izin verip vermeyeceği kuvvetle kaç giriş olduğuna bağlı. Zararı en aza indirmek için, el sıkışmasında sadece 3 kooperatif görünür.

Düzenleme: TAGMATCH şimdi sadece bunlardan birini değiştirmek gibi aptal hataları önlemek için dinamik ve böylece gelecekte TAG dinamik yapabilirim.

Düzenleme 2: Şimdi etiketi ilk çalıştırmada rastgele oluşturur ve bunu belirtilen dosyada sys.argv[0]( .pycyerine koyar, .pyböylece kod bytecode'a değil, dosyaya gider) saklar . Bence bu, bütün örneklerin kimsenin sahip olmadığı tek bilgi, parazitlerden kaçınmak için tek seçenek gibi görünüyor.


Ama doppelganger kendini şeytan yapmayı nasıl biliyor?
arrdem,

1
(Her zaman "Tat için Baştankara" diyerek bir papağan gibi hissediyorum ...) T4T'nin stratejinizi bir eşleşme halinde yeneceğini unutmayın: T4T (daha önce işbirliği yapar) ve Şeytan (daha az Rat sonucu) ve stratejisi. Tabii ki, genel toplam, eşleştirme toplamı değil, sonunda önemli olan şeydir. Dediğiniz gibi, nüfus önemlidir.
Josh Caswell

1
Ah, hayır, Tat için fazladan S al. Güzel. TAGGeri çalındığını bilmiyordum . Ancak, TAGMATCH'KEEEKEEEKE' olmamanız gerekmiyor mu? "".join({('c', 'c'):'K', ('t', 't'): 'E'}[moves] for moves in zip(TAG, TAG))
Josh Caswell

@John İyi nokta - Başlangıçta farklı bir TAG'm vardı ve işbirliğini en aza indirmek için değiştirdiğimde TAGMATCH'i güncellemeyi unuttum. @Arrdem Fikir, eğer kendime karşı oynuyorsam, yapılacak en iyi şey, her ikisinin de puanlarının toplamını en üst düzeye çıkarmak için her zaman işbirliği yapmasıdır.
Aaron Dufour

1
Aww, kahretsin. Şimdi .pykodunuz için tüm dosyaları aramalı ve TAG kodunu çıkarmalıyım. C de bunu yapmayacağım, ama ...
Joey

6

Küçük Lisper

(setf *margin* (/ (+ 40 (random 11)) 100))
(setf *r* 0.0)
(setf *s* 0.0)
(setf *k* 0.0)
(setf *e* 0.0)

;; step 1 - cout up all the games results

(loop for i from 1 to (length(car *args*)) do
    (setf foo (char (car *args*) (1- i)))
    (cond 
        ((equal foo #\R) (setf *r* (1+ *r*)))
        ((equal foo #\S) (setf *s* (1+ *s*)))
        ((equal foo #\K) (setf *k* (1+ *k*)))
        ((equal foo #\E) (setf *e* (1+ *e*)))
    )
)

(setf *sum* (+ *r* *s* *k* *e*))

;; step 2 - rate trustworthiness
(if (> *sum* 0)
    (progn
        (setf *dbag* (/ (+ *r* *e*) *sum*)) ; percentage chance he rats
        (setf *trust* (/ (+ *s* *k*) *sum*)); percentage chance he clams
    )
    (progn
        (setf *dbag* 0) ; percentage chance he rats
        (setf *trust* 0); percentage chance he clams
    )
)



;; step 3 - make a decision (the hard part....)

(write-char
    (cond
        ((> *sum* 3) (cond 
                    ((or (= *dbag* 1) (= *trust* 1)) #\t) ; maximizes both cases
                                                          ; takes advantage of the angel, crockblocks the devil
                    ((> (+ *dbag* *margin*) *trust*) #\t) ; crockblock statistical jerks
                    ((< *dbag* *trust*) #\c)              ; reward the trusting (WARN - BACKSTABBING WOULD IMPROVE SCORE)
                    ((and
                        (= (floor *dbag* *margin*) (floor *trust* *margin*))
                        (not (= 0 *dbag* *trust*)))
                        #\t)                              ; try to backstab a purely random opponent, avoid opening w/ a backstab
                    )
        )
        (t #\c)                                            ; defalt case - altruism
    )
)

Şeytan

Aşağıdakileri göz önünde bulundurun, formatlayın (Player1, Player2)

  • (C, T) - P2 , ihaneti için DÖRT NOKTALARI kazanırken, P1 BİRİ KAYBOLU
  • (T, T) - P2 VE P1 KAZANIMI 1

P2'nin şeytan olduğunu varsayarsak, şeytanın puan kaybedebileceği bir yol yoktur, aslında yapabileceği en kötü şey yalnızca bir puan kazanmaktır. Bu nedenle tamamen rastgele bir rakibe karşı, şeytanın olası en kötü puanı tam olarak (5/2) * n olacaktır; burada n, oynanan "oyun" sayısıdır. Mutlak en kötü durumu, puanının n olacağı kendine karşı ve en iyi olayı ise, 4 * olacak bir meleğe karşıdır.

Assert: optimal_strat = şeytan

bu bir turnuva. Hücre arkadaşımı geri yerleştirmek, işbirliğinden çok daha iyi bir strateji çünkü MY SCORE'a daha fazla yardımcı oluyor (+4). BONUS - çarptı (-1)! Boynumu onun için dışarı çıkarırsam, (+2) ve gevşemeye (-1) katlanırım. Bunun için istatistiksel olarak geri tepme ödüllendirilir.

Ama En Uygun mu?

EVER'in (bu puanlama sistemi altında) işbirliği yapması için hiçbir sebep yoktur.

  • İstemek için yanlış zamanı seçtiyseniz, gevşetin.
  • Eğer sıçan, en azından hiçbir şey kaybetmezsin.
  • Eğer sıçan ve aptal, iyi bir oyun olsaydı 2 kat daha fazla kazanırsın.

KOTH sisteminde geri dönüşlerin maksimize edilmesi şarttır. Mükemmel bir şekilde senkronize edilen ve işbirliği yapan iki botunuz olsa bile, bireysel puanları, sporcu olmaları için sadece 200 puan artacaktır. Öte yandan, bir şeytan ortalama 200 ve maksimum 400 olayla en az 100 puan kazanacak ve rakiplerine her biri 100 puana mal olacak! Bu yüzden, pratik olarak, şeytan gerçekten ortalama bir 300 puan alıyor ve 500'e yükseliyor.

Alt satırda - zaman söyleyecek

Bana göre, şeytanın günü alabilmesi için skorlamanın yeniden değerlendirilmesi gerektiği görülüyor. İşbirliği puanını 3'e çıkarmak, hepsini yapabilir. Bununla birlikte, şeytanları tespit etmek ve pavlov ve spite show gibi tam 400'lerini atmalarını engellemek mümkündür. İkisinin de inançlarını haklı çıkarmak için işbirlikleri için yeterli puan toplayacağını kanıtlayabilir miyim? Hayır. Bunların hepsi son yarışmacı alanına bağlıdır.

GL, HF!

Ve lütfen bu yazıya en kötüsünü yap. Her şey söylenip bittiğinde, kıdemli gazetemi bunun üzerine yazmak istiyorum.

Sürüm geçmişi

  1. Lisper'ın duchebaggery toleransını rastgele değiştiren bir marj değişkeni eklendi.
  2. Kooperatif rakipleriyle sağ ayağa kalkmak için ilk iki raund için istiridye istiridye güncellendi
  3. Standart bir rakip gruba karşı maksimum puanlarını temel alarak rastgele eşik üreteci için en sağlam değerleri bulmak için genetik bir algoritma kullanıldı. Onları içeren güncelleme yayınlandı.

LISPER'ın RESMİ SÜRÜMÜ

LİSANS DEVEL SÜRÜMÜ


Skor, oyunun farklı varyantlarına göre değişir. Ben yaptım işbirliği teşvik artmaktadır oynayabilir ve bunu seçilmiş stratejiler üzerinde etkisi olacağını kabul edersiniz. İyi haber: Eğer kendi kurallarını ayarlamak, skorer kapmak ve onu deneyebilirsiniz. Prensipte bir ödül bile önerebilirsin.
dmckee

fink install clisp :: parmaklara tekrar tekrar dokunarak ::
dmckee

1
@josh - bağlantı için teşekkürler. Bu ikilemde başka wikipedia sayfalarını da okudum, ancak bu bölümü kaçırdım. Az önce fark ettiğim bir kural hatası, dosya sistemini kullanan girişlere karşı kural yok. Bu, el sıkışmasının hatları boyunca çok daha verimli bir işbirliği potansiyeli yaratır.
arrdem

3
There is no reason to EVER (under this scoring system) co-operatesadece yarı doğru. Rakibinizin tarihi hesaba katmadığını biliyorsanız (melek, şeytan, rastgele) o zaman her zaman kusurlu olmalısınız. Rakibiniz geçmişi hesaba katarsa ​​ve senkronize edebilirsiniz, o zaman daha iyisini yapabilirsiniz. Rakibin rasyonel mi yoksa evrimsel mi olduğunu tespit etme etrafında dönen birkaç fikrim var.
Peter Taylor

1
En son sürümle zamanın 3 / 20'sinde sıfıra bölme hataları almıyor musunuz? Her (random 20)5, 2 elde edilmiştir, ya da 8, (/ (+1 rand-num) 10)0.6, 0.3 0.9, ve 0.3 ile dizgisinde 0 olduğu; bu yüzden (floor *dbag* *margin*)ölür.
Josh Caswell

5

Güvensizlik (değişken)

Bu, ilk önce yıllar önce kendi sınavlarımda ortaya çıktı (o zamanlar ben 11. sınıftaydım ve diğer öğrenciler tarafından geliştirilen stratejiler kullanarak tam olarak bu konuda küçük bir tez yaptım). Dizi ile başlar tcc(ve bundan sonra Tat için Tit gibi oynar.

Korkunç kod için özür dilerim; Eğer biri tam olarak golf oynamazken bunu daha da kısaltabilirse minnettar olurum

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
    if (argc == 1)
        printf("t\n");
    else switch (strlen(argv[1])) {
        case 0:
            printf("t\n");
            break;
        case 1:
        case 2:
            printf("c\n");
            break;
        default:
            if (argv[1][0] == 'R' || argv[1][0] == 'E')
                printf("t\n");
            else
                printf("c\n");
            break;
    }

    return 0;
}

1. ve 2. uzunluklarda yinelenen kodlara gerek yoktur case 1: case2: printf(...); break;. Ve gcc string.h, kullanımın açık bir bildirimini istiyor strlen. Her durumda çalışmasını sağladım.
dmckee

Ah, doğru. Boş bir ilk argüman (tarih) ya da sadece hiçbiri olup olmadığına rağmen ilk turun nasıl belirleneceğinden emin değildim.
Joey

Emin değilim. Python ne Popen(p+" "+h,stdout=subprocess.PIPE,shell=True)zaman yaparsa yapsın h = ''. Ben tahmin ediyorum argc=1.
dmckee

1
Bu ilk dizi, tamamen Tat'ın zayıflığı için Tit'i hedef alan iyi bir fikirdir. Üzerinde küçük bir ipucu elde edersiniz, daha sonra ilerlersiniz.
Josh Caswell,

1
@Josh, minik kurşun nerede? T4T'ye karşı bu, SRK ile başlar ve sonra K ile devam eder. Ancak, SR her oyuncu için 3 puan değerindedir.
Peter Taylor

5

Anti-T42T Füze

#!/usr/bin/python

"""
Anti-T42T Missile, by Josh Caswell

That Tit-for-two-tats, what a push-over!
  T42T: ccctcctcc...
AT42TM: cttcttctt...
        KSSRSSRSS...
"""
import sys
try:
    history = sys.argv[1]
except IndexError:
    print 'c'
    sys.exit(0)

if history[:2] == 'SS':
    print 'c'
else:
    print 't'

Temel savaşçı setine karşı makul derecede iyi yapar: Devil tarafından hafifçe dövülen Angel'ı öldürür (ancak puanını düşük tutar), genellikle RAND'ı kolayca yener ve Tat için zar zorlukla yener. Kendisine karşı oynarken kötü yapar.


Bunun çalışmasını sağlayan bir düzenleme yaptım :) Onaylanması gerekiyor.
Casey,

@Casey: Tanrım, bu sorun için coşkumda o kadar aptalca hatalar yapıyorum! Sağol ama neden sh-bang'i ortadan kaldırdın?
Josh Caswell,

Er, bu bir kazaydı. Onu tekrar ekleyeceğim.
Casey,

@Casey: sorun değil. Yaparım. Zaten bir doc string eklemeniz gerekir.
Josh Caswell

4

yakınsama

Başlangıçta güzel, sonra rakibin tarihine bir göz ile rastgele oynuyor.

/* convergence
 *
 * A iterated prisoners dilemma warrior for
 *
 * Strategy is to randomly chose an action based on the opponent's
 * history, weighting recent rounds most heavily. Important fixed
 * point, we should never be the first to betray.
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char**argv){
  srandom(time(0)+getpid()); /* seed the PRNG */
  unsigned long m=(1LL<<31)-1,q,p=m;
  if (argc>1) {
    size_t i,l=strlen(argv[1]);
    for (i=l; --i<l; ){
      switch (argv[1][i]) {
      case 'R':
      case 'E':
    q = 0;
    break;
      case 'K':
      case 'S':
    q = m/3;
    break;
      }
      p/=3;
      p=2*p+q;
    }
  }
  /* printf("Probability of '%s' is %g.\n",argv[1],(double)p/(double)m); */
  printf("%c\n",(random()>p)?'t':'c'); 
  return 0;
}

Tarihin ağırlığını düşürmeye çalıştım, ama doğru şekilde optimize etmedim.


4

Köpekbalığı

#!/usr/bin/env python

"""
Shark, by Josh Caswell

Carpe stultores.
"""

import sys

HUNGER = 12

try:
    history = sys.argv[1]
except IndexError:
    print 'c'
    sys.exit(0)

if history.count('S') > HUNGER:
    print 't'
else:
    print 'c' if history[0] in "SK" else 't'

Baz kadroya karşı oldukça iyi yapar.


... istiridye ele geçirmek?
arrdem

:) Aptalları yakala.
Josh Caswell

Geçerli alanda tutarlı bir 2. sırada yer almak için +1.
arrdem

3

Pavlov - Win Stay, Geçiş Anahtarı

İlk dönüşte o işbirliği ve sonra işbirliği ancak ve ancak iki oyuncunun önceki hamlede aynı seçim için seçti.

#!/usr/bin/python
import sys

if len(sys.argv) == 1:
    print 'c'
else:
    hist = sys.argv[1]
    if hist[0] == 'K' or hist[0] == 'E':
        print 'c'
    else:
        print 't'

Bu kullanılmamalıdır mı hist[0]( hist[-1]her zaman turun ilk hamlesidir)?
Josh Caswell

Vay canına, haklısın. Giriş dizesinin, dizenin sonunda, başında değil en son rauntlara sahip olduğunu varsaydım. Sabit.
Casey,

3

Hırsızlar arasında Onur

#!/usr/bin/env python

"""
Honor Among Thieves, by Josh Caswell

I'd never sell out a fellow thief, but I'll fleece a plump mark,
and I'll cut your throat if you try to cross me.
"""

from __future__ import division
import sys

PLUMPNESS_FACTOR = .33
WARINESS = 10

THIEVES_CANT = "E" + ("K" * WARINESS)

try:
    history = sys.argv[1]
except IndexError:
    history = ""

if history:
    sucker_ratio = (history.count('K') + history.count('S')) / len(history)
    seem_to_have_a_sucker = sucker_ratio > PLUMPNESS_FACTOR


# "Hey, nice t' meetcha."
if len(history) < WARINESS:
    #"Nice day, right?"
    if not set(history).intersection("RE"):
        print 'c'
    # "You sunnuvab..."
    else:
        print 't'

# "Hey, lemme show ya this game. Watch the queen..."
elif len(history) == WARINESS and seem_to_have_a_sucker:
    print 't'

# "Oh, s#!t, McWongski, I swear I din't know dat were you."
elif history[-len(THIEVES_CANT):] == THIEVES_CANT:

    # "Nobody does dat t' me!"
    if set(history[:-len(THIEVES_CANT)]).intersection("RE"):
        print 't'
    # "Hey, McWongski, I got dis job we could do..."
    else:
        print 'c'

# "Do you know who I am?!"
elif set(history).intersection("RE"):
    print 't'

# "Ah, ya almos' had da queen dat time. One more try, free, hey? G'head!"
elif seem_to_have_a_sucker:
    print 't'

# "Boy, you don't say much, do ya?"
else:
    print 'c'

THIEVES_CANTEsasen bir el sıkışma olduğuna dikkat edin , ancak yalnızca bir işbirliğine karşı oynadığınızda ortaya çıkacaktır. Ancak, daha sonraki haçları kontrol ederek parazit sorununu önler. Baz kadroya karşı oldukça iyi yapar.


Lisper'i güvenilir bir şekilde öldüren ilk kişi olmasından dolayı +1. Ortalama zafer marjı - 300 puan.
arrdem

Mevcut alanın turnike çalışmasında en güçlü olduğu görülüyor.
Peter Taylor

Aslında, hayır, Druid şimdi golcüyü düzelttim.
Peter Taylor

@ rmckenzie, @ Peter: Geez, gerçekten mi? Sadece kişiliğe gidiyordum.
Josh Caswell

@josh - daha fazla değil .... yeni gol kodunda @ casey gol kodunda Lisper geri döndü, ardından köpekbalığı geldi.
arrdem

3

"Probabimatic"

İşbirliği ile başlar, sonra hangi seçeneğe en yüksek değeri verirse onu seçer. Basit.

#include <stdio.h>

void counts(char* str, int* k, int* r, int* s, int* e) {
    *k = *r = *s = *e = 0;
    char c;
    for (c = *str; c = *str; str++) {
        switch (c) {
            case 'K': (*k)++; break;
            case 'R': (*r)++; break;
            case 'S': (*s)++; break;
            case 'E': (*e)++; break;
        }
    }
}

// Calculates the expected value of cooperating and defecting in this round. If we haven't cooperated/defected yet, a 50% chance of the opponent defecting is assumed.
void expval(int k, int r, int s, int e, float* coop, float* def) {
    if (!k && !r) {
        *coop = .5;
    } else {
        *coop = 2 * (float)k / (k + r) - (float)r / (k + r);
    }
    if (!s && !e) {
        *def = 2.5;
    } else {
        *def = 4 * (float)s / (s + e) + (float)e / (s + e);
    }
}

int main(int argc, char** argv) {
    if (argc == 1) {
        // Always start out nice.
        putchar('c');
    } else {
        int k, r, s, e;
        counts(argv[1], &k, &r, &s, &e);
        float coop, def;
        expval(k, r, s, e, &coop, &def);
        if (coop > def) {
            putchar('c');
        } else {
            // If the expected values are the same, we can do whatever we want.
            putchar('t');
        }
    }
    return 0;
}

İşbirliği ile başlamak için kullanılır, ancak şimdi kusurlu işlem aslında daha iyi çalışıyor gibi görünüyor. EDIT: Oh bekleyin, aslında değil.


1
Başka bir istatistikçi! Bunun onun diğer hesap makinelerine karşı nasıl oynadığını görelim !
Josh Caswell

Bu arada, gcc değiştirirseniz for (char c = *str;, char c; for (c = *str;gcc bunu C99 moduna geçirilmesi gerektiğinden şikayet etmeden derleyecektir.
Peter Taylor

3

Hiperrasyonel Eşekarısı

Java'da uygulandı çünkü veri yapılarının ne kadar karmaşık olacağından emin değildim. Eğer bu bir insan için bir sorunsa, sanırım çok fazla problem olmadan bash ile bağlantı kurabilirim çünkü sonunda sadece basit ilişkisel diziler kullanır.

Not : Bunu, Java'yı işlemek için yamamın en son sürümüne uygun bir paketteki puanlayıcıya kaldırdım. Eğer iç sınıfları kullanan bir Java çözümü göndermek istiyorsanız, yamayı düzeltmeniz gerekir.

import java.util.*;

public class HyperrationalWasp
{
    // I'm avoiding enums so as not to clutter up the warriors directory with extra class files.
    private static String Clam = "c";
    private static String Rat = "t";
    private static String Ambiguous = "x";

    private static final String PROLOGUE = "ttc";

    private static int n;
    private static String myActions;
    private static String hisActions;

    private static String decideMove() {
        if (n < PROLOGUE.length()) return PROLOGUE.substring(n, n+1);

        // KISS - rather an easy special case here than a complex one later
        if (mirrorMatch()) return Clam;
        if (n == 99) return Rat; // This is rational rather than superrational

        int memory = estimateMemory();
        if (memory == 0) return Rat; // I don't think the opponent will punish me
        if (memory > 0) {
            Map<String, String> memoryModel = buildMemoryModel(memory);
            String myRecentHistory = myActions.substring(0, memory - 1);
            // I don't think the opponent will punish me.
            if (Clam.equals(memoryModel.get(Rat + myRecentHistory))) return Rat;
            // I think the opponent will defect whatever I do.
            if (Rat.equals(memoryModel.get(Clam + myRecentHistory))) return Rat;
            // Opponent will cooperate unless I defect.
            return Clam;
        }

        // Haven't figured out opponent's strategy. Tit for tat is a reasonable fallback.
        return hisAction(0);
    }

    private static int estimateMemory() {
        if (hisActions.substring(0, n-1).equals(hisActions.substring(1, n))) return 0;

        int memory = -1; // Superrational?
        for (int probe = 1; probe < 5; probe++) {
            Map<String, String> memoryModel = buildMemoryModel(probe);
            if (memoryModel.size() <= 1 || memoryModel.values().contains(Ambiguous)) {
                break;
            }
            memory = probe;
        }

        if (memory == -1 && isOpponentRandom()) return 0;

        return memory;
    }

    private static boolean isOpponentRandom() {
        // We only call this if the opponent appears not have have a small fixed memory,
        // so there's no point trying anything complicated. This is supposed to be a Wilson
        // confidence test, although my stats is so rusty there's a 50/50 chance that I've
        // got the two probabilities (null hypothesis of 0.5 and observed) the wrong way round.
        if (n < 10) return false; // Not enough data.
        double p = count(hisActions, Clam) / (double)n;
        double z = 2;
        double d = 1 + z*z/n;
        double e = p + z*z/(2*n);
        double var = z * Math.sqrt(p*(1-p)/n + z*z/(4*n*n));
        return (e - var) <= 0.5 * d && 0.5 * d <= (e + var);
    }

    private static Map<String, String> buildMemoryModel(int memory) {
        // It's reasonable to have a hard-coded prologue to probe opponent's behaviour,
        // and that shouldn't be taken into account.
        int skip = 0;
        if (n > 10) skip = n / 2;
        if (skip > 12) skip = 12;

        Map<String, String> memoryModel = buildMemoryModel(memory, skip);
        // If we're not getting any useful information after skipping prologue, take it into account.
        if (memoryModel.size() <= 1 && !memoryModel.values().contains(Ambiguous)) {
            memoryModel = buildMemoryModel(memory, 0);
        }
        return memoryModel;
    }

    private static Map<String, String> buildMemoryModel(int memory, int skip) {
        Map<String, String> model = new HashMap<String, String>();
        for (int off = 0; off < n - memory - 1 - skip; off++) {
            String result = hisAction(off);
            String hypotheticalCause = myActions.substring(off+1, off+1+memory);
            String prev = model.put(hypotheticalCause, result);
            if (prev != null && !prev.equals(result)) model.put(hypotheticalCause, Ambiguous);
        }
        return model;
    }

    private static boolean mirrorMatch() { return hisActions.matches("c*ctt"); }
    private static String myAction(int idx) { return myActions.substring(idx, idx+1).intern(); }
    private static String hisAction(int idx) { return hisActions.substring(idx, idx+1).intern(); }
    private static int count(String actions, String action) {
        int count = 0;
        for (int idx = 0; idx < actions.length(); ) {
            int off = actions.indexOf(action, idx);
            if (off < 0) break;
            count++;
            idx = off + 1;
        }
        return count;
    }

    public static void main(String[] args) {
        if (args.length == 0) {
            hisActions = myActions = "";
            n = 0;
        }
        else {
            n = args[0].length();
            myActions = args[0].replaceAll("[KR]", Clam).replaceAll("[SE]", Rat);
            hisActions = args[0].replaceAll("[KS]", Clam).replaceAll("[RE]", Rat);
        }

        System.out.println(decideMove());
    }

}

Bunu yapmak için golcüye yaptığım değişiklikler:

17a18
> import re
22a24
> GCC_PATH = 'gcc'                #path to c compiler
24c26
< JAVA_PATH = '/usr/bin/java'   #path to java vm
---
> JAVA_PATH = '/usr/bin/java'     #path to java vm
50,55c52,59
<         elif ext == '.java':
<             if subprocess.call([JAVAC_PATH, self.filename]) == 0:
<                 print 'compiled java: ' + self.filename
<                 classname = re.sub('\.java$', '', self.filename)
<                 classname = re.sub('/', '.', classname);
<                 return JAVA_PATH + " " + classname
---
>         elif ext == '.class':
>             # We assume further down in compilation and here that Java classes are in the default package
>             classname = re.sub('.*[/\\\\]', '', self.filename)
>             dir = self.filename[0:(len(self.filename)-len(classname))]
>             if (len(dir) > 0):
>                 dir = "-cp " + dir + " "
>             classname = re.sub('\\.class$', '', classname);
>             return JAVA_PATH + " " + dir + classname
196c200,201
<         if os.path.isdir(sys.argv[1]):
---
>         warriors_dir = re.sub('/$', '', sys.argv[1])
>         if os.path.isdir(warriors_dir):
198,200c203,211
<             for foo in os.listdir("./src/"): # build all c/c++ champs first.
<                 os.system(str("gcc -o ./warriors/" + os.path.splitext(os.path.split(foo)[1])[0] + " ./src/" + foo ))
<                 #print str("gcc -o ./warriors/" + os.path.splitext(os.path.split(foo)[1])[0] + " ./src/" + foo )
---
>             for foo in os.listdir("./src/"): # build all c/c++/java champs first.
>                 filename = os.path.split(foo)[-1]
>                 base, ext = os.path.splitext(filename)
>                 if (ext == '.c') or (ext == '.cpp'):
>                     subprocess.call(["gcc", "-o", warriors_dir + "/" + base, "./src/" + foo])
>                 elif (ext == '.java'):
>                     subprocess.call([JAVAC_PATH, "-d", warriors_dir, "./src/" + foo])
>                 else:
>                     print "No compiler registered for ", foo
202,203c213,214
<             print "Finding warriors in " + sys.argv[1]
<             players = [sys.argv[1]+exe for exe in os.listdir(sys.argv[1]) if os.access(sys.argv[1]+exe,os.X_OK)]
---
>             print "Finding warriors in " + warriors_dir
>             players = [warriors_dir+"/"+exe for exe in os.listdir(warriors_dir) if (os.access(warriors_dir+"/"+exe,os.X_OK) or os.path.splitext(exe)[-1] == '.class')]

Challenger fonksiyonumda katlandığım için @rmckenzie'ye teşekkürler.


Sadece bir stil meselesi .... .java dosyası "kaynak" olarak kabul edilmeli ve. / Src dizinine ve. Java yorumlanır ve .java ve .class birlikte kalır mı? Her halükarda golcüye yapılan güzel değişiklikler ... onları depoda saklayacak.
arrdem

@ rmckenzie, iyi nokta: evet, teknik olarak derlendi. Kaynak dosyamın savaşçı dizininde olmasının sebebi python dosyalarının da orada bulunması - derlenmiş olmaları. İsterseniz, ./src'den ./warriors'a derlemek için hangi değişikliklerin gerekli olduğunu kontrol edebilirim - ancak birkaç derleyici argümanına ihtiyaç duyar, çünkü Java varsayılan olarak dizin yapısının paketi (ad alanını) yansıttığını varsaymaktadır.
Peter Taylor

Peter, merak ediyorum da ... savaşçıların. / savaşçılarda * nix 777, ya da başka şekilde çalıştırılabilir olmaları nedeniyle bulundu. Python ve Lisp scriptleri NOMINALLY performans için derlenmiştir, ancak doğal (kaynak) durumlarında çalıştırılabilirler. JAVA OLMAYAN BİR KİŞİ OLARAK BİLGİLERİME .java dosyalarında bu izinler bulunmuyor ve bu yüzden görünmüyor. Bunun için hack var ... derleme ayrı bir adımdır. Yani evet. Bu değişikliği yapmayı düşünürseniz çok sevinirim. REPO LINK
21'de arrdem

777’de eşek arısı ve kodunu kullanarak JVM bu güzelliği attı. Exception in thread "main" java.lang.NoClassDefFoundError: //warriors/HyperrationalWasp Caused by: java.lang.ClassNotFoundException: ..warriors.HyperrationalWasp at java.net.URLClassLoader$1.run(URLClassLoader.java:217) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:205) at java.lang.ClassLoader.loadClass(ClassLoader.java:321) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
arrdem

@rmckenzie, bu garip. Her neyse, sanırım kısa bir süre içinde senin için bir yamam olacak. Sınıf dosyaları çalıştırılamadığından yükleme kodunu kırmak zorunda kaldım. Diğer Java girişleri iç sınıfları kullanırsa kırılır.
Peter Taylor

3

Soft_majo

Tabii ki, sadece sıralamayı tamamlamak için standart stratejilerden bir diğeri.

Bu, rakibin en çok yaptığı hareketi seçer; Eşit ise işbirliği yapar.

#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[]) {
    int d = 0, i, l;

    if (argc == 1) {
        printf("c\n");
    } else {
        l = strlen(argv[1]);

        for (i = 0; i < l; i++)
            if (argv[1][i] == 'R' || argv[1][i] == 'E')
                d++;

        printf("%c\n", d > l/2 ? 't' : 'c');
    }
}

Kodunuz soft_majo, ancak açıklamanız hard_majo.
Peter Taylor

Peter: Eek, özür dilerim; sabit.
Joey,

3

Rastgele enayi

Bu, rakibin çok sık hasar vermesi durumunda (eşik) arızalanacak, ancak her seferinde ve sonra rasgele geri çekilmeyi deneyecektir.

Java ve Lisp oyuncuları dışındaki herkese karşı oldukça iyi bir performans sergiliyor (test makinesinde ne Java ne de Lisp olduğu için kaçamıyorum); en azından çoğu zaman.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define THRESHOLD 7
#define RAND 32

int main(int c, char * a []) {
    int r;
    char * x;
    int d = 0;

    srandom(time(0) + getpid());

    if (c == 1) {
        printf("c\n");
        return 0;
    }

    for (x = a[1]; *x; x++)
        if (*x == 'R' || *x == 'E') d++;

    if (d > THRESHOLD || random() % 1024 < RAND || strlen(a[1]) == 99)
        printf("t\n");
    else
        printf("c\n");

    return 0;
}

HyperrationalWasp'a karşı genellikle şeytana karşı kabaca yapacağız. Her zaman sadece işbirliği yapmaya başlıyor, bu yüzden melek olduğunu farz ediyorum ve saldırıya devam ediyorum. Sonra eşiğe çarptığında şeytan moduna geçeceksiniz ve ben t4t'ye geçeceğim. İlk 6 hamlede rastgele yedeklenirse, şeytana geçmeden önce t4t'ye geçeceğim, ancak bunun olasılığı yüksek değil.
Peter Taylor

1
Peter: Stratejileri nadiren doğrudan birbirine karşı test ediyorum, çünkü genel alan strateji performansını oldukça etkiliyor. Şu anda testlerimde birincilik için çoğunlukla kademeli ve çekingen savaşlar yapıyor.
Joey,

Kademeli ve kederli olanlar Wasp'a karşı yaklaşık 200 puan aldı; rastgele enayi 83 puan alır.
Peter Taylor

2

mazide

#!/usr/bin/env python

"""
BYGONES, entry to 1P5 Iterated Prisoner's Dilemma, by Josh Caswell

Cooperates at first, plays as Tit for Tat for `bygones * 2` rounds, then checks 
history: if there's too much ratting, get mad and defect; too much 
suckering, feel bad and cooperate.
"""

bygones = 5

import sys

# React to strangers with trust.
try:
    history = sys.argv[1]
except IndexError:
    print 'c'
    sys.exit(0)

replies = { 'K' : 'c', 'S' : 'c',
            'R' : 't', 'E' : 't' }

# Reply in kind.
if len(history) < bygones * 2:
    print replies[history[0]]
    sys.exit(0)

# Reflect on past interactions.
faithful_count = history.count('K')
sucker_count = history.count('S')
rat_count = history.count('R')

# Reprisal. 
if rat_count > faithful_count + bygones:
    # Screw you!
    print 't'
    sys.exit(0)

# Reparation.
if sucker_count > faithful_count + bygones:
    # Geez, I've really been mean.
    print 'c'
    sys.exit(0)

# Resolve to be more forgiving.
two_tats = ("RR", "RE", "ER", "EE")
print 't' if history[:2] in two_tats else 'c'

Henüz en iyi değeri bygoneshesaplayamadım. Bunun kazanma amaçlı bir strateji olmasını beklemiyorum , ancak gerçek hayatta "iyi" olduğunu düşündüğüm gibi bir stratejinin performansıyla ilgileniyorum. Gelecekteki bir revizyonda karşılıklı kusur sayısının kontrol edilmesi de bulunabilir.


2

Vampir Yardım

#!/usr/bin/env python

"""
Help Vampire, entry to 1P5 Iterated Prisoner's Dilemma,
by Josh Caswell.

1. Appear Cooperative 2. Acknowledge Chastisement 
3. Act contritely 4. Abuse charity 5. Continual affliction
"""

import sys
from os import urandom

LEN_ABASHMENT = 5

try:
    history = sys.argv[1]
except IndexError:
    print 'c'    # Appear cooperative
    sys.exit(0)

# Acknowledge chastisement
if history[0] in "RE":
    print 'c'
# Act contritely
elif set(history[:LEN_ABASHMENT]).intersection(set("RE")):
    print 'c'
# Abuse charity
elif history[0] == 'S':
    print 't'
# Continual affliction
else:
    print 't' if ord(urandom(1)) % 3 else 'c'

Kendisine karşı karıştığında eğlenceli bir asimetrik sonuç var. Keşke bu çözüm gerçek hayatta uygulanabilirse.


2

Büyücü

#!/usr/bin/env python

"""
Druid, by Josh Caswell

Druids are slow to anger, but do not forget.
"""

import sys
from itertools import groupby

FORBEARANCE = 7
TOLERANCE = FORBEARANCE + 5

try:
    history = sys.argv[1]
except IndexError:
    history = ""

# If there's been too much defection overall, defect
if (history.count('E') > TOLERANCE) or (history.count('R') > TOLERANCE):
    print 't'
# Too much consecutively, defect
elif max([0] + [len(list(g)) for k,g in     # The 0 prevents dying on []
                groupby(history) if k in 'ER']) > FORBEARANCE:
    print 't'
# Otherwise, be nice
else:
    print 'c'

Baz kadroya karşı oldukça iyi yapar.


2

avanak

#!/usr/bin/env python

"""
Simpleton, by Josh Caswell

Quick to anger, quick to forget, unable to take advantage of opportunity.
"""

import sys
from os import urandom

WHIMSY = 17

try:
    history = sys.argv[1]
except IndexError:
    if not ord(urandom(1)) % WHIMSY:
        print 't'
    else:
        print 'c'
    sys.exit(0)

if history[0] in "RE":
    print 't'
elif not ord(urandom(1)) % WHIMSY:
    print 't'
else:
    print 'c'

Baz görevlilerine karşı tamam.


2

Küçük Schemer

#!/usr/bin/env python

"""
The Little Schemer, by Josh Caswell

No relation to the book. Keeps opponent's trust > suspicion 
by at least 10%, trying to ride the line.
"""

from __future__ import division
import sys
from os import urandom

out = sys.stderr.write

def randrange(n):
    if n == 0:
        return 0
    else:
        return ord(urandom(1)) % n

try:
    history = sys.argv[1]
except IndexError:
    print 'c'
    sys.exit(0)

R_count = history.count('R')
S_count = history.count('S')
K_count = history.count('K')
E_count = history.count('E')

# Suspicion is _S_ and E because it's _opponent's_ suspicion
suspicion = (S_count + E_count) / len(history)
# Likewise trust
trust = (K_count + R_count) / len(history)

if suspicion > trust:
    print 'c'
else:
    projected_suspicion = (1 + S_count + E_count) / (len(history) + 1)
    projected_trust = (1 + K_count + R_count) / (len(history) + 1)

    leeway = projected_trust - projected_suspicion
    odds = int(divmod(leeway, 0.1)[0])

    print 't' if randrange(odds) else 'c'

Taban setine karşı zayıf, ancak hedefine karşı oldukça iyi yapar. Açıkçası, Şema'da yazılı değil.


Neden bir meydan okuma hissediyorum?
arrdem

Bu serseriyi mağlup et ... Lisper'daki eşiği rastgele seçti.
arrdem

@rmckenzie: Fakat bu alanın geri kalanına karşı oyununuzu nasıl etkiledi? Birbirleriyle yeterli sayıda işbirlikçi çalışarak paranoyak veya kıskanç stratejiler daha da kötüleşmeye başlayacak. Siz de, sömürülebilecek sabit bir üst sınırınız var.
Josh Caswell

Şu anki lisper'ı okursanız, kıskançlıktan daha savunmacıdır. Bunun gibi istatistiksel olarak haince sınırlar peşinde koşan rakipleri algılamaya çalışır ve ancak o zaman ateşi geri verir. CC açılışı, Hırsızlarla sağ ayağa kalkacak şekilde tasarlandı ve kooperatif sınırlarının çoğunu birlikte oynamaya ikna etmenin faydasını ekledi.
arrdem

@ rmckenzie: Çok iyi! Ona bir tur vereceğim.
Josh Caswell

1

Two Tats için baştankara

başka bir eski favori

#!/usr/bin/env python

"""
Tit For Two Tats, entry to 1P5 Iterated Prisoner's Dilemma, 
    by Josh Caswell (not an original idea).

Cooperates unless opponent has defected in the last two rounds.
"""

import sys
try:
    history = sys.argv[1]
except IndexError:
    history = ""

two_tats = ("RR", "RE", "ER", "EE")

if len(history) < 2:
    print 'c'
else:
    print 't' if history[:2] in two_tats else 'c'

Bir fonksiyonun içinde olmadıkça bir geri dönüş yapamazsınız. Belki kullanmak sys.exit(0)? Ya da bitmesine izin ver. Düzenleme: Ayrıca, programınıza yapılan ilk çağrı IndexError, yaptığınız zaman neden olan herhangi bir tarihe sahip değildir argv[1].
Casey,

len(history)<2Maddeyi bırakmış olabilirsiniz , çünkü sonuncusu elsebölüme benziyor .
dmckee

@Casey @dmckee Hata düzeltmeleri için teşekkür ederiz. Özellikle de "Duh" return!
Josh Caswell

@dmckee: Bu daha karmaşık bir şeyin parçası olarak başladı ve sonra İki Tat için Baştankara'yı yeniden yazdığımı ve girmeye karar verdiğimi fark ettim. Kopyala yapıştır kullanıcı hatası.
Josh Caswell

@Josh: Bygones girişinizi kısaca gördüm, sildiniz mi? İlgilenmiş görünüyordu.
Casey,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.