ภาวะที่กลืนไม่เข้าคายไม่ออกที่มีเสียงดังของนักโทษ


35

ในการท้าทายนี้คุณจะเล่นสถานการณ์ที่ไม่แน่นอนของนักโทษที่มีเสียงดัง

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

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

ภาวะที่กลืนไม่เข้าคายไม่ออกซ้ำแล้วซ้ำอีกของเสียงดังขึ้นส่งเสียงดังในการสื่อสาร ความรู้ของคุณเกี่ยวกับสิ่งที่คู่ต่อสู้ของคุณได้เล่นในอดีตจะมีเสียงรบกวนบ้าง คุณจะรู้ว่าสิ่งที่คุณทำเคลื่อนไหวในอดีต อัตราเสียงนั้นคงที่ตลอดหนึ่งรอบกับคู่ต่อสู้เดียวกัน แต่ต่างกันระหว่างรอบที่แตกต่างกัน

ท้าทาย

ในการท้าทายนี้คุณจะเขียนโปรแกรม Python 3 เพื่อเล่นวิกฤติของนักโทษที่มีเสียงดัง

โปรแกรมของคุณจะได้รับสามอินพุต:

  • การเคลื่อนไหวของคุณเองโดยไม่ต้องใช้การพลิกแบบสุ่ม

  • การเคลื่อนไหวของฝ่ายตรงข้ามโดยใช้การโยนแบบสุ่ม

  • ตัวแปรสถานะซึ่งเริ่มต้นเป็นรายการว่างในแต่ละรอบและคุณสามารถแก้ไขได้หากคุณต้องการ คุณสามารถละเว้นสิ่งนี้หากคุณไม่ต้องการใช้

โปรแกรมของคุณควรส่งออก'c'ไปให้ความร่วมมือหรือมี'd'ข้อบกพร่อง

ตัวอย่างเช่นต่อไปนี้เป็นโปรแกรมที่ให้ความร่วมมือหากฝ่ายตรงข้ามได้ให้ความร่วมมืออย่างน้อย 60% ของเวลาในอดีตหลังจากการใช้การสุ่มแบบสุ่มและ 10 ครั้งแรก:

def threshold(my_plays, their_flipped_plays, state):
    if len(their_flipped_plays) < 10:
        return 'c'
    opp_c_freq = their_flipped_plays.count('c')/len(their_flipped_plays)
    if opp_c_freq > 0.6:
        return 'c'
    else:
        return 'd'

ถ้าคุณไม่รู้จัก Python เขียนการส่งของคุณใน pseudocode และใครบางคน (ฉันหรือสมาชิกคนอื่นของไซต์) สามารถสร้างโปรแกรม Python ที่สอดคล้องกันได้

เพลย์

รองชนะเลิศอันดับการแข่งขันสามารถพบได้ที่นี่: มีเสียงดังเกม วิ่งnoisy-game.pyเพื่อแข่งขัน ฉันจะอัปเดตที่เก็บข้อมูลนั้นด้วยการส่งใหม่ basic.pyโปรแกรมตัวอย่างที่สามารถพบได้ใน

คะแนนโดยรวมของโปรแกรมคือคะแนนรวมของเกมมากกว่า 100 ครั้ง

เกมประกอบด้วย matchups รอบโรบินของผู้เล่นแต่ละคนกับผู้เล่นแต่ละคนรวมถึงตัวเอง การแข่งขันประกอบด้วย 100 รอบ รอบประกอบด้วย 300 การเคลื่อนไหวของแต่ละคนที่เกี่ยวข้องกับการ outputting หรือ'c''d'

การส่งของคุณจะเล่น matchup กับทุกการส่งรวมถึงของคุณเอง การแข่งขันแต่ละครั้งจะประกอบด้วย 100 รอบ [0, 0.5]ในระหว่างแต่ละรอบน่าจะพลิกจะได้รับเลือกโดยการสุ่มจากสม่ำเสมอ

แต่ละรอบจะมี 300 การเคลื่อนไหว ในการย้ายแต่ละครั้งทั้งสองโปรแกรมจะได้รับการเล่นก่อนหน้านี้ทั้งหมดที่พวกเขาพยายามและการเล่นก่อนหน้านี้ทั้งหมดที่โปรแกรมอื่นทำหลังจากใช้การพลิกและตัวแปรสถานะซึ่งเป็นรายการที่ไม่แน่นอนซึ่งโปรแกรมสามารถปรับเปลี่ยนได้ถ้าต้องการ โปรแกรมจะแสดงผลการเคลื่อนไหวของพวกเขา

