Đá trung thực, giấy, kéo


58

Nhiều người coi RPS là một trò chơi may rủi. Nếu cả hai người chơi chơi không thể đoán trước, chiến lược tốt nhất là chơi ngẫu nhiên. Tuy nhiên, hãy giới thiệu một chút về khả năng dự đoán cho nó.

Mỗi bot sẽ có cơ hội nói với bot khác những gì nó sẽ chơi cùng một lúc. Sau đó, có một khoảng dừng trong đó mỗi bot sẽ biết những gì người chơi khác đã thông báo. Nếu nó chơi vũ khí đó, nó tuyên bố nó sẽ ghi được một điểm ngoài số điểm của nó cho một trận thua hoặc hòa.

Một chiến thắng có giá trị hai điểm, một trận hòa, một điểm và thua 0 điểm.

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

Thành thật là lợi ích tốt nhất của bạn (nhưng cũng phải chắc chắn rằng đối thủ của bạn không tin bạn).

Các trận đấu sẽ được chơi theo thể thức vòng tròn và mục tiêu sẽ là tối đa hóa tổng số điểm của bạn qua các trận đấu bạn chơi.

Định dạng I / O:

  • Bot của bạn sẽ là một hàm Python 2.7 có 4 đối số và phải có một tên duy nhất (sẽ được sử dụng để thể hiện trình của bạn).
  • Hai đối số đầu tiên sẽ luôn luôn theo thứ tự: các bước đi trong quá khứ của đối thủ, tiếp theo là các bước đi trong quá khứ của bạn. Đây sẽ là một danh sách theo thứ tự từ vòng đầu tiên đến vòng gần đây nhất, với mỗi chỉ số chứa một danh sách với nước đi mà đối thủ tuyên bố họ sẽ thực hiện, tiếp theo là di chuyển mà họ thực sự thực hiện.
  • Hai đối số tiếp theo sẽ cho phép bot của bạn xác định xem đây là vòng "trung thực" hay vòng "thực". Nếu đó là một vòng "trung thực", cả hai sẽ là Không. Nếu đó là một vòng "thực sự", theo thứ tự, đối thủ của bạn sẽ tuyên bố họ sẽ thực hiện, tiếp theo là động tác bạn tuyên bố bạn sẽ thực hiện.
  • Tất cả các đối số hoặc các phần của các đối số đại diện cho di chuyển sẽ sử dụng "R", "P" và "S" để thể hiện tương ứng với đá, giấy và kéo.
  • Chức năng của bạn sẽ trả về "R" cho đá, "P" cho giấy hoặc "S" cho kéo. Các bot có khả năng trả về các giá trị khác sẽ bị loại.
  • Mỗi bot sẽ được chạy với tất cả các bot khác 200 lần, và chính nó 100 lần. Mục tiêu là trở thành bot có nhiều điểm nhất khi kết thúc cuộc thi.
  • Liên quan đến thảo luận trong các bình luận, bài nộp không được đọc hoặc ghi vào bất kỳ tệp nào, hoặc bằng mọi cách phá hoại hoặc đọc mã của đối thủ.

Ví dụ:

Đây là bốn ví dụ bot tôi kết hợp nhanh chóng. Họ sẽ tham gia cuộc thi như những bot bổ sung. Nếu bạn thua đến người cuối cùng, bạn có một số việc phải làm.

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

Điều khiển:

Và đây là bộ điều khiển tôi sẽ sử dụng. Các bài nộp mới sẽ được nhập vào đầu và thêm vào từ điển 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

Điểm cuối cùng:

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
Tình trạng là gì?
user1502040

Câu trả lời:


11

Mason

Cố gắng thu thập thông tin về các bot khác như mức độ trung thực của chúng và cách chúng bị ảnh hưởng bởi bước đi đầu tiên của tôi. Sau đó tôi thử và tìm các bot rõ ràng khác theo mô hình và khai thác chúng để cho tôi nhiều điểm hơn. Cuối cùng, Mason có một vũ khí bí mật: kiến ​​thức về một xã hội bí mật, nơi cả hai bot tham gia cùng nhau rút thăm, giành được 500 điểm mỗi cái. Thật không may, bí mật là ... Bí mật và thay đổi mỗi khi Mason thực hiện.

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: học tăng cường

