1P5: ภาวะที่กลืนไม่เข้าคายไม่ออกของนักโทษที่ถูกย้ำ


35

งานนี้เป็นส่วนหนึ่งของครั้งแรกงวดพรีเมียร์โปรแกรมปริศนาผลักดันและมีวัตถุประสงค์เพื่อเป็นสาธิตของใหม่ท้าทายชนิดข้อเสนอ

ภารกิจคือเขียนโปรแกรมเพื่อเล่นภาวะที่กลืนไม่เข้าคายไม่ออกของนักโทษที่ทำซ้ำได้ดีกว่าผู้เข้าร่วมรายอื่น

ดู Vinny เรารู้จักเพื่อนร่วมห้องของคุณ --- เขาชื่ออะไร? ใช่ McWongski, นักเลงนิปโป - ไอริช - ยูเครน - ขึ้นอยู่กับบางสิ่งและคุณรู้ว่ามันคืออะไร

เราพยายามทำตัวให้ดีที่นี่วินนี ให้โอกาสคุณ Givin

ถ้าคุณบอกเราว่าเขาวางแผนอะไรเราจะเห็นว่าคุณได้รับงานที่ดี

และถ้าคุณไม่ ...

กฎของเกม

  • การประกวดประกอบด้วยการแข่งขันรอบเต็มรูปแบบ (การจับคู่ที่เป็นไปได้ทั้งหมด) ของผู้เข้าแข่งขันสองคนในเวลาเดียวกัน (รวมถึงการเล่นด้วยตัวเอง)
  • มี 100 รอบการเล่นระหว่างแต่ละคู่
  • ในแต่ละรอบผู้เล่นแต่ละคนจะถูกขอให้เลือกระหว่างการร่วมมือกับผู้เล่นคนอื่นหรือทรยศพวกเขาโดยไม่ทราบเจตนาของผู้เล่นคนอื่นในเรื่องนี้แต่ด้วยความทรงจำเกี่ยวกับผลลัพธ์ของรอบก่อนหน้าที่เล่นกับคู่ต่อสู้นี้
  • คะแนนจะได้รับในแต่ละรอบขึ้นอยู่กับตัวเลือกที่รวมกัน หากผู้เล่นทั้งสองร่วมมือกันพวกเขาแต่ละคนจะได้รับ 2 คะแนน การหักหลังร่วมกันให้คะแนน 1 คะแนน ในกรณีที่ผสมผู้เล่นที่ถูกหักหลังจะได้รับ 4 คะแนนและผู้ประสานงานจะถูกลงโทษด้วย 1
  • การแข่งขัน "ทางการ" จะดำเนินการไม่ช้ากว่า 10 วันหลังจากโพสต์พร้อมกับผลงานทั้งหมดที่ฉันสามารถทำงานได้และใช้เพื่อเลือกผู้ชนะที่ "ยอมรับ" ฉันมีกล่อง Mac OS 10.5 ดังนั้นโซลูชัน POSIX ควรใช้งานได้ แต่มี linuxisms ที่ไม่มี ในทำนองเดียวกันฉันไม่ได้รับการสนับสนุนสำหรับ win32 API ฉันยินดีที่จะใช้ความพยายามขั้นพื้นฐานในการติดตั้งสิ่งต่าง ๆ แต่มีข้อ จำกัด ข้อ จำกัด ของระบบของฉันไม่แสดงถึงขีด จำกัด ของการตอบสนองที่ยอมรับได้เพียงแค่สิ่งที่จะรวมอยู่ในการแข่งขัน "อย่างเป็นทางการ"

ส่วนต่อประสานของโปรแกรมเมอร์

  • รายการควรอยู่ในรูปแบบของโปรแกรมที่สามารถเรียกใช้จากบรรทัดคำสั่ง การตัดสินใจจะต้องส่งออก (แต่เพียงผู้เดียว!) ของโปรแกรมในการส่งออกมาตรฐาน ประวัติของรอบก่อนหน้ากับคู่ต่อสู้นี้จะถูกนำเสนอเป็นอาร์กิวเมนต์บรรทัดคำสั่ง
  • เอาท์พุทเป็น "c" (สำหรับclam up ) หรือ "t" (เพื่อบอกทั้งหมด )
  • ประวัติเป็นสตริงอักขระเดียวที่แสดงถึงรอบก่อนหน้าโดยมีรอบล่าสุดที่เร็วที่สุดในสตริง ตัวละครนั้น
    • "K" (สำหรับการรักษาความเชื่อหมายถึงความร่วมมือซึ่งกันและกัน)
    • "R" (สำหรับหนู b @ st @ rd ขายให้ฉันหมดแล้ว! )
    • "S" (สำหรับผู้ดูด!หมายความว่าคุณได้รับประโยชน์จากการทรยศ)
    • "E" (สำหรับทุกคนมองหาหมายเลขหนึ่งในการทรยศต่อกัน)

ตัวยึด

ผู้เล่นสี่คนจะได้รับการจัดทำโดยผู้เขียน

  • นางฟ้า - ร่วมมือกันเสมอ
  • Devil - พูดเสมอ
  • TitForTat - ให้ความร่วมมือในรอบแรกจากนั้นทำตามที่เขาทำในรอบสุดท้ายเสมอ
  • สุ่ม - 50/50