การเคลื่อนไหวมีคะแนนดังนี้: ถ้าโปรแกรมเล่น a 'c', โปรแกรมตรงข้ามได้รับ 2 คะแนน หากโปรแกรมเล่น a 'd'โปรแกรมนั้นจะได้ 1 คะแนน

จากนั้นการเคลื่อนไหวแต่ละครั้งจะถูกพลิกอย่างอิสระโดยมีความน่าจะเป็นเท่ากับความน่าจะเป็นพลิกและเก็บไว้เพื่อแสดงต่อฝ่ายตรงข้าม

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

เกณฑ์การให้คะแนน

เราจะใช้การให้คะแนนวิวัฒนาการ แต่ละโปรแกรมเริ่มต้นด้วยน้ำหนักที่เท่ากัน จากนั้นน้ำหนักจะได้รับการอัปเดตดังนี้สำหรับการวนซ้ำ 100 ครั้งโดยใช้คะแนนรวมจากเกม:

น้ำหนักใหม่ของแต่ละโปรแกรมนั้นขึ้นอยู่กับน้ำหนักของผลิตภัณฑ์ก่อนหน้านี้และผลรวมคะแนนเฉลี่ยโดยน้ำหนักตามน้ำหนักของคู่ต่อสู้

มีการอัปเดต 100 รายการดังกล่าวและน้ำหนักสุดท้ายเป็นคะแนนของแต่ละโปรแกรมสำหรับการดำเนินการของเกมนั้น

คะแนนรวมจะรวมกันมากกว่า 100 เกม

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

คำเตือน

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

แก้ไข: การส่งอาจไม่ซ้ำกันแน่นอนของโปรแกรมพื้นฐานใด ๆ หรือการส่งก่อนหน้านี้

หากคุณมีคำถามใด ๆ อย่าลังเลที่จะถาม

ผลลัพธ์ปัจจุบัน

nicht_genug: 40.6311
stealer: 37.1416
enough: 14.4443
wait_for_50: 6.947
threshold: 0.406784
buckets: 0.202875
change_of_heart: 0.0996783
exploit_threshold: 0.0670485
kickback: 0.0313357
tit_for_stat: 0.0141368
decaying_memory: 0.00907645
tit_for_whoops: 0.00211803
slider: 0.00167053
trickster: 0.000654875
sounder: 0.000427348
tit_for_tat: 9.12471e-05
stubborn_stumbler: 6.92879e-05
tit_for_time: 2.82541e-05
jedi2sith: 2.0768e-05
cooperate: 1.86291e-05
everyThree: 1.04843e-05
somewhat_naive: 4.46701e-06
just_noise: 1.41564e-06
growing_distrust: 5.32521e-08
goldfish: 4.28982e-09
vengeful: 2.74267e-09
defect: 3.71295e-10
alternate: 2.09372e-20
random_player: 6.74361e-21

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

nicht_genug: 39.3907
stealer: 33.7864
enough: 20.9032
wait_for_50: 5.60007
buckets: 0.174457
kickback: 0.0686975
change_of_heart: 0.027396
tit_for_stat: 0.024522
decaying_memory: 0.0193272
tit_for_whoops: 0.00284842
slider: 0.00153227
sounder: 0.000472289
trickster: 0.000297515
stubborn_stumbler: 3.76073e-05
cooperate: 3.46865e-05
tit_for_time: 2.42263e-05
everyThree: 2.06095e-05
jedi2sith: 1.62591e-05
somewhat_naive: 4.20785e-06
just_noise: 1.18372e-06
growing_distrust: 6.17619e-08
vengeful: 3.61213e-09
goldfish: 3.5746e-09
defect: 4.92581e-10
alternate: 6.96497e-20
random_player: 1.49879e-20

การชนะ

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


tit_for_whoops ไม่สนใจการเล่นของคู่ต่อสู้อย่างไร
LyricLy

@LyricLy ฉันถือว่าหมวดหมายถึงโปรแกรมพื้นฐานที่จัดหาโดย Isaac ซึ่งไม่สนใจคู่ต่อสู้ของตน
FryAmTheEggman

