Pedra honesta, papel e tesoura


58

Muitas pessoas consideram o RPS um jogo de sorte. Se ambos os jogadores jogam imprevisivelmente, a melhor estratégia é jogar aleatoriamente. No entanto, vamos apresentar um pouco de previsibilidade.

Cada bot terá a chance de dizer ao outro bot o que será reproduzido simultaneamente. Depois, há uma pausa em que cada bot saberá o que o outro jogador anunciou. Se jogar essa arma, anunciou que marcará um ponto, além dos pontos, por perda ou empate.

Uma vitória vale dois pontos, um empate, um ponto e uma perda de 0 pontos.

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

É do seu interesse ser honesto (mas também para garantir que seu oponente não acredite em você).

As partidas serão disputadas no formato round robin, e o objetivo será maximizar sua própria pontuação total nas partidas que você jogar.

Formato de E / S:

  • Seu bot será uma função Python 2.7 que recebe 4 argumentos e deve ter um nome exclusivo (que será usado para representar sua submissão).
  • Os dois primeiros argumentos sempre serão, em ordem: os movimentos passados ​​do oponente, seguidos pelos movimentos passados. Essa será uma lista da ordem da primeira à rodada mais recente, com cada índice contendo uma lista com a jogada que o oponente afirmou que faria, seguida pela jogada que realmente fez.
  • Os próximos dois argumentos permitirão ao seu bot determinar se esta é uma rodada "honesta" ou uma rodada "real". Se for uma rodada "honesta", os dois serão Nenhum. Se for uma rodada "real", eles serão, em ordem, o lance que o seu oponente declarou que faria, seguido pelo lance que você declarou que faria.
  • Todos os argumentos ou partes de argumentos que representam movimentos usarão "R", "P" e "S" para representar pedra, papel e tesoura, respectivamente.
  • Sua função deve retornar um "R" para pedra, um "P" para papel ou um "S" para tesoura. Os robôs que têm a capacidade de retornar outros valores serão desqualificados.
  • Cada bot será executado 200 vezes contra todos os outros bot e 100 vezes. O objetivo é ser o bot com mais pontos no final da competição.
  • No que diz respeito à discussão nos comentários, as submissões não podem ser lidas ou gravadas em nenhum arquivo, nem sabotar ou ler o código do oponente.

Exemplos:

Estes são quatro exemplos de bots que eu montei rapidamente. Eles entrarão na competição como bots adicionais. Se você perder para o último, terá algum trabalho a fazer.

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

Controlador:

E aqui está o controlador que eu vou usar. Novos envios serão importados no início e adicionados ao dicionário 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

Pontuações finais:

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

11
Qual é o status?
precisa saber é o seguinte

Respostas:


11

Pedreiro

Tenta coletar informações sobre outros bots, como quão honestos eles são e como são afetados pelo meu primeiro movimento. Em seguida, tento encontrar outros bots óbvios que seguem um padrão e os exploro para me dar mais pontos. Finalmente, o Mason tem uma arma secreta: o conhecimento de uma sociedade secreta na qual os dois robôs participantes se empolgam mutuamente, ganhando 500 pontos cada. Infelizmente, o segredo é bastante ... Bem secreto e muda toda vez que o maçom muda.

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: aprendizagem por reforço

Utiliza uma abordagem de aprendizado reforçado, enfrentando esse jogo de maneira semelhante ao problema dos bandidos n-armados. Ele o faz de duas maneiras: tenta aprender qual declaração é melhor contra cada oponente e se mantém fiel àquela (útil contra robôs constantes) e tenta aprender o resultado de vários movimentos em situações semelhantes anteriores (semelhante em relação às jogadas relativas , por exemplo, pedra x papel é semelhante a um papel anterior x tesoura). As premissas iniciais são otimistas, então esse jogador assume que ser honesto dará 3 pontos e mentir dará 2 e, portanto, sempre será honesto até prova em contrário.

Atualização: Os primeiros resultados do torneio destacaram um problema com este bot, que era sua incapacidade de detectar padrões nas declarações de seus oponentes (o que o fazia jogar subótimamente contra rotadores). Em seguida, adicionei um componente de correspondência de padrão ao código para as rodadas honestas, que usa uma expressão regular para procurar o sufixo mais longo da história das declarações do oponente que está presente em algum lugar anteriormente nessa história, e qual jogada foi executada depois disso . Assumimos que o oponente fará o mesmo movimento novamente e use o aprendizado por reforço como antes para decidir qual deveria ser a melhor resposta.

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

Experimente online!


6