ที่ฉันจะเพิ่มรายการทั้งหมดที่ฉันสามารถเรียกใช้

คะแนนรวมจะเป็นคะแนนรวมกับทุกฝ่าย (รวมถึงการเล่นด้วยตนเองเพียงครั้งเดียวและใช้คะแนนเฉลี่ย)

ผู้เข้าประกวด

(ปัจจุบัน ณ วันที่ 2 พฤษภาคม 2011 7:00 น.)

The Secret Handshake | Anti-T42T Missile | ความไม่ไว้วางใจ (ตัวแปร) | ป้องกันการจับมือกัน | The Little Lisper | บรรจบ | ฉลาม | Probabimatic | พาฟโลฟ - ชนะ Stay, สวิทช์ลด | เกียรติยศในหมู่โจร | ช่วยเหลือแวมไพร์ | Druid | ลิตเติ้ลอุบาย | Bygones | หัวนมสำหรับ Two Tats | Simpleton |

คนจดบัญชี

#! /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
  • การร้องเรียนเกี่ยวกับหลามที่น่ากลัวของฉันยินดีต้อนรับเนื่องจากฉันแน่ใจว่านี่แย่กว่าหนึ่งทาง
  • ยินดีต้อนรับการแก้ไขข้อผิดพลาด

ผู้บันทึกการเปลี่ยนแปลง:

  • พิมพ์ผู้เล่นและคะแนนที่เรียงลำดับแล้วประกาศผู้ชนะ (4/29, Casey)
  • เรียกใช้การแข่งขันหลายรายการ ( ./score warriors/ num_tournaments)) ค่าเริ่มต้น = 1, ตรวจจับและรวบรวมไพ ธ อนแหล่ง (4/29, เคซี่ย์)
  • แก้ไขข้อผิดพลาดโง่ ๆ ที่ผู้เล่นคนที่สองกำลังถูกส่งผ่านประวัติที่ไม่ถูกต้อง (4/30, dmckee; ขอบคุณ Josh)

นักรบเริ่มต้น

โดยวิธีการเป็นตัวอย่างและเพื่อให้สามารถตรวจสอบผลลัพธ์

นางฟ้า

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

หรือ

#!/bin/sh
echo c

หรือ

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

ปีศาจ

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

สุ่ม

#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;
}

โปรดทราบว่าผู้บันทึกคะแนนอาจเรียกนักรบอีกหลายครั้งในหนึ่งวินาทีดังนั้นความพยายามอย่างจริงจังจะต้องทำเพื่อประกันการสุ่มผลลัพธ์ถ้าใช้เวลาในการหว่าน PRNG

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;
}

คนแรกที่ทำอะไรบางอย่างกับประวัติศาสตร์

การเรียกผู้ลงคะแนนเฉพาะผู้ที่ได้รับผลตอบแทนเท่านั้น

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)

ปีศาจตัวนั้นเขาเป็นคนมีฝีมือและดูเหมือนว่าคนดี ๆ จะเข้ามาในที่สุด

ผล

ของการ "รัน" อย่างเป็นทางการ

('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
ถ้าเพื่อนร่วมห้องของฉันคือนิปปอน - ไอริช - ยูเครนทำไมชื่อของเขาถึงดู Hiberno-Sino-Russian
Peter Taylor

2
@Peter: ฮ่า ๆ ความจริง? (1) ลำดับวงศ์ตระกูลไม่ชัดเจน แต่ฉันอาจจะมาโดยmic'edness ของฉันโดยวิธีสก็อต - ไอริช (2) หลังจากฉันเขียน "Nippo" ฉันลองชื่อเพื่อนของฉันหลาย ๆ ชิ้นจากดินแดนอาทิตย์อุทัยและไม่ชอบวิธีที่พวกเขาสแกนดังนั้นฉันจึงไปข้างหน้าและใช้นามสกุลจีนที่ฟัง ดีแทนและ (3) ฉันไม่ทราบความแตกต่างหากพวกเขาผลัดกันตีด้วยโซ่ตรวนของฉัน ซึ่งดูเหมือนว่าน่าจะอยู่ภายใต้สถานการณ์
dmckee

1
@Josh: การเปลี่ยนreturn (s1, L1+h1), (s2, L2+h1)เป็นreturn (s1, L1+h1), (s2, L2+h2)[Note L2+h2แทนที่จะL2+h1เป็นตอนท้าย] เป็นเรื่องง่ายไหม? // ความผิดพลาดของ Cut-n-paste หรือสิ่งที่งี่เง่าอย่างเท่าเทียมกัน Sheesh!
dmckee

2
ฉันใช้เวลาบางส่วนในสคริปต์การทดสอบและฉันยินดีที่จะประกาศการปรับปรุงที่นี่ อัปเดตนี้เพิ่มเชลล์แบบง่ายให้กับสคริปต์ทดสอบซึ่งช่วยให้ผู้ใช้เรียกใช้บอทนี้กับบอทนั้นด้วยตนเองเรียกใช้ทัวร์นาเมนต์ที่มีฟิลด์ จำกัด และสิ่งดีๆอื่น ๆ อย่าลังเลที่จะให้คำแนะนำ! โอ้ และฉันเป็นหนี้ @josh สำหรับแนวคิด bot-vs-bot จริงๆแล้วมันเป็นเพียงการใช้งานสคริปต์ "ผู้ฝึกสอน" ของเขายิ่งขึ้น
arrdem

2
น่าสนใจ: มีผู้เข้าแข่งขัน 23 คนแต่ละคนเล่น 22 รอบ หากทุกคนเล่น "Angel" ทุกคะแนนจะเป็น 4400 แต่คะแนนที่ดีที่สุดของ 4167 ก็ไม่ตรงกัน ถ้าเพียง แต่เราอยู่ในโลกที่สมบูรณ์แบบ ... :)
Briguy 37