1
ฉันเข้าใจถูกต้องหรือไม่ว่าคุณสามารถใช้ตัวแปรสถานะเพื่อบันทึกการเคลื่อนไหวทั้งหมดของคุณเมื่อคุณส่งพวกเขาดังนั้นจึงรู้ทั้งการเคลื่อนไหวที่แท้จริงและการเคลื่อนไหวที่พลิกแล้วของคุณและประเมินความน่าจะเป็นที่พลิกกลับ
xnor

1
@xnor คุณจะได้รับการบอกเล่าการเคลื่อนไหวที่แท้จริงของคุณ เป็นเพียงการเคลื่อนไหวของคู่ต่อสู้ที่อาจพลิก
ช่วยในการจำ

1
@isaacg ฉันพยายามคัดลอกexploit_threshold()หลายครั้งในขณะที่exploit_threshold1()ฯลฯ และเพิ่มลงในplayersรายการ ทำไมฉันถึงได้ผลลัพธ์ที่แตกต่างอย่างมากมายสำหรับกลยุทธ์ที่เหมือนกัน
ngn

คำตอบ:


4

Genug ist nicht genug

(อาจถูกเรียกenough2หรือstealback)

def nicht_genug(m,t,s):
    if not s:
        s.append("c")
        return "c"
    if s[0]=="t":
        return "d"
    if m[-42:].count("d")>10 or len(t)+t.count("d")>300:
        s[0]="t"
        return "d"
    if t[-1]=="d":
        if s[0]=="d":
            s[0]="c"
            return "d"
        else:
            s[0]="d"
            return "c"
    else:
        if t[-3:].count("d")==0:
            s[0]="c"
        return "c"

ฉันได้เรียนรู้ว่าหัวนมดั้งเดิมของสอง tatsรอสองtats ติดต่อกันอย่างที่tit_for_whoopsทำและดูเหมือนว่าเราควรให้อภัยและลืม (ดีเกือบ ... ) ก่อนหน้านี้ และผู้เล่นจำนวนมากบกพร่องในรอบสุดท้าย ฉันยังชอบที่จะดีเมื่อทุกอย่างเรียบร้อยดี แต่แถบความอดทนของบอทลดลงเรื่อย ๆ


11

หัวนม-FOR-อ๊ะ

แรงบันดาลใจจากกลยุทธ์จาก ncase.me/trust

def tit_for_whoops(m, t, s):
    if len(t) < 2:
        return 'c'
    else:
        return 'd' if all([x == 'd' for x in t[-2:]]) else 'c'

ข้อบกพร่องเฉพาะในกรณีที่ผู้เล่นคนอื่นเสียไปสองครั้งติดต่อกันเพื่อป้องกันการเข้าใจผิด


ขอบคุณสำหรับการส่งของคุณ! โปรดทราบว่าเนื่องจากความน่าจะเป็นของการพลิกเฉลี่ยเฉลี่ย 1/4 จะมีการพลิกสองครั้งทุกๆ 16 การเคลื่อนไหวหรือมากกว่านั้น
isaacg

ฉันเพิ่มตัวแปรสถานะซึ่งคุณสามารถละเว้นได้หากคุณไม่ต้องการใช้
isaacg

9

เปลี่ยนใจ

def change_of_heart(m, t, s):
    return 'c' if len(t) < 180 else 'd'

มีการเปลี่ยนแปลงของหัวใจตรงไปตรงมา ทำได้ดีอย่างน่าประหลาดใจ


ขอแสดงความยินดีกับการเป็นผู้นำ / ที่สอง ฉันประทับใจและแปลกใจที่ฝ่ายตรงข้ามไม่สนใจกลยุทธ์ทำได้ดี
isaacg

9

กลยุทธ์ Stealer

แรงบันดาลใจจากเพียงพอ change_of_heart และ tit-for-whoops ควรให้อภัยมากกว่านี้อีกหน่อย ฉันพยายามที่จะปรับแต่งตัวเลขเพื่อผลลัพธ์ที่ดีที่สุด แต่พวกเขาไม่ต้องการเปลี่ยนแปลงมากนัก

