正直ロック、紙、はさみ


58

多くの人がRPSをチャンスのゲームだと考えています。両方のプレイヤーが予想外にプレイする場合、最善の戦略はランダムにプレイすることです。ただし、少し予測可能性を紹介しましょう。

各ボットは、同時にプレイする内容を他のボットに伝える機会があります。その後、各ボットが他のプレイヤーが発表した内容を知るための一時停止があります。その武器をプレイした場合、勝ち負けまたは引き分けのポイントに加えて1ポイントを獲得すると発表しました。

勝利には2ポイント、引き分け、1ポイント、損失0ポイントの価値があります。

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

正直であることはあなたの最大の利益です(しかし、相手があなたを信じないようにすることも)。

試合はラウンドロビン形式で行われ、目的はあなたがプレイする試合全体であなた自身の合計スコアを最大にすることです。

I / O形式:

  • ボットは、4つの引数を取るPython 2.7関数であり、一意の名前(提出物を表すために使用される)を持つ必要があります。
  • 最初の2つの引数は、常に順番になります。対戦相手の過去の動きと、それに続く過去の動きです。これらは、最初のラウンドから最新のラウンドまでの順番のリストになります。各インデックスには、対戦相手が行ったと主張した動きのリストと、実際に行った動きが含まれます。
  • 次の2つの引数により、ボットは「正直な」ラウンドか「実際の」ラウンドかを判断できます。「正直な」ラウンドの場合、両方ともNoneになります。それが「本物の」ラウンドである場合、それらは順番に、対戦相手が彼らが行うと宣言した動きであり、その後、あなたが行うと宣言した動きです。
  • 動きを表すすべての引数または引数の部分は、それぞれ「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アームの盗賊問題と同様の方法でこのゲームに取り組みます。それは2つの方法でそれを行います:各宣言に対してどちらの宣言が優れているかを学習しようとし、その宣言に固執し(一定のボットに対して有用)、以前の同様の状況での様々な動きの結果を学習しようとします(相対的なプレイに関して同様)たとえば、岩と紙は以前の紙とハサミに似ています)。最初の仮定は楽観的であるため、このプレーヤーは、正直であることで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

私は実際にPythonをあまり使ったことがないので、どこかで間違いを犯したと確信しています。

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:コンスタントボット検出器を改良し、回転ボットでも動作するようにしました。

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

@ user1502040なぜそう思うのですか?私は問題を観察したことがありません。
クリスチャンシーバーズ


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

Tatのシジュウカラ

古典的なアクセルの出場者:希望に満ちた、まだ小さい。シンプルでありながら堅牢です。これは囚人のジレンマではないので、対戦相手の動きを予測しようとはしなかったので、本当に競争力があるとは思わない。しかし、「協力する」ことは依然として競技者にとって最も全体的なポイントを生み出すので、少なくともややこしいと思う。

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

2/3

Sandboxおよびこのコメントで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

あ。このコンピューターにpythonがないので、今はこれを修正できませんが、家に帰ったらコードで修正します。@ mbomb007がここでそれを修正するなら、それは素晴らしいことです。
グリフォン-復活モニカ

3

DeepThought

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は考えるのが好きです。たくさん。申し訳ありませんが、修正方法はわかりません。私はPythonを非難します。
  • DeepThoughtは正直になろうとします。正直であることは、1つの追加ポイントを提供します。
  • ただし、DeepThoughtは、ゲームごとに2ポイントを超えて異常な状態になります。彼はいくつかの検出を使用して、いくつかの一般的な動作(だまし、正直な行動など)を見つけ、それに応じて適応します。
  • DeepThoughtは純粋に決定論的であるため、両端で常に同じ決定を行うため、それ自体に反します。
  • 自分自身に対して嘘をつかないように、ここにある他のボットのように、特別な検出機能があります。これは非常にアグレッシブなものであり、1ラウンド後(および最初のラウンドでも)真であると想定しています。基本的に、相手の動きがまさに私のものである限り、ミラーマッチを想定します。
  • 興味深い部分(および数十の誤検知がある部分)は、決定的なボットのチェックです。これは、独自の優先結果にのみ依存しています。このチェックでは、サイズnのパターンを検索します。これは2回繰り返され、最後のn-1の動きを記述し、対戦相手の要求を予測し、事前に動きます。悲しいことに、この部分には時間がかかります。