คำตอบ:


11

ค่อยๆ

กลยุทธ์นี้จะขึ้นอยู่กับกระดาษโดยBeaufils, Delahaye และมาติเยอ My C ไม่ใช่ของที่ดีที่สุดดังนั้นหากใครมีข้อเสนอแนะในการปรับปรุง / เร่งรหัสให้ฉันรู้

[แก้ไข] สิ่งที่ควรทราบคือ Gradual ถูกออกแบบมาเพื่อเป็นกลยุทธ์ที่มีประสิทธิภาพสูงกว่า Tit สำหรับ Tat มันมีคุณสมบัติคล้ายกันโดยยินดีที่จะร่วมมือและตอบโต้กับคู่ต่อสู้ที่เสียเปรียบ ซึ่งแตกต่างจาก Tit for Tat ซึ่งมีเพียงความทรงจำของการเล่นรอบสุดท้ายเท่านั้น Gradual จะจดจำการมีปฏิสัมพันธ์ที่สมบูรณ์และกำจัดจำนวนครั้งที่ฝ่ายตรงข้ามเสียไป มันจะให้ความร่วมมือซึ่งกันและกันหลังจากนั้นอีกครั้ง

ตามปกติประสิทธิภาพของกลยุทธ์ขึ้นอยู่กับการจัดเรียงของกลยุทธ์อื่น ๆ กระดาษต้นฉบับยังไม่ชัดเจนในรายละเอียดบางอย่าง

#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

ความลับจับมือกัน

#!/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()

กลยุทธ์ที่นี่คือการเสียสละ 10 รอบแรกเพื่อทำการจับมือ "ความลับ" ถ้าฉันถูกขังอยู่กับตัวเองฉันก็จำประวัติศาสตร์ของการเคลื่อนไหว 10 ครั้งแรกและสวมหมวกเทวดาของฉันตลอดเวลาที่เหลือของเกม ทันทีที่ฉันรู้ว่าเพื่อนร่วมห้องของฉันไม่ใช่ตัวเองฉันก็กลายเป็นปีศาจในความพยายามที่จะใช้ประโยชน์จากเพื่อนร่วมห้องที่ร่วมมือกันมากเกินไป

ไม่ว่าการเสียสละ 10 รอบแรกจะช่วยให้ฉันได้เปรียบตัวปีศาจหรือไม่นั้นขึ้นอยู่กับจำนวนรายการที่มี เพื่อลดความเสียหายให้มีเพียง 3 คนเท่านั้นที่ร่วมมือกันปรากฏในการจับมือกัน

แก้ไข: TAGMATCH แบบไดนามิกในขณะนี้เพื่อป้องกันข้อผิดพลาดโง่ ๆ เช่นการเปลี่ยนแปลงเพียงหนึ่งในนั้นและดังนั้นฉันสามารถทำให้ TAG แบบไดนามิกในบางจุดในอนาคต

แก้ไข 2: ตอนนี้สร้างแท็กแบบสุ่มในการเรียกใช้ครั้งแรกและเก็บไว้ในไฟล์ที่ระบุโดยsys.argv[0]( .pycแทนที่ด้วย.pyดังนั้นมันจะไปที่รหัสไม่ใช่รหัสไบต์ไฟล์) ฉันคิดว่านี่เป็นข้อมูลเดียวที่อินสแตนซ์ทั้งหมดของฉันมีซึ่งไม่มีใครมีดังนั้นจึงดูเหมือนเป็นตัวเลือกเดียวสำหรับการหลีกเลี่ยงปรสิต


แต่ผู้ดูแลของคุณรู้ได้อย่างไรว่าตัวเองเป็นมาร?
arrdem

1
(ฉันรู้สึกเหมือนนกแก้วพูดว่า "Tit for Tat" ตลอดเวลา ... ) โปรดทราบว่า T4T จะเอาชนะกลยุทธ์ของคุณในการจับคู่กับ: T4T (ร่วมมือกันก่อนหน้านี้) และ Devil (ผลลัพธ์หนูน้อยลง) และจะผูกกับคุณ กลยุทธ์. แน่นอนว่าผลรวมที่ยิ่งใหญ่ไม่ใช่การจับคู่ทั้งหมดเป็นสิ่งที่นับได้ในท้ายที่สุด อย่างที่คุณพูดประชากรเป็นสิ่งสำคัญ
Josh Caswell

1
โอ้ไม่คุณได้รับ S เสริมหนึ่งรายการจาก Tit สำหรับ Tat ดี ฉันไม่รู้ว่าTAGกำลังเล่นอยู่ข้างหลัง อย่างไรก็ตามคุณไม่ควรTAGMATCHเป็น 'KEEEKEEEKE' หรือ "".join({('c', 'c'):'K', ('t', 't'): 'E'}[moves] for moves in zip(TAG, TAG))
Josh Caswell