def stealer(mine, theirs, state):
    if len(mine) == 0:
        state.append('c')
        return 'c'
    elif len(mine) > 250:
        return "d"
    elif state[0] == 't':
        return 'd'
    elif mine[-40:].count('d') > 10:
        state[0] = 't'
        return 'd'
    elif theirs[-1] == 'd':
        if state[0] == 'd':
            state[0] = 'c'
            return 'd'
        else:
            state[0] = 'd'
            return 'c'
    elif all([x == 'c' for x in theirs[-3:]]):
        state[0] = 'c'
        return 'c'
    else:
        return 'c'

ยินดีต้อนรับสู่ PPCG!
Giuseppe

ขอแสดงความยินดีกับการเป็นผู้นำ!
isaacg

8

หัวนม-For-Time

def tit_for_time(mine, theirs, state):
    theirs = theirs[-30:]
    no_rounds = len(theirs)
    return "c" if no_rounds < 5 or random.random() > theirs.count("d") / no_rounds else "d"

หากคุณใช้เวลาส่วนใหญ่ทำร้ายฉันฉันจะทำร้ายคุณ อาจ.


ส่งดี! ขณะนี้คุณอยู่ในอันดับที่ 1 โดยไม่มีโปรแกรมพื้นฐานที่คู่ต่อสู้รู้
isaacg

7

เติบโตไม่ไว้วางใจ

import random

def growing_distrust(mine, theirs, state):
    # Start with trust.
    if len(mine) == 0:
        state.append(dict(betrayals=0, trust=True))
        return 'c'

    state_info = state[0]

    # If we're trusting and we get betrayed, trust less.
    if state_info['trust'] and theirs[-1] == 'd':
        state_info['trust'] = False
        state_info['betrayals'] += 1

    # Forgive, but don't forget.
    if random.random() < 0.5 ** state_info['betrayals']:
        state_info['trust'] = True

    return 'c' if state_info['trust'] else 'd'

ยิ่งคู่ต่อสู้ทรยศฉันเท่าไรฉันก็ยิ่งเชื่อใจได้ว่ามันเป็นแค่เสียงรบกวน


ใช่ไม่มีสิ่งที่รัฐโชคร้าย แต่ฉันต้องการให้ส่งเป็นชุดดังนั้นนี่คือสิ่งที่ดีที่สุดที่ฉันสามารถคิด คุณมีความคิดเกี่ยวกับวิธีเพิ่มรัฐหรือไม่?
isaacg

เพียงแค่มีstateข้อโต้แย้งว่าโดยค่าเริ่มต้นเป็นรายการหรือไม่? รายการไม่แน่นอนดังนั้นรัฐจะสามารถแก้ไขได้อย่างง่ายดาย
LyricLy

งั้นเหรอ ฉันไม่เห็นว่ามันจะเป็นไปได้
LyricLy

@ ความทรงจำฉันคิดว่าฉันรู้วิธีการใช้งานนี้ ฉันจะให้มันหมุนวน
isaacg

ฉันเพิ่มตัวแปรสถานะซึ่งเป็นรายการว่างเปล่าอย่างตั้งใจและคุณสามารถแก้ไขได้
isaacg

7

Jedi2Sith

เริ่มต้นทุกสิ่งที่ดีและไม่เห็นแก่ตัว แต่เมื่อเวลาผ่านไปอิทธิพลของด้านมืดก็แข็งแกร่งขึ้นเรื่อย ๆ จนกระทั่งไม่กลับมา ไม่มีการหยุดยั้งอิทธิพลนี้ แต่สิ่งเลวร้ายทั้งหมดที่เห็นเกิดขึ้นเพียงแค่ช่วยให้เกิดพลังด้านมืด ...

def jedi2sith(me, them, the_force):
  time=len(them)
  bad_things=them.count('d')
  dark_side=(time+bad_things)/300
  if dark_side>random.random():
    return 'd'
  else:
    return 'c'

ลองออนไลน์!


6

Slider

def slider(m, t, s):
    z = [[2, 1], [0, 1], [2, 3], [2, 1]]
    x = 0
    for y in t:
      x = z[x][y == 'c']
    return 'c' if x < 2 else 'd'

เริ่มต้นด้วย 'c' และค่อย ๆ เลื่อนไปทางหรือออกจาก 'd'


ฉันได้เขียนสิ่งนี้เทียบเท่ากับการทำงานเพื่อใช้ตัวแปรสถานะเพราะมันทำงานช้ามาก อย่างไรก็ตามคุณไม่จำเป็นต้องเปลี่ยนแปลงอะไรเลย
isaacg

