Rock Jujur, Kertas, Gunting


58

Banyak orang menganggap RPS sebagai permainan peluang. Jika kedua pemain bermain tanpa terduga, strategi terbaik adalah bermain secara acak. Namun, mari kita perkenalkan sedikit hal yang dapat diprediksi.

Setiap bot akan memiliki kesempatan untuk memberi tahu bot lain apa yang akan dimainkan secara bersamaan. Lalu ada jeda di mana setiap bot akan tahu apa yang diumumkan pemain lain. Jika ia memainkan senjata itu, ia mengumumkan akan mencetak satu poin di samping poinnya untuk menang kalah atau seri.

Kemenangan bernilai dua poin, satu imbang, satu poin, dan kehilangan 0 poin.

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

Adalah kepentingan terbaik Anda untuk jujur ​​(tetapi juga untuk memastikan lawan Anda tidak percaya Anda).

Pertandingan akan dimainkan dalam format round robin, dan tujuannya adalah untuk memaksimalkan skor total Anda sendiri di pertandingan yang Anda mainkan.

Format I / O:

  • Bot Anda akan menjadi fungsi Python 2.7 yang mengambil 4 argumen, dan harus memiliki nama unik (yang akan digunakan untuk mewakili kiriman Anda).
  • Dua argumen pertama akan selalu, secara berurutan: gerakan masa lalu lawan, diikuti dengan gerakan masa lalu Anda. Ini akan menjadi daftar secara berurutan dari babak pertama hingga babak terbaru, dengan setiap indeks berisi daftar dengan gerakan yang diklaim akan dibuat lawan, diikuti dengan gerakan yang benar-benar mereka buat.
  • Dua argumen berikutnya akan memungkinkan bot Anda untuk menentukan apakah ini putaran "jujur" atau putaran "nyata". Jika itu adalah babak "jujur", keduanya akan menjadi Tidak Ada. Jika itu adalah babak "nyata", mereka akan, secara berurutan, gerakan yang dinyatakan lawan Anda akan dibuat, diikuti oleh langkah yang Anda nyatakan akan Anda buat.
  • Semua argumen atau bagian dari argumen yang mewakili gerakan akan menggunakan "R", "P", dan "S" untuk masing-masing mewakili batu, kertas, dan gunting.
  • Fungsi Anda harus mengembalikan "R" untuk rock, "P" untuk kertas, atau "S" untuk gunting. Bot yang memiliki kemampuan untuk mengembalikan nilai lain akan didiskualifikasi.
  • Setiap bot akan dijalankan melawan setiap bot lainnya 200 kali, dan itu sendiri 100 kali. Tujuannya adalah menjadi bot dengan poin terbanyak di akhir kompetisi.
  • Berkenaan dengan diskusi dalam komentar, pengiriman tidak boleh membaca dari atau menulis ke file apa pun, atau dengan cara apa pun menyabotase atau membaca kode lawan.

Contoh:

Ini adalah empat contoh bot yang saya kumpulkan dengan cepat. Mereka akan bergabung dengan kompetisi sebagai bot tambahan. Jika Anda kalah dari yang terakhir, Anda memiliki beberapa pekerjaan yang harus dilakukan.

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

Pengendali:

Dan inilah pengontrol yang akan saya gunakan. Kiriman baru akan diimpor di awal dan ditambahkan ke kamus 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

Skor Akhir:

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
Apa statusnya?
user1502040

Jawaban:


11

Tukang batu

Mencoba mengambil informasi tentang bot lain seperti seberapa jujur ​​mereka dan bagaimana mereka dipengaruhi oleh langkah pertama saya. Saya kemudian mencoba dan menemukan bot lain yang jelas yang mengikuti pola dan mengeksploitasi mereka untuk memberi saya lebih banyak poin. Akhirnya, Mason memiliki senjata rahasia: pengetahuan tentang masyarakat rahasia di mana kedua bot yang berpartisipasi saling bertarung untuk hasil imbang penuh, masing-masing memperoleh 500 poin. Sayangnya rahasianya agak ... Rahasia baik dan berubah setiap kali Mason melakukannya.

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: pembelajaran penguatan