@ John Good point - ฉันเคยมีแท็กที่แตกต่างกันและเมื่อฉันเปลี่ยนเพื่อลดความร่วมมือฉันลืมอัปเดต TAGMATCH @Arrdem ความคิดคือถ้าฉันเล่นกับตัวเองสิ่งที่ดีที่สุดที่จะทำคือการให้ความร่วมมือตลอดเวลาเพื่อเพิ่มผลรวมของคะแนนของพวกเขา
Aaron Dufour

1
อ๊ะไอ้บ้า ดังนั้นตอนนี้ฉันต้องค้นหา.pyไฟล์ทั้งหมดสำหรับรหัสของคุณและแตกแท็ก ฉันจะไม่ทำอย่างนั้นใน C แม้ว่า ...
Joey

6

The Little 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
    )
)

มาร

พิจารณารูปแบบต่อไปนี้ (Player1, Player2)

  • (C, T) - P2 ได้รับคะแนนสี่สำหรับการทรยศของเขาในขณะที่ P1 สูญเสียหนึ่ง
  • (T, T) - P2 และ P1 กำไร 1

สมมติว่า P2 เป็นปีศาจไม่มีหนทางใดที่ปีศาจจะสามารถทำคะแนนได้ในความเป็นจริงที่เลวร้ายที่สุดที่เขาสามารถทำได้คือได้รับเพียงจุดเดียว เมื่อเทียบกับฝ่ายตรงข้ามแบบสุ่มดังนั้นคะแนนที่เป็นไปได้ที่เลวร้ายที่สุดของมารจะเท่ากับ (5/2) * n โดยที่ n คือจำนวน "เกม" ที่เล่น กรณีที่เลวร้ายที่สุดของเขาคือการทำร้ายตัวเองซึ่งคะแนนของเขาจะเป็น n และกรณีที่ดีที่สุดของเขาคือต่อทูตสวรรค์ซึ่งจะเป็น 4 * n

ยืนยัน: ultimate_strat = ปีศาจ

นี่คือ Tourney การหนุนหลังเพื่อนร่วมห้องของฉันเป็นกลยุทธ์ที่ดีกว่าการร่วมมือกันเพราะจะช่วยให้คะแนนของฉันมากขึ้น (+4) โบนัส - เขาถูกกระแทก (-1)! ถ้าฉันยื่นคอให้เขาฉันจะได้รับ (+2) และหลวม (-1) ดังนั้นการแทงด้วยฝีเท้าทางสถิติจะได้รับรางวัล

แต่มันเป็นสิ่งที่ดีที่สุด?

ไม่มีเหตุผลใดที่จะร่วมมือกัน (ภายใต้ระบบการให้คะแนนนี้)

  • หากคุณเลือกเวลาที่ไม่ถูกต้องในการจับมือคุณจะหลุด
  • ถ้าคุณหนูอย่างน้อยคุณจะไม่เสียอะไรเลย
  • ถ้าคุณให้หนูและเขาเป็นใบ้คุณจะได้รับมากกว่า 2x ถ้าคุณเป็นคนดี

ในระบบ KOTH การเพิ่มผลตอบแทนสูงสุดเป็นสิ่งจำเป็น แม้ว่าคุณจะมีบอทสองคนที่ได้รับการซิงค์อย่างสมบูรณ์แบบและร่วมมือกันคะแนนบุคคลของพวกเขาจะยังคงได้รับเพิ่มเพียง 200 คะแนนสำหรับกีฬาของพวกเขา ในทางกลับกันมารจะได้รับอย่างน้อย 100 คะแนนโดยมีค่าเฉลี่ย 200 และสูงสุด 400 และเสียค่าใช้จ่ายสูงถึง 100 คะแนนในแต่ละฝ่าย! ดังนั้นจริง ๆ แล้วมารได้คะแนนเกมโดยเฉลี่ยอยู่ที่ 300 ถึง 500

บรรทัดล่างสุด - เวลาจะบอก

สำหรับฉันดูเหมือนว่าการให้คะแนนควรได้รับการพิจารณาอีกครั้งเพื่อมิให้ปีศาจใช้เวลาทั้งวัน การเพิ่มคะแนนความร่วมมือเป็น 3 ทั้งหมดอาจทำได้ อย่างไรก็ตามมีความเป็นไปได้ที่จะตรวจจับปีศาจและป้องกันพวกเขาจากการให้คะแนนเต็ม 400 เช่น pavlov และการแสดงทั้งๆที่มี ฉันสามารถพิสูจน์ได้ว่าคนใดคนหนึ่งจะได้รับคะแนนมากพอสำหรับความร่วมมือของพวกเขาเพื่อพิสูจน์ความศรัทธาของพวกเขา ไม่ ทั้งหมดนี้ขึ้นอยู่กับสนามสุดท้ายของการแข่งขัน

GL, HF!

และโปรดทำสิ่งที่เลวร้ายที่สุดให้กับโพสต์นี้ ฉันต้องการเขียนรายงานขั้นสูงของฉันในเรื่องนี้เมื่อทุกคนพูดและทำ