Sử dụng một phương pháp học tập củng cố, giải quyết trò chơi này theo cách tương tự như vấn đề tên cướp vũ trang n. Nó làm như vậy theo hai cách: cố gắng tìm hiểu tuyên bố nào tốt hơn đối với từng đối thủ và bám sát vào đối thủ đó (hữu ích với các bot không đổi) và cố gắng tìm hiểu kết quả của các động tác khác nhau trong các tình huống tương tự trước đó (tương tự như các lần chơi tương đối , ví dụ rock vs paper tương tự như giấy trước so với cắt kéo). Các giả định ban đầu rất lạc quan, vì vậy người chơi này sẽ cho rằng trung thực sẽ cho nó 3 điểm và nói dối sẽ cho 2, và do đó sẽ luôn trung thực cho đến khi được chứng minh khác đi.

Cập nhật: Kết quả giải đấu đầu tiên nêu bật một vấn đề với bot này, đó là không có khả năng phát hiện các mẫu trong tuyên bố của đối thủ (điều này khiến nó chơi dưới chuẩn chống lại các công cụ quay vòng). Sau đó, tôi đã thêm một thành phần khớp mẫu vào mã cho các vòng trung thực, sử dụng biểu thức chính quy để tìm hậu tố dài nhất trong lịch sử khai báo đối thủ có ở đâu đó trong lịch sử đó và di chuyển nào được chơi sau đó . Chúng tôi giả định rằng đối thủ sẽ chơi cùng một động tác một lần nữa và sử dụng học tăng cường như trước để quyết định câu trả lời tốt nhất cho câu hỏi đó là gì.

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

Hãy thử trực tuyến!


6

Tôi chưa bao giờ thực sự sử dụng trăn nhiều nên tôi chắc chắn mình đã mắc lỗi ở đâu đó.

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

Cần kiểm tra 10 vòng cuối để xem đối thủ có thường xuyên nói dối hay không, sau đó chọn một phản ứng khác nhau tùy theo điều đó.


6

Đây là bot thích ứng của tôi. Nó phân tích 2 động tác cuối cùng của đối thủ để xác định xem đó có phải là một bot trung thực hay không và chơi theo đó:

Chỉnh sửa 1: Nếu bot khác là bot không đổi (nghĩa là luôn chơi cùng một vũ khí) thì bot này sẽ nghiền nát nó bằng cách chơi vũ khí chiến thắng và trung thực cùng một lúc.

Chỉnh sửa 2: Cải thiện trình phát hiện bot liên tục để làm việc với các bot quay.

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]

Hãy trung thực miễn là người chơi khác và phát hiện các bot xác định đơn giản. Chơi di chuyển tối đa hóa giá trị mong đợi, nơi chúng tôi chủ yếu đi cho điểm của mình, nhưng cũng muốn không cho điểm cho người chơi khác. Nhưng điểm riêng tốt hơn theo hệ số mười, do đó các số bất thường trong valuehàm. Các động thái của đối thủ được dự kiến ​​theo mức độ thường xuyên chúng ta đã thấy chúng trước đây trong tình huống này (các động thái được tuyên bố), nhưng các động thái được nhìn thấy gần đây có trọng số hơn các động thái được thấy trước đó. Đối với các bước di chuyển ban đầu ngẫu nhiên (các tình huống chưa từng thấy trước đây) và một số độ mờ thêm, các trọng số bao gồm các số ngẫu nhiên nhỏ thêm.

