정직한 바위, 종이, 가위


58

많은 사람들이 RPS를 우연한 게임이라고 생각합니다. 두 선수 모두 예상치 못한 플레이를하는 경우, 가장 좋은 전략은 무작위로 플레이하는 것입니다. 그러나 약간의 예측 가능성을 소개합시다.

각 봇은 다른 봇에게 동시에 플레이 할 내용을 알려줄 수 있습니다. 그런 다음 각 봇이 다른 플레이어가 발표 한 내용을 알 수있는 일시 중지가 있습니다. 그것이 그 무기를 사용하면 승리 손실이나 무승부 점수 외에 1 점을 획득 할 것이라고 발표했습니다.

승리는 2 점, 무승부, 1 점, 손실 0 점입니다.

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

정직하게 행동하는 것이 가장 좋습니다 (그러나 상대방이 당신을 믿지 않도록하는 것).

경기는 라운드 로빈 형식으로 진행되며, 경기 중 자신의 총 점수를 극대화하는 것이 목표입니다.

I / O 형식 :

  • 봇은 4 개의 인수를받는 Python 2.7 함수이며 고유 한 이름 (제출을 나타내는 데 사용됨)을 가져야합니다.
  • 처음 두 가지 논증은 항상 순서대로 진행됩니다 : 상대의 과거 움직임과 과거의 움직임. 이들은 첫 라운드부터 가장 최근 라운드까지의 목록이 될 것이며, 각 인덱스는 상대방이 주장한 움직임과 함께 실제로 만들어진 움직임이 포함 된 목록을 포함합니다.
  • 다음 두 인수를 통해 봇은 이것이 "정직한"라운드인지 "진짜"라운드인지 판단 할 수 있습니다. "정직한"라운드 인 경우 둘 다 없음입니다. "진정한"라운드 인 경우, 상대방이 자신이 선언 한 움직임과 순서대로 진행됩니다.
  • 움직임을 나타내는 모든 인수 또는 인수의 일부는 "R", "P"및 "S"를 사용하여 각각 바위, 종이 및 가위를 나타냅니다.
  • 함수는 바위의 경우 "R", 용지의 경우 "P"또는 가위의 경우 "S"를 반환해야합니다. 다른 값을 반환 할 수있는 봇은 실격됩니다.
  • 각 봇은 다른 모든 봇에 대해 200 번, 자체적으로 100 번 실행됩니다. 목표는 경쟁이 끝날 때 가장 많은 점수를 가진 봇이되는 것입니다.
  • 의견에 대한 논의와 관련하여 제출물은 파일을 읽거나 파일에 쓰거나 어떤 식 으로든 방해하거나 상대방의 코드를 읽을 수 없습니다.

예 :

이것들은 내가 함께 모은 4 개의 봇입니다. 그들은 추가 봇으로 경쟁에 참여할 것입니다. 마지막에 졌다면해야 할 일이 있습니다.

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

석공

다른 봇에 대한 정직성 및 나의 첫 움직임에 따른 영향과 같은 다른 봇에 대한 정보를 얻으려고 시도합니다. 그런 다음 패턴을 따르는 다른 명백한 봇을 찾아서 더 많은 포인트를 제공하는 데 사용합니다. 마지막으로, 메이슨은 비밀 무기를 가지고 있습니다. 비밀 사회에 대한 지식은 서로 참여하는 두 봇이 각각 최대 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 : 강화 학습

강화 학습 접근 방식을 사용하여 n-armed bandit 문제와 유사한 방식으로이 게임을 처리합니다. 그것은 두 가지 방식으로 수행됩니다 : 각 상대에 대해 어떤 선언이 더 나은지 배우고 그에 고착하고 (일관된 봇에 유용) 이전의 유사한 상황에서 다양한 움직임의 결과를 배우려고합니다 (상대 극과 유사) 예를 들어, 바위 대 종이는 이전 종이 대 가위와 유사합니다). 초기 가정은 낙관적이므로,이 플레이어는 정직하면 3 점을 부여하고 거짓말은 2를 부여한다고 가정하므로 달리 입증 될 때까지 항상 정직합니다.

업데이트 : 첫 번째 토너먼트 결과는이 봇의 문제를 강조했습니다. 그런 다음 정직한 라운드의 코드에 패턴 일치 구성 요소를 추가했습니다. 정규식을 사용하여 정규식을 사용하여 이전에 어딘가에 존재했던 상대 선언의 역사에서 가장 긴 접미사를 찾습니다. . 우리는 상대방이 다시 같은 움직임을 할 것이라고 가정하고, 그에 대한 최선의 답변이 무엇인지 결정하기 위해 이전과 같이 강화 학습을 사용합니다.

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