6

ปากแข็ง Stumbler

def stubborn_stumbler(m, t, s):
    if not t:
        s.append(dict(last_2=[], last_3=[]))
    if len(t) < 5:
        return 'c'
    else:
        # Records history to state depending if the last two and three
        # plays were equal
        s = s[0]
        if t[-2:].count(t[-1]) == 2:
            s['last_2'].append(t[-1])
        if t[-3:].count(t[-1]) == 3:
            s['last_3'].append(t[-1])
    c_freq = t.count('c')/len(t)
    # Checks if you've consistently defected against me
    opp_def_3 = s['last_3'].count('d') > s['last_3'].count('c')
    opp_def_2 = s['last_2'].count('d') > s['last_2'].count('c')
    # dist func from 0 to 1
    dist = lambda x: 1/(1+math.exp(-5*(x-0.5)))
    # You've wronged me too much
    if opp_def_3 and opp_def_2:
        return 'd'
    # Otherwise, if you're consistently co-operating, co-operate more
    # the less naive you are
    else:
        return 'c' if random.random() > dist(c_freq) - 0.5 else 'd'

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

UPDATE: ติดตามการเล่นต่อเนื่องสองบทและสามบทต่อเนื่องลงโทษภายใต้เงื่อนไขที่รุนแรงและเพิ่มตัวเลือกแบบสุ่มเมื่อไม่แน่ใจ

ปรับปรุง 2: เงื่อนไขที่ถูกลบออกและฟังก์ชั่นการกระจายเพิ่ม


ขอแสดงความยินดีกับการเขียนโปรแกรมแรกเพื่อเป็นผู้นำ!
isaacg

6

บอท

def just_noise(m,t,s):
    return 'c' if random.random() > .2 else 'd'

ฉันร่วมมือกับบอทอย่างแน่นอน นั่นเป็นเพียงเสียงรบกวน


6

พอคือพอ

def enough(m,t,s):
    if not s:
        s.append("c")
        return "c"
    if s[0]=="t":
        return "d"
    if m[-42:].count("d")>10:
        s[0]="t"
        return "d"
    if t[-1]=="d":
        if s[0]=="d":
            s[0]="c"
            return "d"
        else:
            s[0]="d"
            return "c"
    else:
        return "c"

เริ่มต้นเป็นtit สำหรับสอง tatsโดยที่ทั้งสอง tats นั้นไม่จำเป็นต้องต่อเนื่องกัน (ต่างจากtit_for_whoops) หากมีการเล่นdบ่อยเกินไปมันจะdรวม -


ขอแสดงความยินดีกับการเป็นผู้นำ!
isaacg

6

Bot ปลาทอง

def goldfish(m,t,s):
    return 'd' if 'd' in t[-3:] else 'c'

ปลาทองไม่เคยให้อภัย แต่ก็ลืมไปอย่างรวดเร็ว


6

คนโกง (คืนสถานะอีกครั้ง)

มีเพียง 10 บทละครที่ผ่านมาเท่านั้น แต่แบ่งออกเป็นสองช่วงตึกห้าช่วงซึ่งมีค่าเฉลี่ยในแต่ละประเภทที่จัดว่าดีหรือไม่ดี

หากฝ่ายตรงข้ามเล่นโดยเฉลี่ย "ดี" ผู้เล่นจะเล่นได้น้อยลงเรื่อย ๆ หากผลลัพธ์ไม่ชัดเจนนักเล่นกลก็น่าจะล่อลวงคู่ต่อสู้ให้ปลอดภัย หากฝ่ายตรงข้ามปรากฏว่ากำลังเล่น "ไม่ดี" นักเล่นกลก็จะตอบโต้

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

import random
def trickster(player,opponent,state):
    pBad = 0.75
    pNice = 0.8
    pReallyBad =0.1
    decay = 0.98
    r = random.random()
    if len(player)<20: #start off nice
        return 'c' 
    else: #now the trickery begins
        last5 = opponent[-5:].count('c')/5.0 > 0.5
        last5old = opponent[-10:-5].count('c')/5.0  > 0.5
        if last5 and last5old: #she is naive, punish her
            pBad = pBad*decay #Increase punishment
            if r<pBad:
                return 'c'
            else:
                return 'd'
        elif last5 ^ last5old: #she is changing her mind, be nice!
            if r<pNice:
                return 'c'
            else:
                return 'd'
        else: #she's ratting you out, retaliate
            pReallyBad = pReallyBad*decay #Retaliate harder
            if r<pReallyBad:
                return 'c'
            else:
                return 'd'

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