Cập nhật: Sử dụng kết quả dự kiến ​​cũng trong vòng trung thực. Để có thể làm điều này, hãy bình thường hóa và lấy điểm bổ sung mà đối thủ có thể tính đến sự trung thực - điều đó không thể ảnh hưởng đến sự phân rã của chúng ta trong vòng đấu thực sự nhưng hiện tại cần thiết. Tôi đã xem xét làm điều này ngay từ đầu, nhưng nghĩ sai rằng nó sẽ không đáng giá. Tôi thấy rằng có thể cho trusting_botít điểm hơn (nhưng dù sao bot đó cũng không phải là đối thủ mạnh), nhưng đã bỏ lỡ rằng có thể kiếm thêm điểm rockbotnhờ chơi tốt trong vòng trung thực mặc dù lối chơi của nó ở vòng này là ngẫu nhiên.


Điều này dường như không phải lúc nào cũng trả lại một kết quả.
user1502040

Tôi nghĩ rằng bạn if mydecl == None:là sai lầm.
user1502040

@ user1502040 Tại sao bạn nghĩ vậy? Tôi chưa bao giờ quan sát bất kỳ vấn đề.
Christian Sievers


4

Sự phản bội

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

Ý tưởng là trong 50 động tác đầu tiên tôi chơi một cách trung thực, và sau đó một khi tôi đã dụ dỗ đối thủ nghĩ rằng tôi trung thực, chơi không trung thực, cố gắng chơi những gì đối thủ sẽ chơi (dựa trên việc anh ta trung thực hay không trung thực trong quá khứ). Khi tôi đạt đến điểm mà tôi thường chơi một cách trung thực hơn là không trung thực, tôi thay đổi chiến thuật và chọn cách di chuyển có khả năng nhất của đối thủ dựa trên các cấu hình đã biết trước đó.


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

3

Tên Bot: Tôi nhớ bạn nói dối như thế nào

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

Đã thử nghiệm cho một số lượt chạy 100 vòng, và hóa ra trung bình người chiến thắng đạt khoảng 220 điểm. Tôi nghĩ khá trung thực;)

Lần đầu tiên tôi tham gia vào các thử thách KOTH, vì vậy tôi nghĩ vẫn còn chỗ để cải thiện


3

Tít cho tất

Thí sinh cổ điển Axelrodian: hy vọng, nhưng nhỏ mọn; đơn giản, nhưng mạnh mẽ. Đây không phải là vấn đề nan giải của tù nhân và tôi đã không cố gắng dự đoán động thái của đối thủ, vì vậy tôi rất nghi ngờ rằng nó sẽ thực sự cạnh tranh. Nhưng "hợp tác" vẫn tạo ra những điểm chung nhất cho các thí sinh, vì vậy tôi nghĩ rằng ít nhất nó sẽ làm được điều đó.

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

Hai phần ba

Sử dụng chiến lược mà Peter Taylor đã đề cập trong Sandbox và trong bình luận này .

Nó sử dụng trạng thái cân bằng 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

Lỗi này cho tôi. Trên dòng 13, trả về Random.choice (di chuyển). Tôi nghĩ có lẽ vì bạn đang sử dụng .choice trên từ điển. Cho đến khi nó được sửa, tôi sợ bài này không hợp lệ.
Gryphon - Phục hồi Monica

@Gryphon Nó không phải là một cuốn từ điển, nó là một bộ.
LyricLy

Ồ xin lỗi. Tôi chỉ thấy ngoặc vuông và nghĩ "từ điển". Lỗi của tôi. Bất cứ ý tưởng tại sao Random.choice bị lỗi trên dòng đó?
Gryphon - Phục hồi Monica

@Gryphon Có vẻ như random.choicedựa vào việc chọn một số chỉ mục ngẫu nhiên và sau đó trả lại đối tượng trong danh sách tại chỉ mục đó. Vì các bộ không có đơn đặt hàng, chúng cũng không hỗ trợ lập chỉ mục và do đó không hoạt động random.choice. Một sửa chữa đơn giản cho việc này sẽ là đặt tập hợp vào danh sách trước khi gọi random.choice.
LyricLy

Ah. Tôi không có python trên máy tính này, vì vậy tôi không thể sửa nó ngay bây giờ, nhưng tôi sẽ sửa nó trong mã của tôi khi tôi về nhà. Nếu @ mbomb007 sẽ sửa nó ở đây, điều đó thật tuyệt.
Gryphon - Phục hồi Monica

3

