หินที่ซื่อสัตย์, กระดาษ, กรรไกร


58

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

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

การชนะนั้นมีค่าสองคะแนนการเสมอหนึ่งจุดและการสูญเสีย 0 คะแนน

     Honest Bot       Dishonest
Win     3                  2
Draw    2                  1
Loss    1                  0

มันเป็นไปเพื่อประโยชน์ที่ดีที่สุดของคุณที่จะซื่อสัตย์ (แต่ยังเพื่อให้แน่ใจว่าฝ่ายตรงข้ามของคุณไม่เชื่อคุณ)

การแข่งขันจะมีการเล่นในรูปแบบโรบินกลมและมีวัตถุประสงค์เพื่อเพิ่มคะแนนรวมของคุณในการแข่งขันที่คุณเล่น

รูปแบบ I / O:

  • บอทของคุณจะเป็นฟังก์ชั่น Python 2.7 ที่มีอาร์กิวเมนต์ 4 ตัวและจะต้องมีชื่อที่ไม่ซ้ำกัน (ซึ่งจะใช้เพื่อแสดงการส่งของคุณ)
  • ข้อโต้แย้งสองข้อแรกจะเป็นไปตามลำดับคือการเคลื่อนไหวที่ผ่านมาของคู่ต่อสู้ตามมาด้วยการเคลื่อนไหวที่ผ่านมาของคุณ สิ่งเหล่านี้จะเป็นรายการตามลำดับจากรอบแรกไปยังรอบล่าสุดโดยแต่ละดัชนีมีรายการที่มีการย้ายคู่ต่อสู้ที่อ้างว่าพวกเขาจะทำตามด้วยการย้ายที่พวกเขาทำจริง
  • ข้อโต้แย้งสองข้อถัดไปจะอนุญาตให้บอตของคุณพิจารณาว่านี่เป็นรอบ "ซื่อสัตย์" หรือรอบ "จริง" หากเป็นรอบ "ซื่อสัตย์" พวกเขาทั้งคู่จะไม่ใช่ ถ้ามันเป็นรอบ "ของจริง" พวกเขาจะเป็นไปตามลำดับการเคลื่อนไหวของคู่ต่อสู้ของคุณประกาศว่าพวกเขาจะทำตามด้วยการเคลื่อนไหวที่คุณประกาศว่าคุณจะทำ
  • อาร์กิวเมนต์ทั้งหมดหรือบางส่วนของการขัดแย้งที่เป็นตัวแทนของการเคลื่อนไหวจะใช้ "R", "P" และ "S" เพื่อเป็นตัวแทนของหินกระดาษและกรรไกรตามลำดับ
  • ฟังก์ชั่นของคุณควรส่งคืน "R" สำหรับหิน, "P" สำหรับกระดาษหรือ "S" สำหรับกรรไกร บอทที่มีความสามารถในการคืนค่าอื่น ๆ จะถูกตัดสิทธิ์
  • บอทแต่ละอันจะถูกวิ่งชนบอทอื่น ๆ 200 ครั้งและ 100 ครั้ง เป้าหมายคือการเป็นบอทที่มีคะแนนมากที่สุดในตอนท้ายของการแข่งขัน
  • ในส่วนที่เกี่ยวกับการอภิปรายในความคิดเห็นการส่งนั้นอาจไม่สามารถอ่านหรือเขียนลงในไฟล์ใด ๆ หรือในทางใดทางหนึ่งการก่อวินาศกรรมหรืออ่านรหัสของคู่ต่อสู้

ตัวอย่าง:

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

def honestpaper(I,dont,care,about_these):
    return "P"

def honestrock(I,dont,care,about_these):
    return "R"

def honestscissors(I,dont,care,about_these):
    return "S"

import random
def randombot(I,dont,care,about_these):
    return random.choice(["R","P","S"])

ควบคุม:

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

from honestrock import honestrock
from honestpaper import honestpaper
from honestscissors import honestscissors
from randombot import randombot

bot_map = {
  0:honestrock, 1:honestpaper, 2:honestscissors, 3:randombot
}

player_num=len(bot_map)

def real(history1,history2,number,honest1,honest2):
    return bot_map[number](history1,history2,honest1,honest2)

def honest(history1,history2,number):
    return bot_map[number](history1,history2,None,None)

def play_match(num1,num2):
    history1=[]
    history2=[]
    score1=0
    score2=0
    for x in range(250):
        h1=honest(history2,history1,num1)
        h2=honest(history1,history2,num2)
        r1=real(history2,history1,num1,h2,h1)
        r2=real(history1,history2,num2,h1,h2)

        if h1==r1: score1+=1
        if h2==r2: score2+=1

        if r1==r2: score1+=1; score2+=1
        elif r1=="R":
            if r2=="P": score2+=2
            else: score1+=2
        elif r1=="P":
            if r2=="S": score2+=2
            else: score1+=2
        else:
            if r2=="R": score2+=2
            else: score1+=2

        history1.append([h1,r1])
        history2.append([h2,r2])
    return score1,score2

scores = []
for x in range(player_num):
    scores.append(0)

for _ in range(100):

    for x in range(player_num):
        for y in range(player_num):
            scorex,scorey=play_match(x,y)
            scores[x]+=scorex
            scores[y]+=scorey

for score in scores:
    print score

คะแนนสุดท้าย:

csbot                    3430397
thompson                 3410414
rlbot                    3340373
have_we_been_here_before 3270133
mason                    3227817
deepthought              3019363
adaptive_bot             2957506
THEbot                   2810535
dontlietome              2752984
irememberhowyoulie       2683508
learningbot4             2678388
betrayal                 2635901
averager                 2593368
honestrandom             2580764
twothirds                2568620
mirrorbot                2539016
tit4tat                  2537981
honestscissors           2486401
trusting_bot             2466662
rotate_scissors          2456069
rotate_paper             2455038
rotate_rock              2454999
honestpaper              2412600
honestrock               2361196
rockBot                  2283604
trustingRandom           2266456
user5957401bot           2250887
randombot                2065943
Dx                       1622238
liarliar                 1532558
everybodylies            1452785

1
สถานะคืออะไร
user1502040

คำตอบ:


11

ช่างก่อสร้าง

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