ยินดีต้อนรับสู่เว็บไซต์! น่าเสียดายที่รหัสของคุณใช้ไม่ได้ในขณะนี้ คุณมีเอลฟ์หลังจากที่อื่น คุณช่วยแก้ไขได้ไหม ขอบคุณ
isaacg

ฉันคาดเดาทุกอย่างจาก elif เป็นต้นไปควรจะเยื้องอีกครั้งหรือไม่
isaacg

ถูกต้องฉันจะเยื้อง
Hektor-Waartgard

@isaacg ฉันได้อัปเดตคำตอบของฉันด้วยรหัสใหม่ ฉันไม่มีชื่อเสียงพอที่จะบอกคุณในคำถามแสดงความคิดเห็น ฉันไม่แน่ใจว่าฉันกำลังใช้ตัวแปรสถานะอย่างถูกต้องฉันคิดว่ามันเป็นรายการที่ว่างซึ่งฉันสามารถผนวกสิ่งที่ฉันต้องการได้ถูกต้องหรือไม่
Hektor-Waartgard

2
นั่นไม่ได้ผล หลังจากเทิร์นแต่ละครั้งจะมีการตัดสินว่าการเคลื่อนไหวปัจจุบันพลิกหรือไม่ (เป็นอิสระสำหรับผู้เล่นสองคน) การตัดสินใจนั้นได้รับการแก้ไขแล้ว คุณจะเห็นการเคลื่อนไหวครั้งแรกเสมอซึ่งอาจพลิกหรือไม่ แต่มันจะไม่เปลี่ยนแปลง
Christian Sievers

5

การสลายความจำ

def decaying_memory(me, them, state):
    m = 0.95
    lt = len(them)

    if not lt:
        state.append(0.0)
        return 'c'

    # If it's the last round, there is no reason not to defect
    if lt >= 299: return 'd'

    state[0] = state[0] * m + (1.0 if them[-1] == 'c' else -1.0)

    # Use a gaussian distribution to reduce variance when opponent is more consistent
    return 'c' if lt < 5 or random.gauss(0, 0.4) < state[0] / ((1-m**lt)/(1-m)) else 'd'

มีน้ำหนักมากกว่าประวัติที่ผ่านมามากขึ้น ลืมอดีตที่ผ่านมาอย่างช้าๆ


5

สินบน

def kickback(m, t, s):
  if len(m) < 10:
    return "c"
  td = t.count("d")
  md = m.count("d")
  f = td/(len(t)+1)
  if f < 0.3:
    return "d" if td > md and random.random() < 0.1 else "c"
  return "c" if random.random() > f+2*f*f else "d"

ความคิดที่คลุมเครือ ...


ขอแสดงความยินดีกับการเป็นผู้นำในเวอร์ชั่นที่มีการลบคาถาพื้นฐานที่ปรับได้
isaacg

ขอบคุณ ฉันคิดว่ามันน่าทึ่งที่ผลลัพธ์ทั้งสองแตกต่างกัน!
Christian Sievers

4

ไม่ได้รับสิ่ง "เสียง" ทั้งหมด

def vengeful(m,t,s):
    return 'd' if 'd' in t else 'c'

อย่าให้อภัยผู้ทรยศ


4

SOUNDER:

แก้ไข: เพิ่มการตอบโต้ในสถานการณ์ที่มีเสียงรบกวนต่ำ

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

หากฝ่ายตรงข้ามของเราทำการเบี่ยงเบนความสนใจมากในเทิร์นเหล่านั้น (2 หรือมากกว่า) เราเพียงแค่ถอยกลับไปที่พวกเขา ถ้ามันเป็นเพียงแค่เสียงรบกวนก็จะส่งผลกระทบต่อการเคลื่อนไหวของเรา

ไม่อย่างนั้นถ้าเพียงแค่ 1 ข้อบกพร่องเราก็แค่ทำง่ายๆสำหรับเกมที่เหลือ