Suy nghĩ sâu sắc

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

Chỉ cần một vài lưu ý về nó:

  • DeepTh Think thích suy nghĩ. Rất nhiều. Tôi xin lỗi về điều đó, nhưng tôi không thực sự biết cách khắc phục nó. Tôi đổ lỗi cho Python.
  • DeepTh Think cố gắng trung thực. Beeing trung thực cung cấp cho bạn một điểm quảng cáo, giống như giá trị mong đợi cho RPS bình thường
  • Nhưng: DeepTh Think nhận được trung bình thậm chí nhiều hơn 2 Điểm mỗi Trò chơi. Anh ta sử dụng một số phát hiện để tìm ra một số hành vi phổ biến (như lừa, nuôi ong trung thực, v.v.) và thích nghi theo đó.
  • DeepTh Think hoàn toàn mang tính quyết định, do đó, nó sẽ chống lại chính nó, bởi vì nó sẽ luôn luôn thực hiện cùng một quyết định ở cả hai đầu.
  • Để chắc chắn không nói dối chính nó, nó cũng có một phát hiện đặc biệt, giống như một số bot khác ở đây. Đây là một trong những rất tích cực, thậm chí giả định là đúng sau một vòng (và trong vòng đầu tiên, quá). Về cơ bản, miễn là đối thủ di chuyển chính xác là của tôi, tôi sẽ cho rằng đó là một trận đấu gương.
  • Phần thú vị (và phần có hàng tá dương tính giả) là phần kiểm tra bot xác định, điều này chỉ phụ thuộc vào kết quả chiếm ưu thế của chính nó. Việc kiểm tra tìm kiếm bất kỳ mẫu nào có kích thước n, được lặp lại hai lần và có thể mô tả các động tác n-1 cuối cùng, dự đoán yêu cầu của đối thủ và di chuyển trước. Phần này đang mất một thời gian, thật đáng buồn.

Tôi mới sử dụng cả hai, koth và Python, vì vậy hãy nói cho tôi biết nếu tôi làm hỏng bất cứ điều gì trong bot này. Tôi không nghĩ rằng nó có thể đánh bại việc học tăng cường (vì tôi đoán nó sẽ học được động tác của tôi quá nhanh), nhưng hãy thử xem.

Tôi thích thử thách này và nếu tôi tìm thấy một chút thời gian, tôi muốn thêm một phê duyệt điện toán hữu cơ (althogh có thể có quá ít áp lực lên các chiều cao hơn). Được phép thêm nhiều đề xuất? Hoặc nó bị cấm để ngăn chặn bot chính của bạn bằng cách chèn một số chỉ nhằm mục đích mất cho chính của bạn?

EDIT: Đã sửa lỗi chính tả mã đã làm tôi say mê như người nói tiếng Anh không phải là người bản ngữ


Không được phép đăng nhiều mục, nhưng không được phép đăng một mục có đạo cụ lên một bot khác (thậm chí một mục không phải của riêng bạn). Bạn có thể thua một bot khác, miễn là không phải do thiết kế.
Gryphon - Tái lập Monica

Tôi đã gặp lỗi khi chạy này, vì dòng thứ 32 của chức năng DeepTh Think của bạn, return resultyêu cầu một thụt lề bổ sung. Tôi tin rằng nó phải nằm trong câu lệnh khổng lồ nếu ngay sau đó, vì biến returnchỉ được khai báo trong câu lệnh đó. Tôi đã thực hiện sửa đổi này trong mã của mình và bây giờ nó chạy mà không gặp lỗi. Nếu bạn không phiền khi thực hiện thay đổi ở đây, điều đó thật tuyệt.
Gryphon - Tái lập Monica

3
Bạn dường như đang rối tung với trạng thái của trình tạo ngẫu nhiên toàn cầu, điều này có lẽ không ổn. Tôi đã xem xét thực hiện một điều tương tự, và tìm thấy giải pháp này: tạo một đối tượng ngẫu nhiên mới với R=random.Random(seed)và sử dụng nó như thế này : R.choice(...).
Christian Sievers