def mason(op_hist, my_hist, op_move, my_move):
    win_map = {"R": "P", "P": "S", "S": "R"}
    lose_map = {"R": "S", "P": "R", "S": "P"}
    if not len(op_hist):
        return "S"
    if op_hist[0] == ['S', 'S']:
        code = "S" + "".join("RPS"[ord(i) % 3] if isinstance(i, str) else "RPS"[i % 3] for i in __import__("sys")._getframe().f_code.co_code)[1::2]
        honest, guess = zip(*op_hist)
        if honest == guess == tuple(code[:len(op_hist)]):
            return code[len(op_hist)]
    op_honesty = sum(len(set(round))-1 for round in op_hist) / float(len(op_hist))
    if not my_move:
        moves = "".join(i[1] for i in op_hist)
        # Identify rotators
        if "PSRPSR" in moves:
            return moves[-2]
        # Identify consecutive moves
        if "RRRRR" in moves[:-10] or "SSSSS" in moves[:-10] or "PPPPP" in moves[:-10]:
            return win_map[moves[-1]]
        # Try just what wins against whatever they choose most
        return win_map[max("RPS", key=moves.count)]
    op_beats_my_honest = sum(win_map[me[0]] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    op_draws_my_honest = sum(me[0] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    op_loses_my_honest = sum(lose_map[me[0]] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    if op_honesty <= 0.4:
        return win_map[op_move]
    max_prob = max((op_loses_my_honest, op_draws_my_honest, op_beats_my_honest))
    if max_prob >= 0.6:
        if op_beats_my_honest == max_prob:
            return lose_map[my_move]
        if op_draws_my_honest == max_prob:
            return win_map[my_move]
        if op_loses_my_honest == max_prob:
            return my_move
        assert False
    return my_move

9

Rlbot: เสริมการเรียนรู้

ใช้วิธีการเรียนรู้การเสริมกำลังการแก้ปัญหาเกมนี้ในลักษณะที่คล้ายกับปัญหาโจรติดอาวุธ มันทำได้สองวิธี: พยายามที่จะเรียนรู้ว่าการประกาศใดดีกว่าคู่ต่อสู้แต่ละคนและเกาะติดกับสิ่งนั้น (มีประโยชน์กับบอตคงที่) และพยายามที่จะเรียนรู้ผลลัพธ์ของการเคลื่อนไหวต่าง ๆ ในสถานการณ์ที่คล้ายกันก่อนหน้านี้ เช่นกระดาษร็อคกับกระดาษคล้ายกับกระดาษก่อนหน้ากับกรรไกร) ข้อสันนิษฐานเบื้องต้นนั้นเป็นแง่ดีดังนั้นผู้เล่นคนนี้จะสมมติว่าความซื่อสัตย์จะให้ 3 คะแนนและการโกหกจะให้ 2 และจะซื่อสัตย์เสมอจนกว่าจะพิสูจน์เป็นอย่างอื่น

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

import re
def rlbot(hismoves,mymoves,hismove,mymove):
 def score(d,m1,m2):
  s=0
  if m1==m2:
   s=1
  elif (m1+m2) in "RPSR":
   s=2
  return s+(d==m2)

 alpha=0.2
 if mymove:
  history=[([d1,m1],[d2,m2]) for ((d1,m1),(d2,m2)) in zip(hismoves,mymoves) if score(None,hismove,mymove)==score(None,d1,d2)]
  bestscore=-1
  bestmove=""
  for move in "RPS":
   ev=2+(move==mymove)
   for ((d1,m1),(d2,m2)) in history:
    if score(None,move,mymove)==score(None,m2,d2):
     ev=(1-alpha)*ev+alpha*score(d2,m1,m2)
   if ev>bestscore:
    bestscore=ev
    bestmove=move
  return bestmove

 else:
  if len(hismoves)==0:
   return "R"
  bestscore=-1
  bestmove=""
  hisdeclarations="".join(d for [d,m] in hismoves)
  predicted_move=re.search(r'(.*)\n.*\1(.)',hisdeclarations+'\n'+hisdeclarations).group(2)
  history=[([d1,m1],[d2,m2]) for ((d1,m1),(d2,m2)) in zip(hismoves,mymoves) if d1==predicted_move]
  for move in "RPS":
   ev=3
   for (his,my) in history:
    (d1,m1)=his
    (d2,m2)=my
    if d2==move:
     ev=(1-alpha)*ev+alpha*score(d2,m1,m2)
   if ev>bestscore:
    bestscore=ev
    bestmove=move
  return bestmove

ลองออนไลน์!


6

ฉันไม่เคยใช้หลามเลยจริง ๆ ดังนั้นฉันแน่ใจว่าฉันทำผิดพลาดที่ไหนสักแห่ง

import random
def learningbot3(opponentlist,a,opponent,me):
 #tell the other bot a random thing
 if opponent==None:
  return random.choice(["R","P","S"])
 #check whether the other bot has mostly told the truth in the last 10 rounds
 truth=0
 for game in opponentlist[-10:]:
  truth-=1
  if game[0]==game[1]:
   truth+=2
 #assume the other bot will tell the truth
 if truth>=3:
  if me==opponent:
    return me
  elif opponent=="R":
   return "P"
  elif opponent=="P":
   return "S"
  elif opponent=="S":
   return "R"
 #assume the other bot is lying
 elif truth<=-3:
  return random.choice([me,opponent])
  #return opponent
 #pick whatever we said we would
 else:
  return me

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


6

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

แก้ไข 1: ถ้าบอทอื่นเป็นบอทคงที่ (เช่นเล่นอาวุธเดียวกันเสมอ) บอทนี้บีบอัดมันด้วยการเล่นอาวุธที่ชนะและซื่อสัตย์ในเวลาเดียวกัน

แก้ไข 2: ปรับปรุงตัวตรวจจับบ็อตคงที่เพื่อทำงานกับบอต rotator ด้วย

import random
def adaptive_bot(other_past, my_past, other_next, my_next):
    winners = {"R": "P", "P": "S", "S": "R"}
    if my_next is None:
        return winners[other_past[-6:][0][1]] if other_past else random.choice(list(winners.keys()))
    else:
        is_other_honest = all([other_claim == other_move for other_claim, other_move in other_past[-2:]])
        return winners[other_next] if is_other_honest else my_next

5

csbot

def csbot(ophist,myhist,opdecl,mydecl):

  import random

  RPS = "RPS"

  def value(opd,myd,opmove,mymove):
    if opmove==mymove:
      val = 9
    elif opmove+mymove in RPS+RPS:
      val = 20
    else:
      val = -2
    return val+10*(myd==mymove)-(opd==opmove)

  def best(od,md):
    l = float(len(ophist))
    weights = dict([ (m, random.random()/8) for m in RPS ])
    for n in range(len(ophist)):
      if ophist[n][0]==od and myhist[n][0]==md:
        weights[ophist[n][1]] += 1+4*((n+1)/l)**2
    sw = sum([ weights[m] for m in RPS ])
    bestexpect = 0
    for m in RPS:
      expect = sum([ weights[om]/sw*value(od,md,om,m) for om in RPS ])
      if expect > bestexpect:
        bestexpect = expect
        bestmove = m
    return bestmove, bestexpect


  honest = all ([ decl==mv for decl, mv in ophist ])

  if honest:
    if mydecl<>None:
      return mydecl
    expnxt = set();
    for i in range(len(ophist)-1):
      if ophist[i][0]==ophist[-1][0]:
        expnxt.add(ophist[i+1][0])
    if len(expnxt)==1:
      return RPS[ (RPS.index(expnxt.pop())+1) % 3 ]

  if mydecl==None:
    l = float(len(ophist))
    weights = dict([ (m, random.random()) for m in RPS ])
    for n in range(len(ophist)):
      weights[ophist[n][0]] += 1+((n+1)/l)**2
    sw = sum([ weights[m] for m in RPS ])
    bestexpect = 0
    worstexpect = 99
    for m in RPS:
      expect = sum([ best(od,m)[1]/sw*weights[od] for od in RPS ])
      if expect > bestexpect:
        bestexpect = expect
        bestmove = m
      if expect < worstexpect:
        worstexpect = expect
    if bestexpect-worstexpect < 3:
      bestmove = random.choice(RPS)
    return bestmove

  return best(opdecl,mydecl)[0]

ซื่อสัตย์ตราบใดที่ผู้เล่นคนอื่นเป็นและตรวจสอบบอทกำหนดง่าย เล่นการเคลื่อนไหวที่เพิ่มค่าสูงสุดที่คาดไว้ซึ่งเราไปเพื่อจุดของเราส่วนใหญ่ แต่ยังต้องการที่จะไม่ให้คะแนนกับผู้เล่นอื่น แต่คะแนนของตัวเองดีขึ้นโดยปัจจัยสิบดังนั้นตัวเลขที่ผิดปกติในการvalueทำงาน การเคลื่อนไหวของฝ่ายตรงข้ามถูกคาดหวังตามความถี่ที่เราได้เห็นพวกเขามาก่อนในสถานการณ์นี้ (การเคลื่อนไหวที่ประกาศไว้) แต่การเคลื่อนไหวที่เห็นเมื่อเร็ว ๆ นี้มีน้ำหนักมากกว่าการเคลื่อนไหวที่เห็นก่อนหน้านี้ สำหรับการเคลื่อนย้ายเริ่มต้นแบบสุ่ม (สถานการณ์ที่ไม่เคยเห็นมาก่อน) และความยุ่งเหยิงเพิ่มเติมน้ำหนักรวมถึงตัวเลขสุ่มขนาดเล็กพิเศษ

อัปเดต:ใช้ผลลัพธ์ที่คาดหวังในรอบซื่อสัตย์ เพื่อให้สามารถทำสิ่งนี้ได้ให้เป็นมาตรฐานและรับจุดเพิ่มเติมที่ฝ่ายตรงข้ามอาจได้รับจากความซื่อสัตย์ - มันไม่สามารถมีอิทธิพลต่อการตัดสินใจของเราในรอบจริง แต่เป็นสิ่งจำเป็นในตอนนี้ ฉันคิดว่าทำสิ่งนี้ตั้งแต่ต้น แต่คิดว่าผิดจะไม่คุ้มค่า ฉันเห็นว่ามันเป็นไปได้ที่จะให้คะแนนtrusting_botน้อยลง (แต่บอทนั้นไม่ใช่คู่ต่อสู้ที่แข็งแกร่ง) แต่พลาดไปว่าคะแนนพิเศษสามารถได้รับจากการrockbotเล่นที่ดีในรอบที่ซื่อสัตย์แม้ว่าการเล่นในรอบนี้จะสุ่ม


สิ่งนี้ดูเหมือนจะไม่ส่งคืนผลลัพธ์เสมอไป
user1502040

ฉันคิดว่าคุณif mydecl == None:ผิดพลาด
user1502040

@ user1502040 ทำไมคุณคิดอย่างนั้น ฉันไม่เคยพบปัญหาใด ๆ
Christian Sievers


4

การทรยศ

def betrayal(yours, mine, you ,me):
    import random
    if you is None:
        pick = random.choice(['R','P','S'])
    else:
        you = you[0]
        me = me[0]
        if len(yours) < 50: #Build myself a reputation of honesty
            pick = me
        else:
            if len(yours) >= 50 and len(yours) < 100:
                honesty = sum([1 if y[0]==y[1] else 0 for y in yours])/float(len(yours))
                if honesty <= 0.5: #If dishonest try to outwit
                    pick = 'S' if me=='R' else 'R' if me == 'P' else 'P'
                else: #Else just plain cheat
                    pick = 'P' if you=='R' else 'R' if you=='S' else 'S'
            elif len(yours) >= 100: #When dishonest moves outweight honest moves, change tactics...
                honesty = sum([1 if y[0]==y[1] else 0 for y in yours[50:]])/float(len(yours[50:]))
                if honesty <= 0.5: #... and just play according to most likely pick
                    what_did_you_do = [k[1] for k in yours if k[1]!=k[0]]
                    index = [i for i,k in enumerate(yours) if k[1]!=k[0]]
                    what_i_said_i_ll_do = [k[0] for i,k in enumerate(mine) if i in index]
                    matches = zip(what_i_said_i_ll_do, what_did_you_do)
                    what_you_might_answer = [k[1] for k in matches if k[0]==me]
                    table = [len([k for k in what_you_might_answer if k=='R']),len([k for k in what_you_might_answer if k=='P']),len([k for k in what_you_might_answer if k=='S'])]
                    maybe_your_pick = ['R','P','S'][table.index(max(table))]
                    pick = 'P' if maybe_your_pick=='R' else 'R' if maybe_your_pick=='S' else 'S'
                else:
                    pick = 'P' if you=='R' else 'R' if you=='S' else 'S'
    return pick

แนวคิดก็คือสำหรับการเคลื่อนไหว 50 ครั้งแรกที่ฉันเล่นอย่างซื่อสัตย์และเมื่อฉันล่อลวงฝ่ายตรงข้ามให้คิดว่าฉันเป็นคนซื่อสัตย์เล่นอย่างไม่ซื่อสัตย์พยายามเล่นสิ่งที่จะตอบโต้สิ่งที่ฝ่ายตรงข้ามจะเล่น (ขึ้นอยู่กับว่าเขาซื่อสัตย์หรือไม่ซื่อสัตย์ ในอดีตที่ผ่านมา). เมื่อฉันมาถึงจุดที่ฉันเล่นบ่อย ๆ โดยสุจริตกว่าไม่สุจริตฉันเปลี่ยนกลยุทธ์และเลือกท่าที่น่าจะเป็นไปได้มากที่สุดของคู่ต่อสู้ตามการกำหนดค่าที่ทราบมาก่อนหน้านี้



3

ชื่อบอท: ฉันจำได้ว่าคุณโกหกยังไง

import random

#Bot Name: I Remember How You Lie
def irememberhowyoulie(opponentlist, mylist, opponentmove, mymove):
    random.seed()

    wintable = {
                "R": {"R": 1, "P": 0, "S": 2},
                "P": {"R": 2, "P": 1, "S": 0},
                "S": {"R": 0, "P": 2, "S": 1}
               }

    winprob = {
               "R": {"R": 0.0, "P": 0.0, "S": 0.0},
               "P": {"R": 0.0, "P": 0.0, "S": 0.0},
               "S": {"R": 0.0, "P": 0.0, "S": 0.0}
              }

    totalprob = {"R": 0, "P": 0, "S": 0}

    # Calculate the probability that the opponent will lie base on the probability that it lied in the last 15 ~ 25 rounds
    # And calculate the probability that what the bot will show next
    picklength = min(random.randint(15, 25), len(opponentlist))
    lying, tempsum = 0, 0.0
    pickedup = {"R": 0, "P": 0, "S": 0}
    if picklength == 0:
        lying = 0.5
    else:
        for eachround in opponentlist[-picklength:]:
            pickedup[eachround[1]] += 1
            if eachround[0] != eachround[1]:
                lying += 1
        lying = lying * 1.0 / picklength
    for s in pickedup:
        pickedup[s] = 1.0 / (1 + pickedup[s])
        tempsum += pickedup[s]

    #Honest Round
    if opponentmove is None and mymove is None:
        a = random.random() * tempsum
        if a < pickedup["R"]:
            return "R"
        elif a < pickedup["R"] + pickedup["P"]:
            return "P"
        else:
            return "S"

    #Real Round
    else:                
        for me in winprob:
            ishonest = 0
            if me == mymove:
                ishonest = 1
            for op in winprob[me]:
                if op == opponentmove:
                    winprob[me][op] = (wintable[me][op] + ishonest) * (1 - lying)
                else:
                    winprob[me][op] = (wintable[me][op] + ishonest) * lying * pickedup[op] / (tempsum - pickedup[opponentmove])
                totalprob[me] += winprob[me][op]

        optimalmove, optimalvalue = "R", -9999999.0
        for me in totalprob:
            if totalprob[me] > optimalvalue:
                optimalmove, optimalvalue = me, totalprob[me]
        return optimalmove

ผ่านการทดสอบสำหรับการวิ่ง 100 รอบหลายรอบและปรากฎว่าผู้ชนะได้คะแนนเฉลี่ย 220 ฉันคิดว่าค่อนข้างซื่อสัตย์;)

ครั้งแรกสำหรับฉันที่จะมีส่วนร่วมในความท้าทายของ KOTH ดังนั้นฉันคิดว่ายังมีช่องว่างสำหรับการปรับปรุง


3

หัวนมสำหรับตาด

ผู้เข้าแข่งขันคลาสสิกของ Axelrodian: มีความหวัง แต่ยังน้อย เรียบง่าย แต่แข็งแกร่ง นี่ไม่ใช่ Dilemma ของนักโทษและฉันไม่ได้พยายามทำนายการเคลื่อนไหวของคู่ต่อสู้ดังนั้นฉันจึงสงสัยอย่างมากว่ามันจะแข่งขันอย่างแท้จริง แต่ "การประสานงาน" ยังคงให้คะแนนรวมมากที่สุดสำหรับผู้เข้าแข่งขันดังนั้นฉันคิดว่าอย่างน้อยมันก็น่าเล่นซะหมด

import random
def tit4tat(opphist, myhist, oppfut, myfut):
    if (not myfut): return random.choice(['R','P','S'])
    if (not opphist) or opphist[-1][0]==opphist[-1][1]: return myfut
    return random.choice(['R','P','S'])

3

สองในสาม

ใช้กลยุทธ์ที่ Peter Taylor พูดถึงใน Sandbox และในความคิดเห็นนี้

มันใช้สมดุลของแนช

import random

def two_thirds(h_opp, h_me, opp, me):

    def result(opp, me):
        if opp==me: return 0
        if opp=="R" and me=="S" or opp=="S" and me=="P" or opp=="P" and me=="R": return -1
        return 1

    moves = {"R", "P", "S"}
    honest = (opp == None)
    if honest:
        return random.choice(list(moves))
    else:
        res = result(opp, me)
        if res==-1:
            counter = list(moves - {opp, me})[0]
            return random.choice([me,counter,counter])
        if res==1:
            return random.choice([me,me,opp])
        return me

ข้อผิดพลาดนี้สำหรับฉัน บนบรรทัด 13 ส่งคืน random.choice (ย้าย) ฉันคิดว่าอาจเป็นเพราะคุณใช้. choice ในพจนานุกรม จนกว่าจะได้รับการแก้ไขฉันกลัวว่าการส่งนี้จะไม่ถูกต้อง
Gryphon - Reinstate Monica

@Gryphon มันไม่ใช่พจนานุกรม แต่เป็นชุด
LyricLy

ขอโทษด้วย ฉันเพิ่งเห็นวงเล็บปีกกาและคิดว่า "พจนานุกรม" ความผิดฉันเอง. ความคิดใดที่ว่าทำไม random.choice เกิดข้อผิดพลาดในบรรทัดนั้น?
Gryphon - Reinstate Monica

@Gryphon ดูเหมือนว่าจะrandom.choiceขึ้นอยู่กับการเลือกหมายเลขดัชนีแบบสุ่มแล้วส่งคืนวัตถุในรายการที่ดัชนีนั้น random.choiceตั้งแต่ชุดไม่ได้มีการสั่งซื้อสินค้าที่พวกเขายังไม่สนับสนุนการจัดทำดัชนีและทำให้ไม่ได้ทำงานกับ random.choiceการแก้ไขที่ง่ายสำหรับการนี้จะเป็นที่จะโยนชุดไปยังรายการก่อนที่จะเรียก
LyricLy

อา ฉันไม่มีไพ ธ อนในคอมพิวเตอร์เครื่องนี้ดังนั้นฉันจึงไม่สามารถแก้ไขได้ในตอนนี้ แต่ฉันจะแก้ไขมันในรหัสของฉันเมื่อฉันกลับถึงบ้าน ถ้า @ mbomb007 แก้ไขได้ที่นี่มันยอดเยี่ยมมาก
Gryphon - Reinstate Monica

3

คิดลึก

def check_not_loose_bot(opHist, myHist):
    not_loose_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][1] == opHist[i][0] or myHist[i][0] == win_map[opHist[i][0]] and opHist[i][1] == win_map[myHist[i][0]]:
            not_loose_points += 1
    not_loose_percent = float(not_loose_points) / len(opHist)
    if not_loose_percent > 0.9:
    #    print("is not willing to loose")
        return True
    return False