def sounder(my, their, state):
    if len(my)<4:
        if their.count("d")>1:
            return "d"
        return "c"
    elif len(my) == 4:
        if all(i == "c" for i in their):
            state.append(0)
            return "d"
        elif their.count("c") == 3:
            state.append(1)
            return "c"
        else:
            state.append(2)
    if state[0] == 2:
        return "d"
    if state[0] == 0:
        if not "d" in my[-4:]:
            return "d"
        return their[-1]
    else:
        return their[-1]

3

สลับกัน

def alternate(m, t, s):
    if(len(m)==0):
        return 'c' if random.random()>.5 else 'd'
    elif(len(m)>290):
        return 'd'
    else:
        return 'd' if m[-1]=='c' else 'c'

เลือกสุ่มในรอบแรกจากนั้นสลับ ข้อบกพร่องเสมอใน 10 รอบสุดท้าย


3

รอ 50

def wait_for_50(m, t, s):
  return 'c' if t.count('d') < 50 else 'd'

หลังจาก 50 ข้อบกพร่องมาเลยมีมัน!


ฉันแก้ไขงูหลามของคุณในขณะที่รักษาเจตนาของคุณ
isaacg

ขอแสดงความยินดีกับการย้ายไปยังอันดับ 3
isaacg

2

บางคนไร้เดียงสา

def somewhat_naive(m, t, s):
    p_flip = 0.25
    n = 10
    if len(t) < n:
        return 'c' if random.random() > p_flip else 'd'
    d_freq = t[-n:].count('d')/n
    return 'c' if d_freq < p_flip else 'd'

ฉันเพิ่งจะคิดว่าถ้าคุณเสียน้อยกว่าน่าจะพลิก ( ๆ ) ในช่วงnผลัดกันมันเป็นเสียงรบกวนและไม่ว่าคุณหมายถึงกำลัง!

ยังไม่ได้ตัวเลขที่ดีที่สุดnอาจดูเพิ่มเติมที่


2

ทุกสาม

def everyThree(me,him,s):
    if len(me) % 3 == 2:
        return "d"
    if len(me) > 250:
        return "d"
    if him[-5:].count("d")>3:
        return "d"
    else:
        return "c"

ข้อบกพร่องทุกสามรอบโดยไม่คำนึงถึง ยังมีข้อบกพร่องในรอบ 50 ครั้งสุดท้าย ถ้าฝ่ายตรงข้ามของเขาเสีย 4 จาก 5 ในรอบสุดท้ายด้วย


2

บุ้งกี๋

def buckets(m, t, s):
    if len(m) <= 5:
        return 'c'
    if len(m) >= 250:
        return 'd'
    d_pct = t[-20:].count('d')/len(t[-20:])
    if random.random() > (2 * d_pct - 0.5):
        return 'c'
    else:
        return 'd'

เล่นได้ดีเพื่อเริ่มต้น ดู 20 ครั้งสุดท้ายหาก <25% d, ส่งคืน c,> 75% d, ส่งคืน d และระหว่างเลือกสุ่มตามฟังก์ชันความน่าจะเป็นเชิงเส้น ล่าสุด 50 ข้อบกพร่อง มีสิ่งนี้เมื่อ 10 ปีที่แล้ว แต่มีข้อบกพร่อง 50 รายการสุดท้าย

ครั้งแรกที่นี่เพื่อแจ้งให้เราทราบหากมีสิ่งใดที่ต้องแก้ไข (หรือฉันจะทดสอบสิ่งนี้ได้อย่างไร)


หากคุณต้องการทดสอบสิ่งต่าง ๆ ในพื้นที่คุณสามารถโคลนที่เก็บและเรียกใช้ noisy-game.py ใช้เวลาสักครู่ดังนั้นคุณอาจต้องการลบคู่แข่งบางคนplayersเพื่อทำซ้ำอย่างรวดเร็ว
isaacg

ขอบคุณ Isaac - ฉันจะต้องเล่นกับมันและทำการแก้ไขบางอย่าง
brian_t

1

หัวนม-FOR-Stat

มีข้อบกพร่องหากฝ่ายตรงข้ามเสียเวลามากกว่าครึ่ง

def tit_for_stat(m, t, s):
  if t.count('d') * 2 > len(m):
    return 'd'
  else:
    return 'c'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.