Menggunakan pendekatan pembelajaran penguatan, menangani game ini dengan cara yang mirip dengan masalah bandit n-bersenjata. Ia melakukannya dengan dua cara: mencoba mempelajari deklarasi mana yang lebih baik terhadap masing-masing lawan dan berpegang teguh pada yang satu itu (berguna melawan bot konstan), dan mencoba mempelajari hasil dari berbagai gerakan dalam situasi serupa sebelumnya (serupa dalam hal permainan relatif , misalnya batu vs kertas mirip dengan kertas sebelumnya vs gunting). Asumsi awal optimis, sehingga pemain ini akan menganggap bahwa bersikap jujur ​​akan memberinya 3 poin dan berbohong akan memberi 2, dan karena itu akan selalu jujur ​​sampai terbukti sebaliknya.

Pembaruan: Hasil turnamen pertama menyoroti masalah dengan bot ini, yang merupakan ketidakmampuannya untuk mendeteksi pola dalam deklarasi lawannya (yang membuatnya bermain secara optimal terhadap rotator). Saya kemudian menambahkan komponen pencocokan pola ke kode untuk putaran jujur, yang menggunakan regex untuk mencari sufiks terpanjang dalam sejarah deklarasi lawan yang ada di suatu tempat sebelumnya dalam sejarah itu, dan langkah apa yang dimainkan setelah itu . Kami berasumsi bahwa lawan akan memainkan langkah yang sama lagi, dan menggunakan pembelajaran penguatan seperti sebelumnya untuk memutuskan apa jawaban terbaik untuk itu.

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

Cobalah online!


6

Saya tidak pernah benar-benar menggunakan python jadi saya yakin saya telah membuat kesalahan di suatu tempat.

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

Seharusnya memeriksa 10 putaran terakhir untuk melihat seberapa sering lawan berbohong, lalu memilih respons yang berbeda tergantung pada itu.


6

Ini bot adaptif saya. Ini menganalisis 2 gerakan terakhir lawan untuk menentukan apakah itu bot yang jujur ​​atau tidak dan bermain sesuai:

Sunting 1: Jika bot lain adalah bot konstan (mis. Selalu memainkan senjata yang sama) bot ini menghancurkannya dengan memainkan senjata yang menang dan jujur ​​pada saat yang sama.

Sunting 2: Detektor bot konstan yang ditingkatkan untuk bekerja dengan bot rotator juga.

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]

Jujur selama pemain lain, dan mendeteksi bot deterministik sederhana. Mainkan gerakan yang memaksimalkan nilai yang diharapkan, di mana kita sebagian besar mengejar poin kita, tetapi juga suka tidak memberikan poin kepada pemain lain. Tetapi poin sendiri lebih baik dengan faktor sepuluh, karenanya angka yang tidak biasa dalam valuefungsi. Gerakan lawan diharapkan sesuai dengan seberapa sering kita telah melihatnya sebelumnya dalam situasi ini (gerakan yang dinyatakan), tetapi gerakan yang baru-baru ini terlihat lebih berat daripada pergerakan yang terlihat sebelumnya. Untuk gerakan awal acak (situasi yang belum pernah terlihat sebelumnya) dan beberapa fuzzyness ekstra, bobotnya termasuk angka acak ekstra kecil.

Pembaruan: Gunakan hasil yang diharapkan juga di babak jujur. Untuk dapat melakukan ini, normalkan dan ambil poin tambahan yang mungkin diperhitungkan lawan untuk kejujuran - itu tidak dapat memengaruhi keputusan kita di babak nyata tetapi dibutuhkan sekarang. Saya mempertimbangkan untuk melakukan ini sejak awal, tetapi salah berpikir itu tidak akan bermanfaat. Saya melihat bahwa mungkin untuk memberikan trusting_botpoin lebih sedikit (tapi bot itu bukan lawan yang kuat), tetapi melewatkan bahwa poin tambahan bisa didapat dari rockbotpermainan bagus di babak jujur ​​meskipun permainannya di babak ini acak.


Ini sepertinya tidak selalu memberikan hasil.
user1502040

Saya pikir Anda if mydecl == None:salah.
user1502040

@ user1502040 Mengapa menurut Anda begitu? Saya tidak pernah mengamati masalah apa pun.
Christian Sievers


4

Pengkhianatan

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

Idenya adalah bahwa untuk 50 langkah pertama saya bermain jujur, dan kemudian setelah saya membujuk lawan untuk berpikir saya jujur, bermain tidak jujur, mencoba bermain apa yang akan melawan apa yang akan lawan mainkan (berdasarkan apakah dia jujur ​​atau tidak jujur) di masa lalu). Ketika saya mencapai titik di mana saya bermain sesering yang jujur ​​daripada tidak jujur, saya mengubah taktik dan memilih langkah yang paling mungkin dari lawan berdasarkan konfigurasi yang diketahui sebelumnya.