Eu realmente nunca usei muito python, então tenho certeza que cometi um erro em algum lugar.

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

Ele deve checar as últimas 10 rodadas para ver com que frequência o oponente mentiu e escolher uma resposta diferente, dependendo disso.


6

Aqui está o meu bot adaptável. Ele analisa os 2 últimos movimentos do oponente para determinar se é um bot honesto ou não e joga de acordo:

Edit 1: Se o outro bot é um bot constante (ou seja, sempre joga a mesma arma), ele esmaga-o jogando a arma vencedora e sendo honesto ao mesmo tempo.

Edit 2: Detector de bot constante aprimorado para trabalhar também com bots do rotador.

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]

Seja honesto enquanto o outro jogador for e detecte bots determinísticos simples. Jogue a jogada que maximiza o valor esperado, onde costumamos buscar nossos pontos, mas também gostamos de não dar pontos ao outro jogador. Mas os próprios pontos são melhores por um fator de dez, daí os números incomuns na valuefunção. Os movimentos adversários são esperados de acordo com a frequência com que os vimos antes nesta situação (movimentos declarados), mas os movimentos vistos recentemente são mais ponderados do que os movimentos vistos anteriormente. Para movimentos iniciais aleatórios (situações nunca vistas antes) e alguma distorção extra, os pesos incluem pequenos números aleatórios extras.

Atualização: use os resultados esperados também na rodada honesta. Para poder fazer isso, normalize e leve em consideração o ponto adicional que o oponente pode considerar pela honestidade - ele não pode influenciar nossa decisão na rodada real, mas é necessário agora. Eu pensei em fazer isso desde o começo, mas pensei erroneamente que não valeria a pena. Eu vi que seria possível dar trusting_botmenos pontos (mas esse bot não é um oponente forte de qualquer maneira), mas perdi que pontos extras poderiam ser ganhos rockbotcom um bom jogo na rodada honesta, mesmo que o jogo nesta rodada seja aleatório.


Isso nem sempre parece retornar um resultado.
precisa saber é o seguinte

Eu acho que você if mydecl == None:está errado.
precisa saber é o seguinte

@ user1502040 Por que você acha isso? Eu nunca observei nenhum problema.
Christian Sievers


4

Traição

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

A idéia é que, nos primeiros 50 movimentos, eu jogo honestamente e, depois de convencer o oponente a pensar que sou honesto, jogue desonestamente, tentando jogar o que contraria o que o oponente jogará (com base em sua honestidade ou desonestidade). no passado). Quando chego ao ponto em que joguei com tanta honestidade quanto desonestidade, mudo de tática e escolho a jogada mais provável do oponente com base nas configurações conhecidas anteriores.


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

3

Nome bot: Lembro-me de como você mente

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

Testado para várias rodadas de 100 rounds, e o vencedor obteve cerca de 220 em média. Bastante honesto, eu acho;)

Primeira vez que participei dos desafios do KOTH, acho que ainda há espaço para melhorias


3

Olho por olho

O clássico concorrente axelrodiano: esperançoso, mas mesquinho; simples, mas robusto. Este não é o dilema do prisioneiro e não fiz nenhuma tentativa de prever a jogada do oponente, por isso duvido que seja realmente competitivo. Mas "cooperar" ainda produz os pontos mais gerais para os competidores, então acho que pelo menos será mediano.

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

Dois terços

Usa a estratégia que Peter Taylor mencionou na Sandbox e neste comentário .

Ele usa o equilíbrio de 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

Isso erros para mim. Na linha 13, retorne random.choice (move). Eu acho que é provavelmente porque você está usando .choice em um dicionário. Até que isso seja corrigido, receio que este envio seja inválido.
Gryphon - Restabelece Monica

@ Gregry Não é um dicionário, é um conjunto.
LyricLy

Ah desculpa. Acabei de ver colchetes e pensei "dicionário". Minha culpa. Alguma idéia de por que o random.choice está enganando nessa linha, então?
Gryphon - Restabelece Monica

@ Gregry Parece que random.choicedepende de escolher um número de índice aleatório e retornar o objeto na lista nesse índice. Como os conjuntos não têm um pedido, eles também não suportam indexação e, portanto, não funcionam random.choice. Uma correção simples para isso seria converter o conjunto em uma lista antes de chamar random.choice.
LyricLy

Ah Eu não tenho python neste computador, então não posso consertar isso agora, mas vou corrigi-lo no meu código quando chegar em casa. Se o @ mbomb007 o corrigisse aqui, seria ótimo.
Gryphon - Restabelece Monica

3

Pensamento profundo

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