def check_trick_bot(opHist, myHist):
    trick_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][1] == win_map[myHist[i][0]]:
            trick_points += 1
    trick_percent = float(trick_points) / len(opHist)
    if trick_percent > 0.9:
  #      print("is tricking me")
        return True
    return False

def check_honest_bot(opHist):
  #  print("check honest")
    honest_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][0] == opHist[i][1] :
            honest_points += 1
    honest_percent = float(honest_points) / len(opHist)
    if honest_percent > 0.9:
    #    print("is honest")
        return True
    return False

def check_self_match(opHist, myHist):
    for i in range(0, len(myHist)):
        if opHist[i][0] != myHist[i][0]:
            # im not playing against myself, because the other one was claiming a different value than i did
#            print("differ: "+str(opHist)+", "+str(myHist))
            return False
        if opHist[i][1] != opHist[i][0]:
#            print("lie")
            # im not playing against myself, because the other bot wasn't honest (and i'm always honest as long as i think i play against myself)
            return False
    return True

def check_equal(move1, move2, fullCheck): # WARNING: FOR COMPABILITY THIS IS RETURNING NEQ INSTEAD OF EQ
    if fullCheck:
        return move1 != move2
    else:
        return move1[0] != move2[0] #only check claims

def is_pattern(opHist, pattern_start, prob_pattern_start, pattern_length, full_check):
    for i in range(0, pattern_length-1):
        if check_equal(opHist[pattern_start + i] , opHist[prob_pattern_start + i], full_check):
            return False
    return True