3
import random
def honestrandom(a, b, c, move):
    if move == None:
        return random.choice(["R","P","S"])
    return move

3

Nama Bot: I Remember How You Lie

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

Diuji untuk beberapa putaran 100 putaran, dan ternyata skor pemenang rata-rata sekitar 220. Agak jujur ​​saya pikir;)

Pertama kali bagi saya untuk berpartisipasi dalam tantangan KOTH, jadi saya pikir masih ada ruang untuk perbaikan


3

Gayung bersambut

Kontestan Axelrodian klasik: penuh harap, namun picik; sederhana, namun kuat. Ini bukan Dilema Tahanan dan saya tidak berusaha untuk memprediksi langkah lawan, jadi saya sangat meragukan itu akan benar-benar kompetitif. Tapi "bekerja sama" masih menghasilkan poin paling keseluruhan untuk kontestan, jadi saya pikir itu setidaknya akan lumayan.

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

Dua pertiga

Menggunakan strategi yang disebutkan Peter Taylor di Sandbox dan dalam komentar ini .

Ia menggunakan keseimbangan Nash .

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

Ini kesalahan untuk saya. Pada baris 13, kembalikan random.choice (bergerak). Saya pikir itu mungkin karena Anda menggunakan .choice di kamus. Sampai itu diperbaiki, saya khawatir pengiriman ini tidak valid.
Gryphon - Reinstate Monica

@Gryphon Ini bukan kamus, ini satu set.
LyricLy

Ah maaf. Saya hanya melihat kurung berlekuk-lekuk dan berpikir "kamus". Salahku. Adakah alasan mengapa random.choice salah pada baris itu?
Gryphon - Reinstate Monica

@Gryphon Tampaknya random.choicebergantung pada memilih nomor indeks acak dan kemudian mengembalikan objek dalam daftar di indeks itu. Karena set tidak memiliki pesanan, mereka juga tidak mendukung pengindeksan dan karenanya tidak berfungsi random.choice. Perbaikan sederhana untuk ini adalah untuk melemparkan set ke daftar sebelum memanggil random.choice.
LyricLy

Ah. Saya tidak punya python di komputer ini, jadi saya tidak bisa memperbaikinya sekarang, tapi saya akan memperbaikinya dalam kode saya ketika saya pulang. Jika @ mbomb007 akan memperbaikinya di sini, itu akan bagus.
Gryphon - Reinstate Monica

3

Pikiran yang dalam

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

Hanya beberapa catatan di atasnya:

  • DeepThought suka berpikir. Banyak. Saya minta maaf tentang hal itu, tetapi saya tidak benar-benar tahu cara memperbaikinya. Saya menyalahkan Python.
  • DeepThought mencoba jujur. Beeing jujur ​​memang memberikan Anda satu poin tambahan, yang sama dengan nilai yang diharapkan untuk RPS normale
  • Tapi: DeepThought mendapat rata-rata lebih dari 2 Poin per Game. Dia menggunakan beberapa deteksi untuk menemukan beberapa perilaku umum (seperti menipu, bersikap jujur, dll.), Dan beradaptasi sesuai dengan itu.
  • DeepThought adalah murni deterministik, sehingga akan menarik dirinya sendiri, karena itu akan selalu melakukan keputusan yang sama di kedua ujungnya.
  • Untuk memastikan tidak berbohong pada dirinya sendiri, ia memiliki deteksi khusus, seperti beberapa bot lain di sini juga. Ini sangat agresif, bahkan dengan asumsi benar setelah satu ronde (dan di ronde pertama juga). Pada dasarnya, selama gerakan lawan benar-benar milikku, aku akan menganggapnya sebagai pertandingan cermin.
  • Bagian yang menarik (dan bagian yang memiliki puluhan false-positive) adalah pemeriksaan untuk bot deterministik, yang hanya bergantung pada hasil sebelumnya yang menonjol. Itu memeriksa pencarian untuk setiap pola ukuran n, yang diulang dua kali, dan itu bisa menggambarkan gerakan n-1 terakhir, memprediksi klaim lawan dan bergerak di muka. Bagian ini butuh waktu, sayangnya.

Saya baru untuk keduanya, koth dan Python, jadi beri tahu saya jika saya mengacaukan sesuatu di bot ini. Saya tidak berpikir itu bisa mengalahkan pembelajaran yang diperkuat (karena saya kira itu akan belajar gerakan saya terlalu cepat), tapi mari kita coba.