여기 내 적응 형 봇이 있습니다. 상대의 마지막 두 움직임을 분석하여 정직한 봇인지 아닌지를 결정하고 그에 따라 재생합니다.

편집 1 : 다른 봇이 일정한 봇인 경우 (즉, 항상 같은 무기를 사용하는 경우)이 봇은 승리 한 무기를 플레이하고 동시에 정직하게 행동함으로써 봇을 짓밟습니다.

편집 2 : 회전 봇과 함께 작동하도록 지속적인 봇 감지기를 개선했습니다.

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]

상대방이있는 한 정직하고 간단한 결정적 봇을 탐지하십시오. 우리가 주로 포인트를 가지지 만 다른 플레이어에게 포인트를주지 않기를 기대하는 가치를 극대화하는 움직임을하십시오. 그러나 자신의 점수는 10 배가 낫기 때문에 value함수 의 특이한 숫자입니다 . 상대 이동은이 상황에서 이전에 본 빈도 (선언 된 이동)에 따라 예상되지만 최근에 본 이동은 이전에 본 이동보다 가중치가 더 높습니다. 임의의 초기 이동 (이전에 본 적이없는 상황) 및 일부 추가 퍼지의 경우 가중치에는 작은 추가 임의 숫자가 포함됩니다.

업데이트 : 정직한 라운드에서도 예상 결과를 사용하십시오. 이를 위해 상대방이 정직하게 생각할 수있는 추가 포인트를 정규화하고 고려하십시오. 실제 라운드에서 우리의 결정에 영향을 줄 수는 없지만 지금 필요합니다. 나는 처음부터 이것을하는 것을 고려했지만 가치가 없다고 잘못 생각했다. 나는 trusting_bot더 적은 점수 를 줄 수 있다는 것을 보았지만 (그러나 봇은 어쨌든 강한 상대는 아니었다), rockbot이 라운드에서의 플레이가 무작위 임에도 불구하고 정직한 라운드에서 좋은 플레이를 통해 추가 포인트를 얻을 수 있다는 것을 놓쳤다 .


항상 결과를 반환하지는 않습니다.
user1502040

당신 if mydecl == None:이 잘못 생각합니다 .
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
def honestrandom(a, b, c, move):
    if move == None:
        return random.choice(["R","P","S"])
    return move

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

문신에 대한 젖꼭지

고전적인 악셀로 디안 참가자 : 희망적이지만 소소한; 간단하면서도 강력합니다. 이것은 죄수의 딜레마가 아니며 상대방의 움직임을 예측하려고 시도하지 않았으므로 진정한 경쟁이 될 것입니다. 그러나 "협력"은 여전히 ​​참가자들에게 가장 전반적인 점수를 제공하므로 적어도 중간 정도는 할 것이라고 생각합니다.

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가 샌드 박스 와이 주석 에서 언급 한 전략을 사용합니다 .

내쉬 평형을 사용합니다 .

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 (moves)를 리턴하십시오. 사전에 .choice를 사용하고 있기 때문일 수 있습니다. 이 문제가 해결 될 때까지이 제출이 유효하지 않은 것 같습니다.
그리폰-복원 모니카

@Gryphon 사전이 아니라 세트입니다.
LyricLy

아 죄송합니다 방금 구불 구불 한 괄호를보고 "사전"이라고 생각했습니다. 내 잘못이야. random.choice가 왜 해당 라인에서 오류가 발생했는지 아십니까?
그리폰-복원 모니카

@Gryphon random.choice임의의 인덱스 번호를 선택한 다음 해당 인덱스의 목록에서 객체를 반환하는 것으로 보입니다 . 세트에는 순서가 없으므로 인덱싱도 지원하지 않으므로와 함께 작동하지 않습니다 random.choice. 이를위한 간단한 해결책은 호출하기 전에 세트를 목록으로 캐스팅하는 것 random.choice입니다.
LyricLy

아 이 컴퓨터에는 파이썬이 없으므로 지금은 해결할 수 없지만 집에 도착하면 코드로 수정하겠습니다. @ mbomb007가 여기서 고치면 좋을 것입니다.
그리폰-복원 모니카

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