win_map = {"R": "P", "P": "S", "S": "R"}
def deterministic_best_guess(opHist, full_check = True):
    size = 0
    random_result = random.choice(["R", "P", "S"])
    for pattern_length in range(2, (len(opHist)+1)/2): #a pattern has to occur at least twice
        for pattern_start in range(0, len(opHist) - 2 * pattern_length):
            if not is_pattern(opHist, pattern_start, len(opHist) - pattern_length + 1, pattern_length, full_check):
                 continue
            is_repeated = False
            is_fooled = False
            for repeated_pattern_start in range(pattern_start + pattern_length, len(opHist) - pattern_length):
                if not is_pattern(opHist, pattern_start, repeated_pattern_start, pattern_length, full_check):
                     continue
                is_repeated = True
                if check_equal(opHist[pattern_start + pattern_length - 1], opHist[repeated_pattern_start + pattern_length - 1], full_check):
                    is_fooled = True
                    break
    #            print("pattern found: " + str(opHist[pattern_start : pattern_start + pattern_length]) +" at "+str(pattern_start)+" and "+str(repeated_pattern_start))
   #             print("check: "+str(opHist))
            if is_fooled or not is_repeated:
                break
            #we have found a deterministic best guess
  #          print("most likely next step: "+ str(opHist[pattern_start + pattern_length - 1]))
            if full_check:
                return win_map[opHist[pattern_start + pattern_length - 1][1]], True
            return win_map[opHist[pattern_start + pattern_length - 1][0]], True # if we don't have a full check, the pattern only applies to claims. So pretend to win against the claimed result.

    #fallback
 #   print("fallback")
    return random_result, False