Saya suka tantangan ini, dan jika saya menemukan waktu, saya ingin menambahkan pendekatan komputasi organik (meskipun mungkin ada tekanan yang terlalu sedikit pada dimensi yang lebih tinggi). Apakah diizinkan menambahkan beberapa saran? Atau apakah dilarang untuk mencegah bot utama Anda dengan memasukkan beberapa yang hanya bertujuan untuk kalah dengan bot utama Anda?

EDIT: Memperbaiki kesalahan ketik kode yang menandai saya sebagai penutur bahasa Inggris yang bukan penutur asli


Tidak dilarang memposting banyak entri, tetapi dilarang memposting entri yang menopang bot yang berbeda (bahkan yang bukan milik Anda). Boleh saja kalah dari bot lain, asalkan bukan karena desain.
Gryphon - Reinstate Monica

Saya mendapat kesalahan ketika menjalankan ini, sebagai baris ke-32 dari fungsi DeepThought Anda, return resultmembutuhkan indentasi tambahan. Saya percaya itu harus di dalam raksasa jika pernyataan itu segera setelah, karena variabel returnhanya dinyatakan dalam pernyataan itu. Saya membuat modifikasi ini dalam kode saya, dan sekarang berjalan tanpa kesalahan. Jika Anda tidak keberatan melakukan perubahan itu di sini, itu akan bagus.
Gryphon - Reinstate Monica

3
Anda tampaknya mengacaukan keadaan generator acak global, yang mungkin tidak baik-baik saja. Aku dianggap melakukan hal yang sama, dan menemukan solusi ini: membuat objek acak baru dengan R=random.Random(seed)dan menggunakannya seperti ini: R.choice(...).
Christian Sievers

@Gryphon diperbaiki. Mungkin beberapa kesalahan yang terjadi ketika mengubah dari skrip lokal saya ke se, di mana setiap orang harus diintensifkan satu kali tambahan
alex berne

1
@alexberne Anda dapat memilih kode yang Anda tempel dan klik {}tombol pada bilah alat untuk secara otomatis membuat indentasi setiap baris.
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

Cukup tanyakan "apakah kita pernah ke sini sebelumnya", dan memilih langkah yang akan memberikan hasil rata-rata terbaik dalam permainan sebelumnya.

Sunting: Klub Kejujuran.Saya telah menambahkan satu blok kode kecil karena bot lain (tukang batu) telah bekerja dengan sangat baik dengan membentuk klub rahasia dengan dirinya sendiri. Namun perhatikan, bahwa bermain jujur ​​melawan lawan yang jujur ​​memiliki rata-rata imbalan yang persis sama ketika bermain melawan diri sendiri, dan mungkin ada manfaat bersama yang lebih luas yang bisa didapat juga?

Sunting2: Pada saat penulisan kedua bot di depan saya sama-sama mengeksploitasi rotator, jadi saya akan menambahkan satu blok kode lagi untuk melompat pada kereta musik itu juga. Saya kira kode saya harus tampak sekolah yang cukup tua - menempel pada konstruksi akrab yang ditemukan dalam bahasa pemrograman karena saya benar-benar tidak tahu 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: THE Exploiter Jujur

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

Saya baru menyadari bahwa saya downvoted oleh misclick, maaf. Akan dibatalkan saat Anda mengedit. (Tidak bisa mengubahnya dengan cara lain.)
Christian Sievers


@ChristianSievers terima kasih!
Cinaski

2

Thompson

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]

Entri yang menarik. Saya akan menjalankannya segera, harus dapat memposting hasil sore ini.
Gryphon - Reinstate Monica

OK, saya sedikit membalikkan parameter.
user1502040

Mengerti. Maaf butuh waktu lama untuk memperbarui, hanya saja, setiap kali hampir selesai, seseorang memperbarui bot mereka, atau saya mendapatkan yang baru, dan saya harus menjalankannya lagi.
Gryphon - Reinstate Monica

@Gryphon Anda bisa menyimpan tabel hasil semua pair-up, jadi ketika bot diperbarui, Anda hanya perlu menjalankan 200 * (num_bots - 1) + 100 pertandingan baru.
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

Saya akan mencoba bot sederhana yang mengulang permainan terakhir lawannya dalam kondisi ini


Selamat datang di 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]

Idenya di sini adalah untuk memaksimalkan skor saat bermain sendiri sementara masih kompetitif secara acak selama tahap lain melawan bot buruk lainnya.