그것에 대한 몇 가지 참고 사항 :

  • DeepThought는 생각하기를 좋아합니다. 많이. 죄송합니다. 문제를 해결하는 방법을 모르겠습니다. 나는 파이썬을 비난합니다.
  • DeepThought는 정직하려고 노력합니다. 정직한 꿀벌은 당신에게 하나의 추가 포인트를 제공합니다.
  • 그러나 DeepThought는 게임당 2 포인트 이상을 절약 할 수 있습니다. 그는 몇 가지 탐지를 사용하여 속임수, 정직함 등과 같은 일반적인 행동을 찾아 그에 따라 적응합니다.
  • DeepThought는 순전히 결정론 적이므로 항상 양측에서 동일한 결정을 내릴 것이기 때문에 자체적으로 불리 할 것입니다.
  • 자기 자신에 대항하지 않기 위해 여기에는 다른 봇과 마찬가지로 특별한 탐지 기능이 있습니다. 이것은 1 라운드 (그리고 1 라운드에서도)라고 가정하더라도 매우 공격적인 것입니다. 기본적으로 상대방의 움직임이 정확히 나의 것이면 거울 일치라고 가정합니다.
  • 흥미로운 부분 (및 수십 개의 오탐이있는 부분)은 결정 론적 봇을 확인하는 것이며, 이는 자체 prevoius 결과에만 의존합니다. 이 검사는 두 번 반복되는 n 크기의 패턴을 검색하여 마지막 n-1 이동을 설명하고 상대방의 주장을 예측하고 미리 이동합니다. 이 부분은 슬프게도 시간이 걸립니다.

나는 koth와 Python을 처음 사용 하므로이 봇에서 무언가를 엉망으로 만들 었는지 알려주십시오. 강화 학습을 이길 수는 없다고 생각합니다 (내 움직임을 너무 빨리 배울 것이라고 생각하기 때문에).

나는이 도전을 좋아하고, 시간이 있으면 유기적 인 컴퓨팅 접근 방식을 추가하고 싶습니다 (높은 차원에 너무 적은 압력이있을 수 있음). 여러 제안을 추가 할 수 있습니까? 아니면 기본 서버를 잃어 버릴 목적으로 만 일부를 삽입하여 메인 봇을 부딪히는 것을 방지하는 것이 금지됩니까?

편집 : 비 영어 원어민으로 나를 caracterized 코드 오타 수정


여러 개의 출품작을 게시하는 것은 금지되어 있지 않지만 다른 봇을 소유 한 출품작 (자신이 소유하지 않은 것)을 게시하는 것은 금지되어 있습니다. 의도적으로 설계된 것이 아니라면 다른 봇을 잃어도 괜찮습니다.
그리폰-복원 모니카

DeepThought 함수의 32 번째 줄에 return result추가 들여 쓰기가 필요 하기 때문에 이것을 실행할 때 오류가 발생했습니다 . 변수 return가 해당 명령문에서만 선언 되므로 즉시 if 문이 거대한 if 문 안에 있어야한다고 생각합니다 . 내 코드 에서이 수정을 수행했으며 이제 오류없이 실행됩니다. 여기서 변경하는 것이 마음에 들지 않으면 좋을 것입니다.
그리폰-복원 모니카

3
전역 랜덤 생성기의 상태를 망쳐 놓은 것 같습니다. 나는 비슷한 일을하는 것을 고려 하고이 해결책을 찾았습니다 : 새로운 임의의 객체를 R=random.Random(seed)만들고 다음과 같이 사용하십시오 : R.choice(...).
Christian Sievers

@Gryphon이 수정되었습니다. 아마도 내 로컬 스크립트에서 se로 변환 할 때 발생하는 일부 오류 일 수 있습니다. 여기서 모든 시간을 한 번 더 들여야합니다
alex berne

1
@alexberne 붙여 넣은 코드를 선택하고 {}도구 모음 에서 단추를 클릭하면 모든 줄이 자동으로 들여 쓰기됩니다.
Selcuk

2
import random
def user5957401bot(a,b,c,d):
    if d == None: 
       return random.choice(["R","P","S"])
    else:
       return random.choice(["R","P","S",d])

2

have_we_been_here_before

단순히 "우리가 여기에 와본 적이 있습니까?"라고 묻고 이전의 모든 게임에서 최고의 평균 결과를 낼 움직임을 선택합니다.