ประวัติรุ่น

  1. เพิ่มตัวแปรระยะขอบซึ่งเปลี่ยนค่าเผื่อของ Lisper สำหรับ duchebaggery แบบสุ่ม
  2. อัปเดตเสียงกระซิบเพื่อหอยสองรอบแรกเพื่อลงบนเท้าขวากับฝ่ายตรงข้ามที่ร่วมมือกัน
  3. ใช้อัลกอริทึมทางพันธุกรรมเพื่อค้นหาค่าที่แข็งแกร่งที่สุดสำหรับตัวสร้างขีด จำกัด แบบสุ่มโดยยึดตามคะแนนสะสมสูงสุดของพวกเขาเทียบกับชุดของคู่ต่อสู้มาตรฐาน โพสต์อัปเดตรวมถึงพวกเขา

เวอร์ชันอย่างเป็นทางการของ LISPER

รุ่นพัฒนาของเสียงกระซิบ


การให้คะแนนแตกต่างกันไปในแต่ละสายพันธุ์ของเกม ผมไม่เล่นรอบกับการเพิ่มแรงจูงใจความร่วมมือและผมเห็นว่ามันจะมีผลกระทบต่อกลยุทธ์การได้รับการแต่งตั้ง ข่าวดี: คุณสามารถคว้าแต้มทำประตูได้และตั้งกฎของคุณเอง โดยหลักการแล้วคุณสามารถเสนอเงินรางวัล
dmckee

fink install clisp :: แตะนิ้วซ้ำ ๆ ::
dmckee

1
@ Josh - ขอบคุณสำหรับลิงค์ ฉันอ่านวิกิพีเดียหน้าอื่น ๆ ในภาวะที่กลืนไม่เข้าคายไม่ออกนี้ แต่ฉันพลาดส่วนนั้น ข้อผิดพลาดของกฎที่ฉันเพิ่งสังเกตเห็นไม่มีกฎกับรายการโดยใช้ระบบไฟล์ สิ่งนี้จะสร้างศักยภาพสำหรับความร่วมมือที่มีประสิทธิภาพมากขึ้นตามเส้นทางของการจับมือกัน
arrdem

3
There is no reason to EVER (under this scoring system) co-operateถูกต้องเพียงครึ่งเดียว หากคุณรู้ว่าคู่ต่อสู้ของคุณไม่ได้คำนึงถึงประวัติ (เทวดามารสุ่ม) จากนั้นคุณควรจะเสีย หากคู่ต่อสู้ของคุณคำนึงถึงประวัติและคุณสามารถซิงค์ได้คุณก็ทำได้ดีกว่า ฉันมีความคิดสองสามข้อที่หมุนรอบการตรวจสอบว่าฝ่ายตรงข้ามมีเหตุผลหรือเหนือชั้น
Peter Taylor

1
คุณไม่ได้รับข้อผิดพลาดหารหารด้วย 3 / 20th ของรุ่นล่าสุดหรือไม่ เมื่อใดก็ตามที่(random 20)ให้ 2, 5, หรือ 8 (/ (+1 rand-num) 10)คือ 0.3, 0.6, 0.9 และส่วนที่เหลือของการหารด้วย 0.3 คือ 0; ดังนั้น(floor *dbag* *margin*)ตาย
Josh Caswell

5

ความไม่ไว้วางใจ (ตัวแปร)

อันนี้ออกมาเป็นครั้งแรกในการทดสอบของตัวเองเมื่อหลายปีก่อน (ตอนนั้นฉันอยู่เกรด 11 และทำวิทยานิพนธ์เล็ก ๆ ตรงนี้โดยใช้กลยุทธ์ที่นักเรียนคนอื่นสร้างขึ้นด้วย) มันเริ่มต้นด้วยลำดับtcc(และเล่นเหมือน Tit for Tat หลังจากนั้น

ขอโทษสำหรับรหัสที่น่ากลัว; หากใครบางคนสามารถทำให้สั้นลงในขณะที่ไม่ได้เล่นกอล์ฟฉันจะขอบคุณ :-)

#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 และ 2 case 1: case2: printf(...); break;ใช้ในฤดูใบไม้ร่วงผ่าน: และ GCC ต้องการการประกาศที่ชัดเจนของการใช้งานstring.h strlenไม่ว่าจะในกรณีใด
dmckee

อืมจริงนะ ฉันไม่แน่ใจว่าจะตรวจจับรอบแรกได้อย่างไรไม่ว่าจะมีอาร์กิวเมนต์แรก (ประวัติ) ว่างเปล่าหรือไม่มีเลย
Joey

ฉันไม่แน่ใจ. มันเป็นสิ่งที่หลามจะมีเมื่อPopen(p+" "+h,stdout=subprocess.PIPE,shell=True) ฉันคาดเดาh = '' argc=1
dmckee

1
ลำดับเริ่มต้นนั้นค่อนข้างเป็นความคิดที่ดีโดยเล็งไปที่ Tit เพราะความอ่อนแอของททท คุณจะได้รับตะกั่วขนาดเล็กบนมันจากนั้นเล่นไปทางนั้นหลังจากนั้น
Josh Caswell

1
@ Josh ใครจะเป็นผู้นำตัวเล็ก ๆ ? เทียบกับ T4T นี่เริ่มต้นจาก SRK และดำเนินการต่อด้วย K แต่ SR มีค่า 3 คะแนนสำหรับผู้เล่นแต่ละคน
Peter Taylor