1
Kata itu isadalah kata kunci, jadi ini tidak valid.
Erik the Outgolfer

@EriktheOutgolfer terima kasih :)
Stephen

1

Dx

Saya hanya menulis bot ini sehingga saya dapat memiliki smiley di nama bot saya 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

Semua orang berbohong

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"

Itu terletak pada gerakannya ("Aku akan bermain Gunting!"), Dan menganggap lawan juga berbohong dan bahwa mereka akan mencoba untuk mengalahkan apa yang saya katakan akan bergerak saya ("hmm, Rock mengalahkan Gunting jadi saya bermain itu "), tetapi saya benar-benar memainkan gerakan yang mengalahkan gerakan itu (" Kertas! Kejutan! ").


3
Kedengarannya seperti level pertama dari strategi Iocaine Powder bagiku :-) "Sekarang, orang yang pandai akan memasukkan racun ke dalam piala sendiri, karena dia akan tahu bahwa hanya orang bodoh yang akan meraih apa yang diberikan padanya. Aku tidak bodoh sekali, jadi aku jelas tidak bisa memilih anggur di depanmu. Tapi kau pasti tahu aku bukan orang bodoh, kau akan mengandalkannya, jadi aku jelas tidak bisa memilih anggur di depanku .. . "
Antony

1

Bot Percaya

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

Selalu mengaku melempar gunting, tetapi akan melakukan apa pun yang mengalahkan apa yang dikatakan lawan. Akan andal menggambar dengan sendirinya.


Ini akan lebih efektif jika selalu jujur ​​terhadap dirinya sendiri.
Gryphon - Pasang kembali Monica

@Gryphon Mungkin, tapi saya tidak python cukup baik untuk ingin mencoba membuat sesuatu yang bekerja sama seperti itu.
ATaco


1

Nama bot: Pembohong Pembohong

Tidak bisa berhenti berbohong

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

Diasumsikan lawan akan jujur ​​dan mencoba untuk mengalahkan mereka, tetapi menolak untuk bermain rock.

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
Ini tampaknya salah karena, pada baris terakhir Anda, "P", "S" tidak di dalam tanda kurung (bukan daftar). Saya mengubahnya dalam versi saya, tetapi jika Anda bisa melakukan hal yang sama di sini, itu akan bagus. Terima kasih.
Gryphon - Reinstate Monica

Tidakkah ini akan kalah mengerikan dari gunting konstan?
Wildcard

@ Kartu Memori ya, tetapi itu akan cukup baik terhadap bot kertas
Slepz

1

Nama bot: dontlietome

Menentukan apakah lawan berbohong atau tidak tergantung pada berapa kali lawan berbohong dalam 10 putaran terakhir. Memilih bergerak tergantung pada apakah lawan berbohong atau tidak. Jika lawan bertekad berbohong, maka mainkan isyarat itu.

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

Pada baris "if is_trustworthy (opp_moves, self.length):", self tidak didefinisikan. Selain itu, pada baris "return los_against_map [opp_hint]", los_against_map juga tidak didefinisikan. Panjang diri tampaknya dipecahkan dengan menghilangkan diri. tapi masalah lainnya masih ada. Sampai itu diperbaiki, saya khawatir ini tidak valid.
Gryphon - Reinstate Monica

Ups, saya menulis ini menggunakan Object dan saya lupa menghapus beberapa referensi mandiri dan menyalin kode sepenuhnya. Saya akan memperbaikinya segera setelah saya pulang.
coolioasjulio

BAIK. Jika itu hanya kesalahan kecil, saya memperbaikinya (seperti yang saya miliki di beberapa bot lain, dan akan melakukannya jika itu hanya masalah diri), tetapi fungsi yang hilang adalah cerita yang berbeda.
Gryphon - Reinstate Monica

@Gryphon saya memperbaiki bug. (menghapus diri sendiri, menambahkan referensilost_against_map , dan memperbaiki pernyataan if memeriksa jika jujur)
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

Hanya sedikit lebih baik daripada entri saya sebelumnya ...

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 pada steroid

Saya pikir saran yang dibuat oleh @ user1502040 dalam komentar harus diikuti. Kalau tidak, bot ini akan memiliki keuntungan yang saya anggap tidak adil. Saya serahkan supaya perbedaan yang dibuat bisa dinilai. Dengan pembibitan acak yang disarankan steroid akan dinetralkan dan bot akan setara dengan csbot, jadi hanya satu yang harus berpartisipasi dalam kontes.

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.