Apenas algumas notas:

  • O DeepThought gosta de pensar. Muito. Sinto muito, mas eu realmente não sei como corrigi-lo. Eu culpo Python.
  • O DeepThought tenta ser honesto. Ser honesto fornece um ponto adicional, que é o mesmo que o valor esperado para o RPS normale
  • Mas: o DeepThought chega em média até mais de 2 pontos por jogo. Ele usa alguma detecção para encontrar alguns comportamentos comuns (como enganar, ser honesto etc.) e se adapta de acordo com isso.
  • O DeepThought é puramente determinístico; portanto, atrai contra si mesmo, porque sempre toma a mesma decisão nos dois lados.
  • Para ter certeza de não mentir contra si mesmo, ele tem uma detecção especial, como alguns outros bots aqui também. Essa é muito agressiva, mesmo assumindo que é verdade depois de uma rodada (e na primeira rodada também). Basicamente, desde que o oponente se mova seja exatamente meu, presumo que seja uma partida espelhada.
  • A parte interessante (e a parte que possui dezenas de falsos positivos) é a verificação de um bot determinístico, que depende apenas de seu próprio resultado anterior. Essa verificação procura por qualquer padrão de tamanho n, repetido duas vezes, e que possa estar descrevendo os últimos movimentos n-1, prevendo a afirmação do oponente e avançando com antecedência. Esta parte está demorando, infelizmente.

Eu sou novo em ambos, koth e Python, então me diga se eu errei alguma coisa neste bot. Não acho que ele possa superar o aprendizado reforçado (porque acho que ele aprenderá meus movimentos muito rapidamente), mas vamos tentar.

Gosto desse desafio e, se encontrar algum tempo, gostaria de adicionar uma abordagem de computação orgânica (embora possa haver muito menos pressão nas dimensões mais altas). É permitido adicionar várias sugestões? Ou é proibido impedir o booster do seu bot principal inserindo alguns que só visam perder o seu principal?

EDIT: Corrigido erro de digitação que me caracterizava como falante de inglês não nativo


Não é proibido postar várias entradas, mas é proibido postar uma entrada que suporte um bot diferente (mesmo um que não seja o seu). Não há problema em perder para outro bot, desde que não seja por design.
Gryphon - Restabelece Monica

Ocorreu um erro ao executar isso, pois a 32ª linha da sua função DeepThought return resultrequer um recuo adicional. Eu acredito que deveria estar dentro da gigantesca declaração if imediatamente após, pois a variável returné declarada apenas nessa declaração. Fiz essa modificação no meu código e agora é executada sem erros. Se você não se importasse de fazer essa mudança aqui, seria ótimo.
Gryphon - Restabelece Monica

3
Você parece estar mexendo com o estado do gerador aleatório global, o que provavelmente não está bem. Eu considerei fazer uma coisa semelhante, e encontrou esta solução: criar um novo objeto aleatório com R=random.Random(seed)e usá-lo como este: R.choice(...).
Christian Sievers

@Gryphon corrigido. Provavelmente alguns erros que ocorreram ao transformar do meu script local para si, onde everythin tem de ser intdented uma vez adicional
alex berne

11
@alexberne Você pode selecionar o código que colou e clicar no {}botão na barra de ferramentas para recuar automaticamente todas as linhas.
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

Simplesmente pergunta "já estivemos aqui antes" e escolhe a jogada que daria o melhor resultado médio em jogos anteriores.

Edit: Clube da Honestidade. Eu adicionei um pequeno bloco de código porque outro bot (pedreiro) se saiu extremamente bem ao formar um clube secreto consigo mesmo. Observe, no entanto, que jogar honestamente contra oponentes honestos tem, em média, exatamente o mesmo resultado quando se joga contra si mesmo, e talvez também haja benefícios mútuos mais amplos?

Edit2: No momento em que escrevi os dois bots à minha frente, ambos exploravam rotadores, então adicionarei outro bloco de código para pular nesse movimento também. Eu acho que meu código deve parecer bastante antigo - aderindo a construções familiares encontradas em qualquer linguagem de programação, porque eu realmente não conheço 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: O Honesto Explorador

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

Acabei de perceber que votei com um clique errado, desculpe. Desfaz quando você edita. (Não é possível alterá-lo othewise.)
Christian Sievers

@ChristianSievers editada
Cinaski

@ChristianSievers obrigado!
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]

Entrada interessante. Vou executá-lo em breve, deve poder postar os resultados esta tarde.
Gryphon - Reinstala Monica

OK, voltei ligeiramente os parâmetros.
user1502040