5

Anti-T42T Missile

#!/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'

ทำได้ดีพอสมควรเมื่อเทียบกับชุดฐานนักรบ: สังหาร Angel, ถูกโจมตีโดย Devil เล็กน้อย (แต่รักษาคะแนนของเขาต่ำ), โดยทั่วไปแล้วเต้นแรนด์อย่างคล่องแคล่วและแทบจะเต้น Tit สำหรับ Tat ทำไม่ดีเมื่อเล่นกับตัวเอง


ฉันส่งการแก้ไขที่ทำให้ใช้งานได้จริง :) ต้องได้รับการอนุมัติ
Casey

@Casey: เจ้านายที่ดีฉันทำผิดพลาดโง่มากในความกระตือรือร้นของฉันสำหรับปัญหานี้! ขอบคุณ แต่ทำไมคุณถึงกำจัด sh-bang ออก?
Josh Caswell

เอ่อนั่นเป็นอุบัติเหตุ ฉันจะเพิ่มกลับ
Casey

@Casey: ไม่มีปัญหา ฉันจะทำมัน. จำเป็นต้องเพิ่มเอกสารสตริงอย่างไรก็ตาม
Josh Caswell

4

การลู่เข้า

เริ่มแรกดีแล้วเล่นแบบสุ่มด้วยตาบนประวัติของคู่ต่อสู้