@Gryphon cố định. Có lẽ một số lỗi xảy ra khi chuyển đổi từ tập lệnh cục bộ của tôi sang se, trong đó mọi thứ phải được thêm vào một lần nữa
alex berne

1
@alexberne Bạn có thể chọn mã bạn đã dán và nhấp vào {}nút trên thanh công cụ để tự động thụt lề mỗi dòng.
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_b Before

Đơn giản chỉ cần hỏi "chúng ta đã từng đến đây chưa" và chọn nước đi có kết quả trung bình tốt nhất trong bất kỳ trò chơi nào trước đó.

Chỉnh sửa: Câu lạc bộ trung thực. Tôi đã thêm một khối mã nhỏ vì một bot (thợ xây) khác đã làm rất tốt bằng cách thành lập một câu lạc bộ bí mật với chính nó. Tuy nhiên, lưu ý rằng chơi trung thực với các đối thủ trung thực có trung bình chính xác cùng một mức chi trả khi chơi với chính mình, và có lẽ cũng có những lợi ích chung rộng lớn hơn?

Edit2: Tại thời điểm viết hai bot phía trước tôi đều khai thác công cụ quay vòng, vì vậy tôi cũng sẽ thêm một khối mã khác để nhảy vào bandwagon đó. Tôi đoán mã của tôi phải có vẻ khá cũ - bám vào các cấu trúc quen thuộc được tìm thấy trong bất kỳ ngôn ngữ lập trình nào vì tôi thực sự không biết 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: Nhà khai thác trung thực

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

Tôi chỉ nhận ra rằng tôi đã đánh giá thấp bằng cách nhấn nhầm, xin lỗi. Sẽ hoàn tác khi bạn chỉnh sửa. (Không thể thay đổi nó ngay lập tức.)
Christian Sievers

@ChristianSievers đã chỉnh sửa
Cinaski

@ChristianSievers cảm ơn bạn!
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]

Thú vị nhập cảnh. Tôi sẽ chạy nó sớm, sẽ có thể đăng kết quả vào chiều nay.
Gryphon - Phục hồi Monica

OK, tôi hơi quay lại các tham số.
user1502040

Hiểu rồi. Xin lỗi, mất quá nhiều thời gian để cập nhật, chỉ là, mỗi khi nó sắp hoàn thành, ai đó sẽ cập nhật bot của họ hoặc tôi nhận được một cái mới và tôi phải chạy lại nó.
Gryphon - Phục hồi Monica

@Gryphon bạn có thể giữ một bảng kết quả của tất cả các cặp, vì vậy khi bot được cập nhật, bạn chỉ phải chạy 200 * (num_bots - 1) + 100 trận đấu mới.
user1502040

2

gương

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

Tôi sẽ thử một bot đơn giản làm lại lần chơi cuối cùng của đối thủ trong những điều kiện này


Chào mừng đến với 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]

Ý tưởng ở đây là tối đa hóa điểm số khi chơi bản thân trong khi vẫn cạnh tranh ngẫu nhiên trong các giai đoạn khác với các bot xấu khác.


1
Từ isnày là một từ khóa, do đó, điều này là không hợp lệ.
Erik the Outgolfer

@EriktheOutgolfer cảm ơn :)
Stephen

1

Dx

Tôi chỉ viết bot này để tôi có thể có một nụ cười trong tên bot xD của tôi.

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

Mọi người đều nói dối

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"

Nó nói về động thái của nó ("Tôi sẽ chơi Kéo!"), Và giả sử đối thủ cũng nói dối và họ sẽ cố gắng đánh bại những gì tôi nói rằng bước đi của tôi sẽ là ("hmm, Rock đập Kéo nên tôi đang chơi đó "), nhưng tôi thực sự chơi động tác đánh bại bước di chuyển đó (" Giấy! Bất ngờ! ").