私はkothとPythonの両方が初めてなので、このボットで何かを台無しにしたかどうかを教えてください。私はそれが強化された学習を打ち負かすことはできないと思います(私の動きをあまりにも早く学ぶだろうと思うので)が、試してみましょう。

私はこの挑戦が好きで、時間があれば、オーガニックコンピューティングのアプローチを追加したいと思います(高次元へのプレッシャーがあまりにも少ないかもしれません)。複数の提案を追加できますか?または、メインボットを失うことのみを目的とするものを挿入することにより、メインボットのブーイングを防ぐことは禁止されていますか?

編集:私を非ネイティブの英語話者として特徴づけるコードタイプミスを修正


複数のエントリを投稿することは禁じられていませんが、別のボット(自分のものではないボットを含む)を支えるエントリを投稿することは禁じられています。設計によるものでない限り、別のボットに負けても構いません。
グリフォン-モニカの復活

DeepThought関数の32行目にreturn result追加のインデントが必要なため、これを実行するとエラーが発生しました。変数returnはそのitステートメントでのみ宣言されるため、その直後の巨大なifステートメント内にあるべきだと思います。コードにこの変更を加えたところ、エラーなしで実行されます。ここでその変更を行うことを気にしないのであれば、それは素晴らしいことです。
グリフォン-モニカの復活

3
グローバルランダムジェネレーターの状態を混乱させているようですが、おそらく大丈夫ではありません。私は同様のことをすることを検討し、この解決策を見つけました:新しいランダムオブジェクトを作成し、次のR=random.Random(seed)ように使用します:R.choice(...)
クリスチャンシーバーズ

@Gryphonが修正されました。おそらく、私の地元のスクリプトからeverythinは一つの追加の時間をintdentedする必要がSEに変換する際に発生したいくつかのエラー
アレックスはベルン

1
@alexberne貼り付けたコードを選択{}し、ツールバーのボタンをクリックして、すべての行を自動的にインデントできます。
セルチュク

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:私の前の2つのボットは両方ともローテーターを悪用しているので、その時流に乗るために別のコードブロックを追加します。私のコードはかなり古いように思えます-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

私は、クリックミスでダウン票を投じたことに気付きました。ごめんなさい。編集すると元に戻ります。(それ以外の方法で変更することはできません。)
クリスチャン

@ChristianSievers編集
シナスキー

ありがとうございます!
シナスキ

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]

興味深いエントリー。すぐに実行します。今日の午後に結果を投稿できるはずです。
グリフォン-モニカの復活

OK、パラメーターを少し戻しました。
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へようこそ!
マーティンエンダー

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はキーワードなので、これは無効です。
エリックアウトゴルファー

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

それはその動き(「私はハサミをプレイします!」)にあり、対戦相手も嘘をついていて、彼らが私の動きだと言ったことを打ち負かそうとします(「うーん、ロックはハサミを打つのでプレイしています」それ」)、しかし、私は実際にその動きを打つ動きをプレイします(「紙!サプライズ!」)。


3
イオカインパウダー戦略の最初のレベルのように思えます:-)「今、賢い人は自分のゴブレットに毒を入れるでしょう。私は偉大な愚か者ではないことを知っていたに違いありません。あなたはそれを頼りにしていたので、私は明らかに私の前でワインを選択することはできません。 。 "
アントニー

1

信頼するボット

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

はさみを投げると常に主張しますが、相手が言ったことを打つものは何でもします。それ自身で確実に描画します。


これは、常に自分自身に対して正直であれば、より効果的です。
グリフォン-モニカの復活

@Gryphonおそらく、しかし、私はそのように協力する何かを作ろうとするのに十分なPythonではありません。
アタコ

じゃあ心配しないで。
グリフォン-モニカの復活

1

ボット名:Liar Liar

嘘を止めることはできません。

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を削除することで解決されるようです。しかし、他の問題はまだ残っています。それが修正されるまで、これは無効だと思います。
グリフォン-モニカの復活

オブジェクトを使用してこれを書いたのですが、自己参照を削除してコードを完全にコピーするのを忘れていました。帰宅したらすぐに修正します。
coolioasjulio

OK。それがほんの小さなエラーであれば、私はそれを修正します(他のいくつかのボットで持っているように、それが単なる自己の問題であった場合はそうするでしょう)。
グリフォン-モニカの復活

@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

アベレージャー

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ため、コンテストに参加できるのは1人だけです。

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.