/* 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;
}

ฉันได้ลองลดน้ำหนักลงบนประวัติศาสตร์แล้ว แต่ยังไม่ได้ปรับให้เหมาะสม


4

ปลาฉลาม

#!/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'

ทำได้ค่อนข้างดีเมื่อเทียบกับบัญชีรายชื่อฐาน


... ยึดหอยหรือไม่
arrdem

:) จับคนเขลา
Josh Caswell

+1 สำหรับการเก็บอันดับ 2 ที่สอดคล้องกันในฟิลด์ปัจจุบัน
arrdem

3

พาฟลอฟ - ชนะอยู่แพ้เสีย

ในเทิร์นแรกมันให้ความร่วมมือและจากนั้นก็จะร่วมมือกันถ้าหากผู้เล่นทั้งสองเลือกที่จะเลือกตัวเลือกเดียวกันในการย้ายครั้งก่อน

#!/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'

ไม่ควรใช้สิ่งนี้hist[0]( hist[-1]เป็นการย้ายครั้งแรกของรอบเสมอ)?
Josh Caswell

โอ้วววคุณพูดถูก ฉันสันนิษฐานว่าสตริงอินพุตมีรอบล่าสุดที่ส่วนท้ายของสตริงไม่ใช่จุดเริ่มต้น คงที่
Casey

3

ให้เกียรติในหมู่โจร

#!/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_CANTนี่คือการจับมือกันแม้ว่ามันจะเกิดขึ้นเมื่อเล่นกับผู้ร่วมมือเท่านั้น อย่างไรก็ตามมันช่วยหลีกเลี่ยงปัญหาของปรสิตด้วยการตรวจสอบกากบาทในภายหลัง ทำได้ค่อนข้างดีเมื่อเทียบกับบัญชีรายชื่อฐาน


+1 สำหรับการเป็น strat แรกที่สามารถสะท้อนแสงได้อย่างน่าเชื่อถือ ระยะขอบเฉลี่ยของชัยชนะ - 300 แต้ม
arrdem

ดูเหมือนจะแข็งแกร่งที่สุดในการแข่งขันรอบทัวร์นาเมนต์ของสนามปัจจุบัน
Peter Taylor

ที่จริงแล้วไม่มีดรูอิดตอนนี้ที่ฉันได้แก้ไขข้อผิดพลาดในแต้ม
Peter Taylor

@rmckenzie, @Peter: Geez จริงเหรอ? ฉันแค่ไปเพื่อบุคลิกภาพ
Josh Caswell

@ Josh - ไม่เหลืออีกแล้ว .... ในรหัสการให้คะแนนใหม่ @ รหัสการให้คะแนนของ casey Lisper กลับมาอยู่ด้านบนตามด้วยฉลาม
arrdem

3

"Probabimatic"

เริ่มต้นด้วยการให้ความร่วมมือจากนั้นเลือกตัวเลือกใดก็ได้ที่ให้มูลค่าที่คาดหวังสูงสุด ง่าย

#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;
}

เคยเริ่มต้นด้วยการร่วมมือกัน แต่ตอนนี้ดูเหมือนว่าการหลบหนีจะได้ผลดีกว่า แก้ไข: โอ้รอจริงมันไม่ได้


1
นักสถิติอีกคน! มาดูกันว่าสิ่งนี้เล่นกับเครื่องคิดเลขเพื่อนได้อย่างไร !
Josh Caswell

โดยวิธีการถ้าคุณเปลี่ยนfor (char c = *str;เป็นchar c; for (c = *str;gcc จะรวบรวมสิ่งนี้โดยไม่บ่นว่าจำเป็นต้องใส่ในโหมด C99
Peter Taylor

3

Hyperrational Wasp

ติดตั้งใน Java เพราะฉันไม่แน่ใจว่าโครงสร้างข้อมูลซับซ้อนแค่ไหน หากนี่เป็นปัญหาสำหรับใครบางคนฉันคิดว่าฉันสามารถพอร์ตให้มันทุบตีโดยไม่มีปัญหามากเกินไปเพราะในท้ายที่สุดแล้วมันใช้การเชื่อมโยงแบบง่าย ๆ เท่านั้น

หมายเหตุ : ฉันได้ลบสิ่งนี้ออกจากแพ็คเกจตามเวอร์ชั่นล่าสุดของแพตช์ของฉันไปที่แต้มเพื่อจัดการกับจาวา หากคุณต้องการโพสต์โซลูชัน Java ที่ใช้คลาสภายในคุณจะต้องแก้ไขแพตช์

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());
    }

}

การเปลี่ยนแปลงที่ฉันทำกับผู้บันทึกเพื่อเรียกใช้สิ่งนี้คือ:

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')]

ขอบคุณ @rmckenzie สำหรับการพับในฟังก์ชั่นผู้ท้าชิงของฉัน


เป็นเรื่องของสไตล์ .... ควรไฟล์. java ถูกพิจารณาว่าเป็น "source" และย้ายไปยังไดเร็กทอรี. / src และ. class สุดท้ายที่อยู่ในโฟลเดอร์. / warriors โดยตัวห้อยเดียวกันที่ใช้กับไฟล์. c หรือ java ตีความและเป็นเช่น. java และ. class อยู่ด้วยกันไหม การเปลี่ยนแปลงที่ดีกับแต้มในกรณีใด ๆ ... จะมีพวกเขาในสถิติซื้อคืน
arrdem

@rmckenzie จุดที่ดี: ใช่เทคนิคการรวบรวม เหตุผลที่ฉันมีไฟล์ต้นฉบับในไดเรกทอรี warriors ก็คือไฟล์ไพ ธ อนก็มีเช่นกัน - และพวกเขาก็รวบรวม หากคุณต้องการฉันสามารถตรวจสอบการเปลี่ยนแปลงที่จำเป็นในการรวบรวมจาก. / src เพื่อ. / นักรบ - แต่มันจะต้องมีข้อโต้แย้งคอมไพเลอร์ไม่กี่เพราะ Java โดยค่าเริ่มต้นถือว่าโครงสร้างไดเรกทอรีสะท้อนแพคเกจ (namespace)
ปีเตอร์เทย์เลอร์

@ ปีเตอร์ฉันแค่สงสัยว่า ... นักรบถูกค้นพบใน. / นักรบโดยอาศัยอำนาจในการเป็น * nix 777 หรือสามารถปฏิบัติการได้ สคริปต์ Python และ Lisp ถูกคอมไพล์ด้วย NOMINALLY เพื่อประสิทธิภาพการทำงาน แต่สามารถเรียกใช้งานได้ในสถานะธรรมชาติ (แหล่งที่มา) สำหรับความรู้ของฉันในฐานะบุคคลที่ไม่ใช่ JAVA ไฟล์. java ไม่มีสิทธิ์เหล่านั้นและจะไม่ปรากฏขึ้น นั่นคือสิ่งที่แฮ็คคมีไว้สำหรับ ... เนื่องจากการรวบรวมเป็นขั้นตอนแยกต่างหาก ใช่แล้ว ฉันจะซาบซึ้งเป็นอย่างยิ่งหากคุณต้องการเปลี่ยนแปลง
ลิงก์

โดยใช้รหัสของคุณและตัวต่อ 777 ในกรณีที่ JVM ขว้างความงามนี้ 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 มันแปลก อย่างไรก็ตามฉันคิดว่าฉันจะมีปะให้คุณในไม่ช้า ฉันต้องแฮ็ครหัสโหลดเนื่องจากไฟล์คลาสไม่สามารถเรียกใช้งานได้ และถ้ารายการ Java อื่น ๆ ใช้คลาสภายในมันจะแตก
Peter Taylor

3

Soft_majo

อ่าเป็นอีกหนึ่งในกลยุทธ์มาตรฐานเพียงเพื่อให้การจัดเรียงเสร็จสมบูรณ์

คนนี้เลือกท่าที่ฝ่ายตรงข้ามทำได้มากที่สุด ถ้าเท่ากันก็ให้ความร่วมมือ

#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');
    }
}

รหัสของคุณคือ soft_majo แต่คำอธิบายของคุณคือ hard_majo
Peter Taylor

Peter: Eek ขอโทษ; คงที่
Joey

3

เครื่องดูดแบบสุ่ม

อันนี้จะเสียถ้าฝ่ายตรงข้ามบกพร่องบ่อยเกินไป (ธรณีประตู) แต่จะพยายามแทงข้างหลังแบบสุ่มทุก ๆ คราว

ทำได้ค่อนข้างดีสำหรับทุกคนยกเว้นผู้เล่น Java และ Lisp (ซึ่งฉันไม่สามารถเรียกใช้ได้เนื่องจากไม่มี Java หรือ Lisp บนเครื่องทดสอบ) ส่วนใหญ่เวลาอย่างน้อย

#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 โดยทั่วไปแล้วจะทำประมาณกับมาร มันเริ่มต้นจากการให้ความร่วมมือตลอดเวลาดังนั้นฉันจึงคิดว่านั่นคือนางฟ้าและโจมตีต่อไป จากนั้นเมื่อถึงเกณฑ์คุณจะเปลี่ยนเป็นโหมดปีศาจและฉันจะเปลี่ยนเป็น t4t ถ้ามันสุ่มแบ็คแท็บในการเคลื่อนที่ 6 ครั้งแรกจากนั้นฉันจะเปลี่ยนเป็น t4t ก่อนที่คุณจะเปลี่ยนเป็นปีศาจ แต่โอกาสของมันนั้นไม่สูง
Peter Taylor

1
ปีเตอร์: ฉันไม่ค่อยทดสอบกลยุทธ์โดยตรงกับคนอื่น ๆ เพราะสนามโดยรวมมีอิทธิพลต่อประสิทธิภาพของกลยุทธ์ค่อนข้างมาก ปัจจุบันมันส่วนใหญ่ต่อสู้กับค่อยเป็นค่อยไปและดรูอิดสำหรับการทดสอบครั้งแรกของฉัน
Joey

แบบค่อยเป็นค่อยไปและ druid ทั้งสองคะแนนประมาณ 200 ต่อ Wasp; เครื่องดูดสุ่มจะทำคะแนนประมาณ 83
Peter Taylor

2

Bygones

#!/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'

ยังไม่ได้ผลคุ้มค่าที่ดีที่สุดสำหรับbygonesยัง ฉันไม่ได้คาดหวังว่านี่จะเป็นกลยุทธ์ที่ชนะแต่ฉันสนใจในการปฏิบัติงานของกลยุทธ์บางอย่างที่ฉันคิดว่าเป็น "ดี" ในชีวิตจริง การแก้ไขในอนาคตอาจรวมถึงการตรวจสอบจำนวนการละทิ้งซึ่งกันและกัน


2

ช่วยแวมไพร์

#!/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'

มีผลลัพธ์ที่ไม่สมดุลอย่างน่าขบขันเมื่อรับมือกับตัวเอง ถ้าเพียงวิธีนี้สามารถนำไปใช้ในชีวิตจริง


2

ดรูอิด

#!/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'

ทำได้ดีพอสมควรเมื่อเทียบกับบัญชีรายชื่อฐาน


2

คนโง่

#!/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'

ไม่เป็นไรกับบัญชีรายชื่อฐาน


2

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'

ทำไม่ดีกับชุดฐาน แต่ค่อนข้างดีกับเป้าหมาย เห็นได้ชัดว่าไม่ได้เขียนใน Scheme


ทำไมฉันถึงรู้สึกถึงความท้าทาย
arrdem

เอาชนะ Bugger นี้ .... เกณฑ์แบบสุ่มใน Lisper
arrdem

@rmckenzie: แต่มันส่งผลต่อการเล่นของคุณกับส่วนที่เหลืออย่างไร? ด้วยความร่วมมือที่เพียงพอในการทำงานร่วมกันกลยุทธ์หวาดระแวงหรือความอิจฉาจะเริ่มแย่ลง คุณยังคงมีขีด จำกัด ที่แน่นอนเช่นกันซึ่งอาจถูกนำไปใช้ประโยชน์
Josh Caswell

หากคุณอ่านเสียงกระซิบในปัจจุบันมันจะป้องกันได้มากกว่าความอิจฉา มันพยายามที่จะตรวจจับคู่ต่อสู้ที่กำลังตามล่าแนวทรยศทางสถิติเช่นนี้และจากนั้นก็ส่งคืนไฟ การเปิดตัว CC นั้นถูกออกแบบมาเพื่อก้าวลงสู่เท้าขวาของ Thieves และได้รับประโยชน์เพิ่มเติมจากการสร้างความเชื่อมั่นให้กับกลุ่มสหกรณ์ส่วนใหญ่ในการเล่น
arrdem

@rmckenzie: ดีมาก! ฉันจะให้มันหมุน
Josh Caswell

1

หัวนมสำหรับ Two Tats

รายการโปรดเก่าอีกรายการ

#!/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'

คุณไม่สามารถส่งคืนได้จนกว่าคุณจะอยู่ในฟังก์ชัน อาจจะใช้sys.exit(0)? หรือปล่อยให้มันเสร็จ แก้ไข:ยังภาวนาแรกที่โปรแกรมของคุณไม่มีประวัติใด ๆ ที่ทำให้เกิดเมื่อคุณทำIndexError argv[1]
Casey

คุณอาจจะทิ้งlen(history)<2ประโยคไว้เพราะประโยคสุดท้ายนั้นดูเหมือนกับelseส่วนนั้น
dmckee

@Casey @dmckee ขอบคุณสำหรับการแก้ไขข้อบกพร่อง "Duh" กับฉันreturnโดยเฉพาะ!
Josh Caswell

@dmckee: สิ่งนี้เริ่มต้นจากสิ่งที่ซับซ้อนยิ่งขึ้นและจากนั้นฉันก็รู้ว่าฉันได้เขียน Tit for Two Tats อีกครั้งและตัดสินใจที่จะป้อนสิ่งนั้น ข้อผิดพลาดของผู้ใช้คัดลอกวาง
Josh Caswell

@ จอช: ฉันเห็นรายการ Bygones ของคุณสั้น ๆ คุณลบมันได้หรือไม่ มันดูน่าสนใจ
Casey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.