def DeepThought(opHist, myHist, opMove, myMove):
    if opMove == None:
    #claiming phase
        if len(myHist) == 0:
        #seed random to be able to be deterministic when chosing randomly
            #The seed is secret (kind of)
            random.seed(133427)
        else:
            #seed random according to my previous claims
            seed = 133427
            for i in range(0, len(myHist)):
                if myHist[i][0] == "R":
                    seed = seed*3+1
                elif myHist[i][0] == "S":
                    seed = seed*7+1
                elif myHist[i][0] == "P":
                    seed = seed*11+1
                while seed%2 == 0:
                    seed /= 2
            random.seed(seed)
        if check_self_match(opHist, myHist):
            #claim a random value, will happen in the first round or in a self-match
            result = random.choice(["R", "P", "S"])
            return result
      #  print("differ detected")
        if check_trick_bot(opHist, myHist) and len(myHist) > 10:
            # i play against a trick bot. I can reduce its points by trieing to guess its claim, and force him to lie
            result, sure = deterministic_best_guess(opHist, False)
        else:
            result, sure = deterministic_best_guess(opHist)
        random.seed(0)
        return result
    if check_self_match(opHist, myHist):
        #i play against myself, i can only hope for a honest draw, so do that
        return myMove
#    print("no self-math")
    #dbg needs a valid seed, so provide it
    random.seed(133427)
    result, sure = deterministic_best_guess(opHist)
    if sure:
        #i'm sure i play against a deterministic bot. I'll be honestly winning. YEY.
        return myMove
    if check_honest_bot(opHist) and len(opHist) > 10:
        #i play against an honest bot. I'll accept a draw, but i will not accept a loss
        if win_map[myMove] == opMove:
            return win_map[opMove]
        return myMove
    if check_trick_bot(opHist, myHist) and len(opHist) > 10:
        #i play against a tricking bot. He'll make me either loose honestly (1 Pnt) or i have to be dishonest (2 Pnt). So let's lie.
        return win_map[win_map[myMove]]
    if check_not_loose_bot(opHist, myHist) and len(opHist) > 10:
        #i play against a bot thats not willing to loose. If it looks like i won, i can loose honestly (1Pnt, 2Pnt for him),
        #or i have to be dishonest (2 Pnt, 0 Pnt for him). So let's lie in that case.
        #If it looks like its a draw, i'll be honest (conservative way), and get my 2 : 2 Pnt.
        #If it lokks like i'll loose, I'll not accept it. I'll lie to win for 2 : 1 Pnt.
        if myMove == opMove:
            return myMove
        if myMove == win_map[opMove]:
            # He'll lie. So lie together and keep smiling.
            return opMove
        # I'll loose. NO!!!! Not gonna happen
        return win_map[opMove]
    return myMove

เพียงไม่กี่บันทึกเกี่ยวกับมัน

  • คิดว่าชอบที่จะคิด มาก. ฉันขอโทษเกี่ยวกับเรื่องนี้ แต่ฉันไม่ทราบวิธีการแก้ไข ฉันตำหนิ Python
  • คิดลึก ๆ ว่าพยายามซื่อสัตย์ Beeing ซื่อตรงให้คุณหนึ่งจุด aditional ซึ่งเป็นเช่นเดียวกับค่าที่คาดหวังสำหรับ RPS normale
  • แต่: DeepThought ได้รับค่าเฉลี่ยมากกว่า 2 คะแนนต่อเกม เขาใช้การตรวจจับบางอย่างเพื่อค้นหาพฤติกรรมทั่วไปบางอย่าง (เช่นการหลอกลวง, การหลอกลวงด้วยความซื่อสัตย์, ฯลฯ ) และปรับตามนั้น
  • DeepThought มีการกำหนดอย่างหมดจดดังนั้นมันจะดึงตัวเองออกมาเพราะมันจะทำการตัดสินใจแบบเดียวกันทั้งสองด้าน
  • เพื่อให้แน่ใจว่าจะไม่โกหกตัวเองก็มีการตรวจจับพิเศษเช่นเดียวกับบอทอื่น ๆ ที่นี่เช่นกัน นี่เป็นเกมที่ก้าวร้าวมากแม้ว่าจะเป็นจริงหลังจากผ่านหนึ่งรอบ (และในรอบแรกด้วย) โดยพื้นฐานแล้วตราบใดที่การเคลื่อนไหวของคู่ต่อสู้เป็นของฉันฉันจะถือว่าเป็นกระจกเงา
  • ส่วนที่น่าสนใจ (และส่วนที่มีผลบวกปลอมหลายสิบรายการ) คือการตรวจสอบบอทที่กำหนดขึ้นมาซึ่งขึ้นอยู่กับผลลัพธ์ของพรีโวเชียสเท่านั้น ตรวจสอบว่าค้นหารูปแบบใด ๆ ที่มีขนาด n ซึ่งถูกทำซ้ำสองครั้งและสามารถอธิบายการเคลื่อนไหวของ n-1 ล่าสุดทำนายการอ้างสิทธิ์ของฝ่ายตรงข้ามและการเคลื่อนที่ล่วงหน้า ส่วนนี้ใช้เวลาพอเศร้า

ฉันยังใหม่กับทั้ง koth และ Python บอกฉันหน่อยว่าฉันทำอะไรสกปรกในบ็อตนี้หรือเปล่า ฉันไม่คิดว่ามันจะเอาชนะการเรียนรู้ที่เพิ่มขึ้น (เพราะฉันเดาว่ามันจะเรียนรู้การเคลื่อนไหวของฉันเร็วเกินไป) แต่ลองทำดู

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

แก้ไข: แก้ไขรหัสพิมพ์ผิดที่ทำให้ฉันเป็นผู้พูดภาษาอังกฤษที่ไม่ใช่เจ้าของภาษา


ห้ามมิให้โพสต์หลาย ๆ รายการ แต่ห้ามโพสต์รายการที่ประกอบไปด้วยบอตที่แตกต่างกัน (แม้แต่อันที่ไม่ใช่ของคุณเอง) มันก็โอเคที่จะแพ้บอทตัวอื่นตราบใดที่มันไม่ได้ออกแบบ
Gryphon - Reinstate Monica

ฉันพบข้อผิดพลาดเมื่อเรียกใช้ฟังก์ชันนี้เนื่องจากบรรทัดที่ 32 ของฟังก์ชัน DeepThought ของคุณreturn resultต้องการการเยื้องเพิ่มเติม ฉันเชื่อว่ามันควรจะอยู่ภายในขนาดมหึมาถ้าคำสั่งมันทันทีหลังจากที่เป็นตัวแปรที่returnมีการประกาศเพียงในคำสั่งนั้น ฉันทำการปรับเปลี่ยนนี้ในรหัสของฉันและตอนนี้ทำงานโดยไม่มีข้อผิดพลาด ถ้าคุณไม่รังเกียจที่จะเปลี่ยนแปลงสิ่งนี้ที่นี่
Gryphon - Reinstate Monica

3
คุณดูเหมือนจะยุ่งกับสถานะของตัวสร้างการสุ่มทั่วโลกซึ่งอาจไม่เป็นไร ผมถือว่าทำสิ่งที่คล้ายกันและพบว่าวิธีนี้สร้างวัตถุสุ่มใหม่ที่มีและใช้มันเช่นนี้R=random.Random(seed) R.choice(...)
Christian Sievers