편집 : 정직 클럽. 다른 봇 (메이슨)이 자체적으로 비밀 클럽을 구성하여 매우 잘 수행했기 때문에 작은 코드 블록을 추가했습니다. 그러나 정직한 상대를 상대로 정직하게 플레이하는 것은 자신을 상대로 플레이 할 때 평균적으로 동일한 결과를 가져 왔을 것입니다.

Edit2 : 나보다 앞서 두 봇을 작성할 때 둘 다 로테이터를 악용하므로 해당 악 대차를 뛰어 넘기 위해 다른 코드 블록을 추가 할 것입니다. 필자는 실제로 파이썬을 알지 못하기 때문에 모든 프로그래밍 언어에서 발견되는 친숙한 구문을 고수하는 내 코드가 꽤 오래된 학교 같아야한다고 생각합니다.

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

방금 잘못 클릭하여 다운 투표했음을 알았습니다. 죄송합니다. 편집 할 때 실행 취소합니다.
Christian Sievers

@ChristianSievers 편집
Cinaski

@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]

재미있는 입장. 곧 실행하겠습니다. 오늘 오후에 결과를 게시 할 수 있어야합니다.
그리폰-복원 모니카

좋아, 나는 매개 변수를 약간 돌려 놓았다.
user1502040

알았다. 업데이트하는 데 너무 오래 걸리는 것은 죄송합니다. 단지 완료 될 때마다 누군가가 봇을 업데이트하거나 새 봇을 얻었고 다시 실행해야합니다.
그리폰-복원 모니카

@Gryphon은 모든 페어 업 결과 테이블을 유지할 수 있으므로 봇이 업데이트되면 200 * (num_bots-1) + 100 개의 새로운 일치 항목 만 실행하면됩니다.
user1502040

2

미러 봇

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

@EriktheOutgolfer 감사합니다 :)
Stephen

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"

그것은 이동에 관한 것이며 ( "나는 가위로 놀겠다!") 상대방도 거짓말을하고 있고 내가했던 움직임을 이길려고한다고 가정한다. 그 "), 그러나 나는 실제로 그 움직임을이기는 움직임 ("종이! 서프라이즈! ")을 재생합니다.


3
나에게 Iocaine Powder 전략 의 첫 번째 수준처럼 들린다 :-) "지금, 영리한 사람은 독을 독에 넣을 것입니다. 왜냐하면 그는 큰 바보 만 그가 주어진 것에 도달 할 수 있다는 것을 알기 때문입니다. 어리석은 바보 이기에 나는 당신 앞에서 포도주를 분명하게 선택할 수 없다. 그러나 너는 내가 어리석은 것이 아니라는 것을 알고 있었을 것이다. . "
Antony

1

신뢰 봇

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

항상 가위를 던지라고 주장하지만 상대방이 말한 것을 능가하는 것은 무엇이든 할 것입니다. 확실하게 스스로 그릴 것입니다.


항상 자신에 대해 정직하면 더 효과적입니다.
그리폰-복원 모니카

@Gryphon 아마, 그러나 나는 파이썬이 그렇게 협력하는 것을 만들고 싶을만큼 충분하지 않습니다.
ATaco

그럼 신경 쓰지 마
그리폰-복원 모니카

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"가 대괄호 안에 있지 않기 때문에 오류가있는 것 같습니다 (목록이 아님). 내 버전에서 변경했지만 여기서도 똑같이 할 수 있다면 좋을 것입니다. 감사.
그리폰-복원 모니카

끊임없는 가위로 끔찍하게 잃지 않습니까?
와일드 카드

@Wildcard 네, 그러나 종이 봇에 대해 꽤 잘 할 것입니다
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_moves, self.length) :"행에서 self는 정의되지 않습니다. 또한 "return lose_against_map [opp_hint]"줄에는 lose_against_map도 정의되어 있지 않습니다. self.length는 self를 제거하여 해결되는 것 같습니다. 그러나 다른 문제는 여전히 유효합니다. 그 문제가 해결 될 때까지, 이것이 유효하지 않은 것 같습니다.
그리폰-복원 모니카

죄송합니다. Object를 사용하여 작성했으며 자체 참조를 제거하고 코드를 완전히 복사하는 것을 잊었습니다. 집에 도착하자마자 고칠 것입니다.
coolioasjulio

승인. 작은 오류 일 경우 (다른 봇과 마찬가지로 자체 문제 인 경우) 오류를 수정하지만 누락 된 기능은 다른 이야기입니다.
그리폰-복원 모니카

@ 그리폰 버그를 수정했습니다. (자체를 제거하고 참조를 추가하고 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

평균 기

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.