Entendi. Desculpe, está demorando tanto para atualizar, mas toda vez que termina, alguém atualiza seu bot ou eu recebo um novo e preciso executá-lo novamente.
Gryphon - Restabelece Monica

@Gryphon, você pode manter uma tabela com os resultados de todas as duplas, portanto, quando um bot é atualizado, você precisa executar apenas 200 * (num_bots - 1) + 100 novas partidas.
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

Vou tentar um bot simples que refaça a última jogada de seu oponente nessas condições


Bem-vindo ao 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]

A idéia aqui é maximizar a pontuação enquanto se joga enquanto ainda é aleatoriamente competitivo durante outras etapas contra outros bots ruins.


11
A palavra isé uma palavra-chave, portanto, isso é inválido.
Erik the Outgolfer

@EriktheOutgolfer thanks :)
Stephen

1

Dx

Eu só escrevi este bot para que eu possa ter um smiley no meu nome de bot 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

Todos mentem

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"

É sobre o seu movimento ("Vou jogar Scissors!"), E assume que o oponente também estava mentindo e que eles tentarão vencer o que eu disse que meu movimento seria ("hmm, Rock bate Scissors, então eu estou jogando isso "), mas na verdade eu jogo a jogada que supera essa jogada (" Paper! Surprise! ").


3
Parece o primeiro nível da estratégia de pó de cocaína para mim :-) "Agora, um homem inteligente colocaria o veneno em seu próprio cálice, porque saberia que apenas um grande tolo alcançaria o que lhe foi dado. Eu não sou um grande tolo, então eu claramente não posso escolher o vinho na sua frente, mas você deve saber que eu não era um grande tolo, você teria contado com isso, então eu claramente não posso escolher o vinho na minha frente .. . "
Antony

1

Confiando no Bot

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

Sempre afirma jogar uma tesoura, mas fará o que bater o que o oponente disse. Irá desenhar de forma confiável consigo mesmo.


Isso seria mais eficaz se sempre fosse honesto contra si mesmo.
Gryphon - Restabelece Monica

@ Gregry Provavelmente, mas eu não faço python bem o suficiente para querer tentar fazer algo que coopere dessa maneira.
ATaco 16/10

Deixa pra lá então.
Gryphon - Restabelece Monica

1

Nome bot: Mentiroso Mentiroso

Não consigo parar de mentir.

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

Supõe que o oponente será honesto e tenta vencê-lo, mas se recusa a tocar 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"])

11
Isso parece estar errado, porque, na sua linha final, "P", "S" não está entre colchetes (não é uma lista). Eu mudei isso na minha versão, mas se você pudesse fazer o mesmo aqui, seria ótimo. Obrigado.
Gryphon - Restabelece Monica

Isso não vai perder terrivelmente com tesouras constantes?
Curinga

@Wildcard sim, mas ele vai fazer muito bem contra bot papel
Slepz

1

Nome bot: dontlietome

Determina se o oponente está mentindo ou não, dependendo de quantas vezes o oponente mentiu nas últimas 10 rodadas. Seleciona o movimento dependendo se o oponente está mentindo ou não. Se o oponente está determinado a mentir, então joga qual foi a dica.

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

Na linha "se is_trustworthy (opp_moves, self.length):", self não está definido. Além disso, na linha "return lose_against_map [opp_hint]", lose_against_map também não está definido. O comprimento do eu parece ser resolvido removendo o eu. mas o outro problema ainda permanece. Até que isso seja corrigido, receio que isso seja inválido.
Gryphon - Restabelece Monica

Opa, eu escrevi isso usando um Object e esqueci de remover algumas referências próprias e copiar completamente o código. Vou consertar isso assim que chegar em casa.
Cool1asjulio #

ESTÁ BEM. Se for apenas um pequeno erro, eu o corrijo (como em alguns outros bots, e teria se fosse apenas o problema do eu), mas uma função que falta é uma história diferente.
Gryphon - Restabelece Monica

@ Gregry Consertei os bugs. (removido o auto, acrescentou o referenciada lost_against_map, e fixou a declaração se verificar se rodada honesto)
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

Apenas um pouco melhor do que a minha entrada anterior ...

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 em esteróides

Eu acho que a sugestão que @ user1502040 faz nos comentários deve ser seguida. Caso contrário, esse bot teria uma vantagem que eu consideraria injusta. Eu o envio para que a diferença que ele faz possa ser avaliada. Com a semeadura aleatória sugerida, os esteróides seriam neutralizados e o bot seria equivalente a csbot, portanto, apenas um deveria participar do concurso.

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.