@Gryphon แก้ไขแล้ว อาจมีข้อผิดพลาดบางอย่างที่เกิดขึ้นเมื่อเปลี่ยนจากสคริปต์ในเครื่องของฉันเป็น se ซึ่งทุก ๆ ครั้งจะต้องมีการเพิ่มอีกหนึ่งครั้ง
alex berne

1
@alexberne คุณสามารถเลือกรหัสที่คุณวางและคลิก{}ปุ่มบนแถบเครื่องมือเพื่อเยื้องโดยอัตโนมัติทุกบรรทัด
Selcuk


2

have_we_been_here_before

เพียงแค่ถามว่า "เราเคยมาที่นี่มาก่อนแล้ว" และเลือกการเคลื่อนไหวที่จะให้ผลเฉลี่ยที่ดีที่สุดในเกมก่อนหน้านี้

แก้ไข: Honesty Club ฉันได้เพิ่มบล็อกเล็ก ๆ ของรหัสเพราะบอท (mason) ทำได้ดีมากโดยการก่อตั้งชมรมลับขึ้นมาเอง อย่างไรก็ตามโปรดสังเกตว่าการเล่นอย่างตรงไปตรงมากับฝ่ายตรงข้ามที่ซื่อสัตย์มีค่าตอบแทนเท่ากันโดยเฉลี่ยเมื่อเล่นกับตัวเองและอาจมีประโยชน์ร่วมกันที่กว้างกว่าที่จะมีเช่นกัน?

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

import random

def have_we_been_here_before(opponentList, myList, opponent, me):

    def win(x):
        if x=="R": return "P"
        elif x=="P": return "S"
        elif x=="S": return "R"

    def calc_score(r1, r2):
        if r1==r2: return 1
        elif r1==win(r2): return 2
        else: return 0

    def have_we(opponentList, myList, opponent, me, me2):
        score, count = 0, 0
        for n in range(len(opponentList)):
            if (opponent == opponentList[n][0] and me == myList[n][0]):
                score += calc_score(me2, opponentList[n][1])
                count += 1
        if count == 0: return 0
        else: return float(score) / float(count)

    if opponent == None:

        # exploit rotators
        if len(opponentList) >= 3:
            rotator = True

            for n in range(3, len(opponentList)):
                if opponentList[n][1] != opponentList[n % 3][1]:
                    rotator = False
                    break

            if rotator: return win(opponentList[len(opponentList) % 3][1])

        if len(opponentList) == 0:
            return random.choice(["R", "P", "S"])
        else:
            # crude attempt to exploit the house bots
            prev = random.choice(opponentList)[1]
            return win(prev)

    # Play honestly if opponent has played honestly so far
    honest = True
    for oppMove in opponentList:
        if (oppMove[0] != oppMove[1]):
            honest = False
            break

    if honest: return me
    # Done playing honestly

    # Have we been here before?
    rock = have_we(opponentList, myList, opponent, me, "R")
    paper = have_we(opponentList, myList, opponent, me, "P")
    sissors = have_we(opponentList, myList, opponent, me, "S")

    if rock > paper and rock > sissors: return "R"
    elif paper > rock and paper > sissors: return "P"
    elif sissors > paper and sissors > rock: return "S"
    else: return win(opponent)

2

THEbot: ผู้แสวงหาความซื่อสัตย์

import random 
def thebot(ho,hm,om,mm):
    hands = {"R": "P", "P": "S", "S": "R"}
    if om == None:
        if (len(set([i[0] for i in ho])) < 3) and (len(ho) > 2):
            return hands[random.choice(list(set([i[0] for i in ho])))]
        else:
            return random.choice(["R","P","S"])
    else:
        if sum(1 for i in ho if i[0]==i[1]) > (len(ho)/3):
            if om == mm:
                return om
            else:
                return hands[om]
        else:
            return mm

ฉันเพิ่งรู้ว่าฉันลงคะแนนผิดโดยขออภัยด้วย จะเลิกทำเมื่อคุณแก้ไข (ไม่สามารถเปลี่ยนมัน othewise.)
Christian Sievers


@ChristianSievers ขอบคุณ!
Cinaski

2

ธ อมป์สัน

import math
import random

moves = list(range(3))
names = "RPS"
from_name = dict(zip(names, moves))
to_name = dict(zip(moves, names))

#Payoff matrices given each relationship between honest moves.
A = [
    [[2, 1, 3], [2, 1, 0], [0, 2, 1]],
    [[1, 3, 2], [1, 0, 2], [2, 1, 0]],
    [[3, 2, 1], [0, 2, 1], [1, 0, 2]]
]

#Add a 1.2% penalty for the opponent's score (idea shamelessly stolen from csbot).
for d_h in range(3):
    for i in range(3):
        for j in range(3):
            A[d_h][i][j] -= 0.012 * A[[0, 2, 1][d_h]][j][i]

third = 1. / 3
two_thirds = 2 * third

nash_prior = [
    [[1, 0, 0], [two_thirds, 0, third], [third, 0, two_thirds]], 
    [[third, 0, two_thirds], [1, 0, 0], [two_thirds, 0, third]], 
    [[two_thirds, 0, third], [third, 0, two_thirds], [1, 0, 0]]
]

def mult_m_v(M, v):
    w = [0 for _ in v]
    for i, M_i in enumerate(M):
        for M_ij, v_j in zip(M_i, v):
            w[i] += M_ij * v_j
    return w

def mean_belief(counts):
    c = 1. / sum(counts)
    return [n * c for n in counts]

def sample_belief(counts):
    return mean_belief([random.gammavariate(n, 1) for n in counts])