3
Nghe có vẻ như cấp độ đầu tiên của chiến lược Iocaine Powder đối với tôi :-) "Bây giờ, một người đàn ông thông minh sẽ đặt chất độc vào chiếc cốc của mình, bởi vì anh ta sẽ biết rằng chỉ có một kẻ ngốc vĩ đại mới đạt được những gì anh ta đã đưa ra. Tôi không phải là một kẻ ngốc vĩ đại, vì vậy tôi rõ ràng không thể chọn rượu trước mặt bạn. Nhưng bạn phải biết tôi không phải là một kẻ ngốc vĩ đại, bạn sẽ tin vào nó, vì vậy tôi rõ ràng không thể chọn rượu trước mặt tôi .. . "
Antony

1

Bot đáng tin cậy

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

Luôn tuyên bố ném kéo, nhưng sẽ làm bất cứ điều gì đánh bại những gì đối thủ nói. Sẽ đáng tin cậy vẽ với chính nó.


Điều này sẽ hiệu quả hơn nếu nó luôn trung thực với chính nó.
Gryphon - Tái lập Monica

@Gryphon Có lẽ, nhưng tôi không đủ trăn để muốn thử làm một cái gì đó hợp tác như thế.
ATaco

Đừng bận tâm.
Gryphon - Phục hồi Monica

1

Tên bot: Kẻ nói dối nói dối

Không thể ngừng nói dối.

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

Giả sử đối thủ sẽ trung thực và cố gắng đánh bại họ, nhưng từ chối chơi đá.

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
Điều này dường như có lỗi vì, trên dòng cuối cùng của bạn, "P", "S" không nằm trong dấu ngoặc vuông (không phải là danh sách). Tôi đã thay đổi điều đó trong phiên bản của tôi, nhưng nếu bạn có thể làm điều tương tự ở đây, nó sẽ rất tuyệt. Cảm ơn.
Gryphon - Tái lập Monica

Điều này sẽ không mất đi khủng khiếp để kéo liên tục?
tự đại diện

@Wildcard có, nhưng nó sẽ hoạt động khá tốt với bot giấy
Slepz

1

Tên bot: dontlietome

Xác định xem đối thủ có nói dối hay không tùy thuộc vào số lần đối thủ nói dối trong 10 vòng gần nhất. Chọn di chuyển tùy thuộc vào việc đối thủ có nói dối hay không. Nếu đối thủ quyết tâm nói dối, thì hãy chơi những gì gợi ý.

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

Trong dòng "if is_trustworthy (opp_move, self.length):", self không được xác định. Ngoài ra, trong dòng "return loss_against_map [opp_hint]", loss_against_map cũng không được xác định. Self.length dường như được giải quyết bằng cách loại bỏ cái tôi. nhưng vấn đề khác vẫn đứng vững. Cho đến khi nó được sửa, tôi sợ điều này không hợp lệ.
Gryphon - Phục hồi Monica

Rất tiếc Tôi đã viết điều này bằng cách sử dụng một Object và tôi đã quên xóa một số tham chiếu tự và sao chép hoàn toàn mã. Tôi sẽ sửa chúng ngay khi về đến nhà.
coolioasjulio

ĐỒNG Ý. Nếu đó chỉ là một lỗi nhỏ, tôi đã sửa nó (như tôi có trong một số bot khác, và sẽ có nếu đó chỉ là vấn đề tự), nhưng một chức năng bị thiếu là một câu chuyện khác.
Gryphon - Phục hồi Monica

@Gryphon Mình sửa lỗi. (đã tự xóa, thêm tham chiếu lost_against_mapvà sửa lỗi kiểm tra câu lệnh if nếu vòng trung thực)
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

Trung bình

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

Chỉ tốt hơn một chút so với mục trước đây của tôi ...

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 trên steroid

Tôi nghĩ rằng đề xuất mà @ user1502040 đưa ra trong các bình luận nên được tuân theo. Nếu không, bot này sẽ có một lợi thế mà tôi sẽ coi là không công bằng. Tôi gửi nó để có thể đánh giá sự khác biệt mà nó tạo ra. Với việc gieo hạt ngẫu nhiên được đề xuất, các steroid sẽ được trung hòa và bot sẽ tương đương csbot, vì vậy chỉ có một người nên tham gia cuộc thi.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.