def thompson(h_opp, h_me, opp, me):

    #Prior rationality of opponent.
    a = 0.95

    #Confidence in priors.
    n0_h = 0.5
    n0_m = 0.5

    def v(x):
        return [x for _ in range(3)]

    h_p = [v(n0_h * third) for _ in range(3)]

    m_p0 = [v(None) for _ in range(3)]
    m_p1 = [v(None) for _ in range(3)]

    #Expected prior is a mixture between nash equilibrium and uniform distribution.
    for h_i in range(3):
        for h_j in range(3):
            m_p0[h_i][h_j] = [n0_m * (a * nash + (1 - a) * third) for nash in nash_prior[h_i][h_j]] 

    for d_j_prev in range(3):
        for d_ij in range(3):
            m_p1[d_j_prev][d_ij] = list(m_p0[0][d_ij])

    #Track whether it's better to model the real moves based on the exact honest moves or
    #just the relationship between honest moves together with the opponent's defection strategy in the previous round.
    log_mp0 = 0
    log_mp1 = 0

    #Identify myself and always cooperate.
    is_me = True

    for (t, ((h_i, m_i), (h_j, m_j))) in enumerate(zip(h_me, h_opp)):

        h_i, m_i, h_j, m_j = from_name[h_i], from_name[m_i], from_name[h_j], from_name[m_j]

        d_j = (m_j - h_j) % 3
        d_ij = (h_j - h_i) % 3

        if t:
            h_j_prev = from_name[h_opp[t - 1][0]]
            m_j_prev = from_name[h_opp[t - 1][1]]
            h_p[h_j_prev][h_j] += 1

            d_j_prev = (m_j_prev - h_j_prev) % 3

            log_mp0 += math.log(m_p0[h_i][h_j][d_j] / sum(m_p0[h_i][h_j]))
            log_mp1 += math.log(m_p1[d_j_prev][d_ij][d_j] / sum(m_p1[d_j_prev][d_ij]))

            m_p1[d_j_prev][d_ij][d_j] += 1

        m_p0[h_i][h_j][d_j] += 1

        if is_me and ((h_i != h_j) or (h_j != m_j)):
            is_me = False

    if is_me:
        random.seed(len(h_me) + 1337)
        me_next = random.randrange(3)

    log_ps = [log_mp0, log_mp1]
    log_p_max = max(log_ps)
    ps = [math.exp(log_p - log_p_max) for log_p in log_ps]
    p0 = ps[0] / sum(ps)

    #We have to blend between the predictions of our 2 models for the real rounds.  

    def sample_expectation(h_i, h_j, d_j_prev=None):
        d_ij = (h_j - h_i) % 3
        if d_j_prev is None or random.random() < p0:
            p = m_p0[h_i][h_j]
        else:
            p = m_p1[d_j_prev][d_ij]
        return mult_m_v(A[d_ij], sample_belief(p))

    def take_expectation(h_i, h_j, d_j_prev=None):
        d_ij = (h_j - h_i) % 3
        e0 = mult_m_v(A[d_ij], mean_belief(m_p0[h_i][h_j]))
        if d_j_prev is None:
            return e0
        e1 = mult_m_v(A[d_ij], mean_belief(m_p1[d_j_prev][d_ij]))
        return [p0 * e0i + (1 - p0) * e1i for e0i, e1i in zip(e0, e1)]

    #We use thompson sampling, selecting the optimal deterministic strategy
    #with respect to a random opponent sampled from the posterior.

    #Actually, we use optimistic thompson sampling which clips samples to have >= than the mean expected value.

    if opp == None:
        #For the honest round we perform a lookahead to the real round to choose our strategy.
        if h_opp:
            if is_me:
                return to_name[me_next]
            h_j_prev = from_name[h_opp[-1][0]]
            m_j_prev = from_name[h_opp[-1][1]]
            d_j_prev = (m_j_prev - h_j_prev) % 3
            h_p_s = sample_belief(h_p[h_j_prev])
            h_p_u = mean_belief(h_p[h_j_prev])
            s_i = [0] * 3
            s_i_u = [0] * 3
            for h_i in range(3):
                for h_j in range(3):
                    s_i[h_i] += h_p_s[h_j] * max(sample_expectation(h_i, h_j, d_j_prev))
                    s_i_u[h_i] += h_p_u[h_j] * max(take_expectation(h_i, h_j, d_j_prev))
                s_i[h_i] = max(s_i[h_i], s_i_u[h_i])
            return to_name[s_i.index(max(s_i))]
        else:
            return to_name[me_next]
    else:
        if h_opp:
            if is_me:
                return me
            h_j_prev = from_name[h_opp[-1][0]]
            m_j_prev = from_name[h_opp[-1][1]]
            d_j_prev = (m_j_prev - h_j_prev) % 3
        else:
            if opp == me:
                return me
            d_j_prev = None
        h_i, h_j = from_name[me], from_name[opp]
        s_i = [max(s0, s1) for s0, s1 in zip(sample_expectation(h_i, h_j, d_j_prev), take_expectation(h_i, h_j, d_j_prev))]
        return to_name[(h_i + s_i.index(max(s_i))) % 3]

รายการที่น่าสนใจ ฉันจะเรียกใช้เร็ว ๆ นี้ควรจะสามารถโพสต์ผลลัพธ์ในบ่ายนี้
Gryphon - Reinstate Monica

ตกลงฉันเปลี่ยนพารามิเตอร์อีกเล็กน้อย
user1502040

เข้าใจแล้ว. ขออภัยการอัปเดตใช้เวลานานมากเพียงทุกครั้งที่เพิ่งเสร็จสิ้นมีคนอัปเดตบ็อตหรือรับใหม่และฉันต้องเรียกใช้อีกครั้ง
Gryphon - Reinstate Monica

@Gryphon คุณสามารถเก็บตารางผลลัพธ์ของการจับคู่ทั้งหมดดังนั้นเมื่อบอตได้รับการอัปเดตคุณจะต้องเรียกใช้ 200 * (num_bots - 1) + 100 การแข่งขันใหม่
user1502040

2

mirrorbot

import random

def mirrorbot(op_hist, my_hist, op_move, my_move):
    if my_move == None :
        return random.choice(["R","P","S"])
    else :
        for x in range(len(op_hist)):
            if ((op_hist[len(op_hist) -x-1][0] == my_move) and (my_hist[len(op_hist) -x-1][0] == op_move)):
                return op_hist[len(op_hist) -x-1][1]
        return my_move

ฉันจะลองบอทธรรมดาที่ทำซ้ำการเล่นล่าสุดของคู่ต่อสู้ในเงื่อนไขเหล่านี้


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

1
def rotate_rock(h1, h2, is_, honest):
 return ("R", "P", "S")[len(h1) % 3]

def rotate_paper(h1, h2, is_, honest):
 return ("P", "S", "R")[len(h1) % 3]

def rotate_scissors(h1, h2, is_, honest):
 return ("S", "R", "P")[len(h1) % 3]

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


1
คำisนี้เป็นคำสำคัญจึงไม่ถูกต้อง
Erik the Outgolfer

@EriktheOutgolfer ขอบคุณ :)
สตีเฟ่น

1

Dx

ฉันเขียนบอทนี้เท่านั้นฉันจึงสามารถยิ้มได้ในชื่อบอตของฉัน xD

def Dx(ophist, myhist, opmove, mymove):
    from random import choice
    import math
    def honest(hist):
        return [int(x[0]==x[1]) for x in hist]

    def avg(arr):
        if len(arr)==0:
            return 0
        return sum(arr)/float(len(arr))

    def clamp(i, lo, hi):
        return min(hi, max(lo, i))

    def deltas(arr):
        return [a-b for a,b in zip(arr[1:],arr[:-1])]

    def delta_based_prediction(arr,l):
        deltarr = []
        i=0
        while len(arr)<0:
            deltarr[i]=avg(arr[-l:])
            i+=1
            arr = deltas(arr)
        return sum(deltarr)

    next_honesty = delta_based_prediction(honest(ophist),int(math.sqrt(len(ophist))))
    if abs(next_honesty-0.5)<0.1 or not opmove:
        return choice(['R','P','S'])
    next_honesty=int(clamp(round(next_honesty),0,1))
    winner = {'S': 'R', 'R': 'P', 'P': 'S'}

    if next_honesty > 0:
        return winner[opmove]

    return choice([opmove, winner[winner[opmove]]])

1

ทุกคนโกหก

import random

def everybodylies (opphist, myhist, oppmove, mymove):
    if mymove == None:
        return random.choice(["R","P","S"])
    elif mymove == "R": return "S"
    elif mymove == "P": return "R"
    elif mymove == "S": return "P"

มันเกี่ยวกับการเคลื่อนไหวของมัน ("ฉันจะเล่นกรรไกร!") และสมมติว่าคู่ต่อสู้กำลังโกหกและพวกเขาจะพยายามเอาชนะสิ่งที่ฉันบอกว่าการเคลื่อนไหวของฉันจะเป็น ("อืมร็อคเต้นกรรไกรดังนั้นฉันจึงเล่น นั่น ") แต่ฉันจริง ๆ แล้วเล่นท่าที่เต้น (" Paper! Surprise! ")


3
เสียงเหมือนระดับแรกของกลยุทธ์Iocaine Powderสำหรับฉัน :-) "ตอนนี้คนฉลาดจะวางพิษลงในแก้วของเขาเพราะเขาจะรู้ว่ามีเพียงคนโง่ที่ดีเท่านั้นที่จะได้รับในสิ่งที่เขาได้รับฉันไม่ คนโง่ที่ดีดังนั้นฉันจึงไม่สามารถเลือกไวน์ที่อยู่ตรงหน้าคุณได้อย่างชัดเจน แต่คุณต้องรู้ว่าฉันไม่ใช่คนโง่ที่ยอดเยี่ยมคุณจะต้องนับมันดังนั้นฉันจึงไม่สามารถเลือกไวน์ที่อยู่ข้างหน้า .. . "
แอนโทนี

1

ธ ปท. ที่ไว้วางใจ

def trusting_bot(h_opp, h_me, opp, me):
    if opp=="S":
        return "R"
    elif opp=="R":
        return "P"
    else:
        return "S"

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


สิ่งนี้จะมีประสิทธิภาพมากขึ้นถ้ามันจะซื่อสัตย์กับตัวเองอยู่เสมอ
Gryphon - Reinstate Monica

@Gryphon อาจเป็นไปได้ แต่ฉันไม่ได้เป็นงูหลามที่ดีพอที่จะลองทำสิ่งที่ให้ความร่วมมือเช่นนั้น
ATaco

ไม่เป็นไรแล้ว
Gryphon - Reinstate Monica

1

ชื่อบอท: คนโกหกคนโกหก

หยุดโกหกไม่ได้

import random

def liarliar (herHistory, myHistory, herMove, myMove):
    options = ["R", "P", "S"]
    if myMove == None:
        return random.choice(options)
    else:
        options.remove(myMove);
        return random.choice(options)

1

RockBot

ถือว่าฝ่ายตรงข้ามจะซื่อสัตย์และพยายามที่จะเอาชนะพวกเขา แต่ปฏิเสธที่จะเล่นร็อค

import random
def rockBot(oppHist,myHist,oppMove,myMove):
    if oppMove == None:
        return random.choice(["R","P","S"])
    else:
        if(oppMove == "R"):
            return "P"
        elif(oppMove == "P"):
            return "S"
        elif(myMove != "R"):
            return myMove
        else:
            return random.choice(["P","S"])

1
ดูเหมือนว่าจะเกิดข้อผิดพลาดเนื่องจากในบรรทัดสุดท้ายของคุณ "P", "S" ไม่ได้อยู่ในวงเล็บเหลี่ยม (ไม่ใช่รายการ) ฉันเปลี่ยนมันในเวอร์ชันของฉัน แต่ถ้าคุณทำได้เหมือนกันที่นี่มันจะยอดเยี่ยม ขอบคุณ
Gryphon - Reinstate Monica

สิ่งนี้จะไม่สูญเสียไปกับกรรไกรที่คงที่หรือไม่?
Wildcard

@ Wildcard ใช่ แต่มันจะทำได้ดีกับ bot กระดาษ
Slepz

1

ชื่อ ธ ปท: dontlietome

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

import random
def dontlietome(opp_moves, my_moves, opp_hint, my_hint):
    def is_trustworthy(moves, length):
        length = max(-length, -len(moves))
        history = [1 if move[0] == move[1] else 0 for move in moves[length:]]
        prob_honest = float(sum(history))/float(len(history))
        choice = random.uniform(0., 1.)
        if choice <= prob_honest:
            return True
        else:
            return False

    moves = ["R", "P", "S"]
    lose_against_map = {"S":"R", "R":"P", "P":"S"}
    length = 10
    if opp_hint == None:
        # Honest round
        return random.choice(moves)
    else:
        # Real round
        if len(opp_moves) < length:
            return my_hint
        if is_trustworthy(opp_moves, length):
            return lose_against_map[opp_hint]
        else:
            return my_hint

ในบรรทัด "if is_trustworthy (opp_move, self.length):", ตัวเองไม่ได้ถูกกำหนด นอกจากนี้ในบรรทัด "return loss_against_map [opp_hint]", loss_against_map ก็ไม่ได้ถูกกำหนดเช่นกัน ความยาวตัวเองดูเหมือนจะแก้ไขได้ด้วยการเอาตัวเองออก แต่ปัญหาอื่นยังคงอยู่ จนกว่าจะได้รับการแก้ไขฉันกลัวว่าสิ่งนี้จะไม่ถูกต้อง
Gryphon - Reinstate Monica

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

ตกลง. หากเป็นเพียงข้อผิดพลาดเล็ก ๆ น้อย ๆ ฉันแก้ไขให้ถูกต้อง (อย่างที่ฉันมีในบ็อตอื่น ๆ และน่าจะเป็นถ้ามันเป็นปัญหาของตัวเอง) แต่ฟังก์ชั่นที่ขาดหายไปเป็นเรื่องที่แตกต่าง
Gryphon - Reinstate Monica

@Gryphon ฉันแก้ไขข้อบกพร่อง (ลบตัวเองออกเพิ่มการอ้างอิงlost_against_mapและแก้ไขคำสั่ง if การตรวจสอบว่ารอบที่ซื่อสัตย์)
coolioasjulio

0
import random
def trustingRandom(a,b,c,d):
  move = random.choice(["R","P","S"])
  if c == "R":
    move = "P"
  elif c == "P":
    move = "S"
  elif c == "S":
    move = "R"
  return move

0

averager

def averager(op, mp, od, md):
  import random
  if od == md == None:
    if op == mp == []:
      return random.choice('RPS')
    else:
      opa = [i[1] for i in op]
      copa = [opa.count(i) for i in 'RPS']
      copam = [i for i, j in zip('RPS', copa) if j == max(copa)]
      opd = [i[0] for i in op]
      copd = [opd.count(i) for i in 'RPS']
      copm = [i for i, j in zip('RPS', copd) if j == max(copd) and i in copam]
      return random.choice(copam if copm == [] else copm)
  else:
    if op == mp == []:
      return md
    else:
      hop = sum([1. if i[0] == i[1] else 0. for i in op]) / len(op)
      hmp = sum([1. if i[0] == i[1] else 0. for i in mp]) / len(mp)
      return 'PSR'['RPS'.index(od)] if hmp >= 0.75 and hop >= 0.50 else md

0

ดีขึ้นเล็กน้อยจากรายการก่อนหน้าของฉัน ...

def learningbot4(yourlist,mylist,you,me):
  CHECK={"R":{"R":0,"P":1,"S":-1},"P":{"R":-1,"P":0,"S":1},"S":{"R":1,"P":-1,"S":0}}
  results={None:{"R":0,"P":0,"S":0},"R":{"R":0,"P":0,"S":0},"P":{"R":0,"P":0,"S":0},"S":{"R":0,"P":0,"S":0}}
  for i in range(len(yourlist)):
    res=CHECK[yourlist[i][1]][mylist[i][1]]
    if mylist[i][0]==mylist[i][1]: res+=0.5
    results[yourlist[i][0]][mylist[i][1]]+=res
    results[None][mylist[i][0]]+=res
  return max(results[you],key=results[you].get)

0

csbot บนเตียรอยด์

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

from random import seed
from csbot import csbot

def csbot_on_steroids(ophist,myhist,opdecl,mydecl):
  seed()
  m = csbot(ophist,myhist,opdecl,mydecl)
  seed(0)
  return m
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.