Piedra honesta, papel, tijeras

58

Muchas personas consideran que RPS es un juego de azar. Si ambos jugadores juegan de forma impredecible, la mejor estrategia es jugar al azar. Sin embargo, vamos a introducir un poco de previsibilidad.

Cada bot tendrá la oportunidad de decirle al otro bot qué va a jugar simultáneamente. Luego hay una pausa en la que cada bot sabrá lo que anunció el otro jugador. Si juega esa arma, anunció que anotará un punto además de sus puntos por una derrota ganadora o un empate.

Una victoria vale dos puntos, un empate, un punto y una pérdida de 0 puntos.

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

Le conviene ser honesto (pero también asegurarse de que su oponente no le crea).

Los partidos se jugarán en formato round robin, y el objetivo será maximizar su propia puntuación total en los partidos que juegue.

Formato de E / S:

  • Su bot será una función Python 2.7 que toma 4 argumentos y debe tener un nombre único (que se utilizará para representar su envío).
  • Los dos primeros argumentos siempre serán, en orden: los movimientos pasados ​​del oponente, seguidos de sus movimientos pasados. Esta será una lista en orden desde la primera ronda hasta la más reciente, con cada índice que contiene una lista con el movimiento que el oponente afirmó que haría, seguido del movimiento que realmente hicieron.
  • Los siguientes dos argumentos permitirán que su bot determine si se trata de una ronda "honesta" o una ronda "real". Si es una ronda "honesta", ambos serán Ninguno. Si es una ronda "real", serán, en orden, el movimiento que tu oponente declaró que harían, seguido del movimiento que declaraste que harías.
  • Todos los argumentos o porciones de argumentos que representan movimientos usarán "R", "P" y "S" para representar piedra, papel y tijera, respectivamente.
  • Su función debe devolver una "R" para piedra, una "P" para papel o una "S" para tijeras. Los bots que tengan la capacidad de devolver otros valores serán descalificados.
  • Cada bot se ejecutará contra cualquier otro bot 200 veces, y a sí mismo 100 veces. El objetivo es ser el bot con más puntos al final de la competencia.
  • En lo que respecta a la discusión en los comentarios, las presentaciones no pueden leer ni escribir en ningún archivo, ni de ninguna manera sabotear o leer el código del oponente.

Ejemplos:

Estos son cuatro bots de ejemplo que armé rápidamente. Se unirán a la competencia como bots adicionales. Si pierde con el último, tiene trabajo que hacer.

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:

Y aquí está el controlador que usaré. Las nuevas presentaciones se importarán al principio y se agregarán al diccionario 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

Puntajes finales:

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
Gryphon - Restablece a Monica
fuente
1
Cual es el estado?
user1502040

Respuestas:

11

Masón

Intenta recoger información sobre otros bots, como cuán honestos son y cómo se ven afectados por mi primer movimiento. Luego trato de encontrar otros bots obvios que sigan un patrón y los explote para darme más puntos. Finalmente, el masón tiene un arma secreta: el conocimiento de una sociedad secreta en la que ambos bots que participan mutuamente van a un sorteo completo, ganando 500 puntos cada uno. Desafortunadamente, el secreto es más bien ... Bueno, secreto y cambia cada vez que lo hace Mason.

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
Azul
fuente
9

Rlbot: aprendizaje por refuerzo

Utiliza un enfoque de aprendizaje de refuerzo, abordando este juego de una manera similar al problema del bandido armado n. Lo hace de dos maneras: intenta aprender qué declaración es mejor contra cada oponente y se adhiere a esa (útil contra bots constantes), e intenta aprender el resultado de varios movimientos en situaciones similares anteriores (similar en lo que respecta a las jugadas relativas , por ejemplo, piedra vs papel es similar a un papel anterior vs tijera). Los supuestos iniciales son optimistas, por lo que este jugador asumirá que ser honesto le dará 3 puntos y mentir dará 2, y por lo tanto siempre será honesto hasta que se demuestre lo contrario.

Actualización: Los primeros resultados del torneo resaltaron un problema con este bot, que era su incapacidad para detectar patrones en las declaraciones de sus oponentes (lo que lo hacía jugar subóptimamente contra los rotadores). Luego agregué un componente de coincidencia de patrones al código para las rondas honestas, que usa una expresión regular para buscar el sufijo más largo en la historia de las declaraciones del oponente que está presente en algún lugar anteriormente en esa historia, y qué movimiento se jugó después de eso. . Asumimos que el oponente volverá a jugar el mismo movimiento y usaremos el aprendizaje de refuerzo como antes para decidir cuál debería ser la mejor respuesta.

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

Pruébalo en línea!

León
fuente
6

Nunca he usado mucho Python, así que estoy seguro de haber cometido un error en alguna parte.

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

Debería verificar las últimas 10 rondas para ver con qué frecuencia mintió el oponente, luego elegir una respuesta diferente dependiendo de eso.

12Me21
fuente
6

Aquí está mi bot adaptativo. Analiza los últimos 2 movimientos del oponente para determinar si es un bot honesto o no y juega en consecuencia:

Edición 1: si el otro bot es un bot constante (es decir, siempre juega la misma arma), este bot lo aplasta al jugar el arma ganadora y ser honesto al mismo tiempo.

Edición 2: Detector de bot constante mejorado para trabajar también con bots rotadores.

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
Selcuk
fuente
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]

Sé honesto mientras el otro jugador lo sea y detecta bots deterministas simples. Juega el movimiento que maximiza el valor esperado, donde generalmente vamos por nuestros puntos, pero también nos gusta no darle puntos al otro jugador. Pero los puntos propios son mejores por un factor de diez, de ahí los números inusuales en la valuefunción. Los movimientos de los oponentes se esperan de acuerdo con la frecuencia con la que los hemos visto antes en esta situación (movimientos declarados), pero los movimientos vistos recientemente se ponderan más que los movimientos vistos anteriormente. Para movimientos iniciales aleatorios (situaciones nunca antes vistas) y algo de confusión adicional, los pesos incluyen pequeños números aleatorios adicionales.

Actualización: Utilice los resultados esperados también en la ronda honesta. Para poder hacer esto, normalice y tome en cuenta el punto adicional que el oponente puede tener por honestidad: no pudo influir en nuestra decisión en la ronda real, pero es necesario ahora. Pensé en hacer esto desde el principio, pero erróneamente pensé que no valdría la pena. Vi que sería posible dar trusting_botmenos puntos (pero ese bot no es un oponente fuerte de todos modos), pero fallé que podría ganar puntos extra rockbotcon un buen juego en la ronda honesta a pesar de que su juego en esta ronda es aleatorio.

Christian Sievers
fuente
Esto no siempre parece devolver un resultado.
user1502040
Creo que tu if mydecl == None:es erróneo.
user1502040
@ user1502040 ¿Por qué piensas eso? Nunca he observado ningún problema.
Christian Sievers
@ChristianSievers stackoverflow.com/questions/3257919/…
Selcuk
4

Traición

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

La idea es que durante los primeros 50 movimientos juego honestamente, y luego, una vez que he atraído al oponente a pensar que soy honesto, juego deshonestamente, tratando de jugar lo que contrarrestaría lo que jugará el oponente (en función de si fue honesto o deshonesto). en el pasado). Cuando llego al punto en el que jugué tan a menudo honestamente que deshonestamente, cambio las tácticas y elijo el movimiento más probable del oponente según las configuraciones conocidas anteriores.

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

Nombre del bot: recuerdo cómo mientes

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

Probado para varias carreras de 100 rondas, y resultó que el ganador obtiene alrededor de 220 en promedio. Más bien honesto, creo;)

Es la primera vez que participo en KOTH desafíos, por lo que creo que todavía hay margen de mejora

Shieru Asakoto
fuente
3

Tal para cual

El clásico concursante axelrodiano: esperanzado, pero mezquino; Simple, pero robusto. Este no es el dilema del prisionero y no intenté predecir el movimiento del oponente, por lo que dudo mucho que sea realmente competitivo. Pero "cooperar" todavía produce la mayor cantidad de puntos generales para los concursantes, así que creo que al menos lo hará de manera mediana.

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'])
hexaedro estrellado
fuente
3

Dos tercios

Utiliza la estrategia que Peter Taylor mencionó en el Sandbox y en este comentario .

Utiliza el equilibrio 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
mbomb007
fuente
Esto me errores. En la línea 13, devuelve random.choice (movimientos). Creo que probablemente sea porque estás usando .choice en un diccionario. Hasta que eso se solucione, me temo que esta presentación no es válida.
Gryphon - Restablece a Monica el
@Gryphon No es un diccionario, es un conjunto.
LyricLy
Oh, lo siento. Acabo de ver corchetes ondulados y pensé "diccionario". Culpa mía. ¿Alguna idea de por qué random.choice está fallando en esa línea entonces?
Gryphon - Restablece a Monica el
@Gryphon Parece que se random.choicebasa en elegir un número de índice aleatorio y luego devolver el objeto en la lista en ese índice. Como los conjuntos no tienen un orden, tampoco admiten la indexación y, por lo tanto, no funcionan random.choice. Una solución simple para esto sería convertir el conjunto en una lista antes de llamar random.choice.
LyricLy
Ah No tengo Python en esta computadora, así que no puedo arreglar esto ahora, pero lo arreglaré en mi código cuando llegue a casa. Si @ mbomb007 lo arreglara aquí, sería genial.
Gryphon - Restablece a Monica el
3

Pensamiento 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

Solo algunas notas al respecto:

  • A DeepThought le gusta pensar. Mucho. Lo siento, pero realmente no sé cómo solucionarlo. Yo culpo a Python.
  • DeepThought intenta ser honesto. Ser honesto le proporciona un punto adicional, que es el mismo que el valor esperado para RPS normale
  • Pero: DeepThought obtiene en rango incluso más de 2 puntos por juego. Utiliza alguna detección para encontrar algunos comportamientos comunes (como engañar, ser honesto, etc.) y se adapta de acuerdo con eso.
  • DeepThought es puramente determinista, por lo que recurrirá a sí mismo, porque siempre hará la misma decisión en ambos extremos.
  • Para asegurarse de no mentir contra sí mismo, también tiene una detección especial, como algunos otros bots aquí. Esta es muy agresiva, incluso suponiendo que sea cierto después de una ronda (y también en la primera ronda). Básicamente, mientras los movimientos del oponente sean exactamente míos, supondré que es una coincidencia de espejo.
  • La parte interesante (y la parte que tiene docenas de falsos positivos) es la verificación de un bot determinista, que solo depende de su propio resultado previo. Esa verificación busca cualquier patrón de tamaño n, que se repite dos veces, y que podría describir los últimos movimientos n-1, predecir el reclamo del oponente y avanzar por adelantado. Esta parte está tomando algo de tiempo, tristemente.

Soy nuevo en ambos, koth y Python, así que dime si me equivoqué en este bot. No creo que pueda vencer el aprendizaje reforzado (porque supongo que aprenderá mis movimientos demasiado rápido), pero vamos a intentarlo.

Me gusta este desafío, y si encuentro algo de tiempo, me gustaría agregar un enfoque de computación orgánica (aunque tal vez haya menos presión en las dimensiones superiores). ¿Está permitido agregar múltiples sugerencias? ¿O está prohibido evitar elegir su bot principal insertando algunos que solo tengan como objetivo perder a su primario?

EDITAR: Se corrigió el error tipográfico que me caracterizaba como hablante de inglés no nativo

alex berne
fuente
No está prohibido publicar múltiples entradas, pero sí está prohibido publicar una entrada que sostenga un bot diferente (incluso uno que no sea el suyo). Está bien perder con otro bot, siempre que no sea por diseño.
Gryphon - Restablece a Monica el
Recibí un error al ejecutar esto, ya que la línea 32 de su función DeepThought return resultrequiere una sangría adicional. Creo que debería estar dentro de la gigantesca declaración if inmediatamente después, ya que la variable returnsolo se declara en esa declaración. Hice esta modificación en mi código, y ahora se ejecuta sin error. Si no te importa hacer ese cambio aquí, sería genial.
Gryphon - Restablece a Monica el
3
Parece que estás jugando con el estado del generador aleatorio global, que probablemente no está bien. Consideré hacer una cosa similar, y encontré esta solución: crear un nuevo objeto al azar con R=random.Random(seed)y utilizar de esta manera: R.choice(...).
Christian Sievers
@Gryphon arreglado. Probablemente se produjeron algunos errores al transformar mi script local en se, donde todo tiene que ser intervenido una vez más
alex berne
1
@alexberne Puede seleccionar el código que pegó y hacer clic en el {}botón en la barra de herramientas para sangrar automáticamente cada línea.
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])
usuario5957401
fuente
2

hemos estado aqui antes

Simplemente pregunta "hemos estado aquí antes", y elige el movimiento que habría dado el mejor resultado promedio en cualquiera de esos juegos anteriores.

Editar: Honestidad Club. He agregado un pequeño bloque de código porque a otro bot (albañil) le ha ido extremadamente bien al formar un club secreto consigo mismo. Sin embargo, tenga en cuenta que jugar honestamente contra oponentes honestos tiene, en promedio, exactamente la misma recompensa cuando juega contra uno mismo, y ¿tal vez también existan beneficios mutuos más amplios?

Edit2: Al momento de escribir, los dos bots delante de mí explotan los rotadores, por lo que agregaré otro bloque de código para saltar también en ese carro. Supongo que mi código debe parecer bastante antiguo: apegarse a construcciones familiares que se encuentran en cualquier lenguaje de programación porque realmente no conozco 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)
Antonio
fuente
2

THEbot: EL EXPLOTADOR HONESTO

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
Cinaski
fuente
Me acabo de dar cuenta de que voté mal por clic incorrecto, lo siento. Se deshará cuando edites. (No se puede cambiar de otra manera.)
Christian Sievers
@ChristianSievers editado
Cinaski el
@ChristianSievers gracias!
Cinaski el
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]
user1502040
fuente
Interesante entrada. Lo ejecutaré pronto, debería poder publicar los resultados esta tarde.
Gryphon - Restablece a Monica el
OK, volví a cambiar los parámetros.
user1502040
Entendido. Lo siento, está tardando tanto en actualizarse, es solo que, cada vez que está a punto de terminar, alguien actualiza su bot, o recibo uno nuevo, y tengo que ejecutarlo nuevamente.
Gryphon - Restablece a Monica el
@Gryphon podría mantener una tabla de los resultados de todos los pares, por lo que cuando se actualiza un bot solo tiene que ejecutar 200 * (num_bots - 1) + 100 nuevas coincidencias.
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

Probaré un bot simple que rehaga la última jugada de su oponente en estas condiciones

Guillaume Pagès
fuente
Bienvenido a 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]

La idea aquí es maximizar el puntaje mientras juegas a ti mismo mientras sigues siendo aleatoriamente competitivo durante otras etapas contra otros robots malos.

Stephen
fuente
1
La palabra ises una palabra clave, por lo tanto, no es válida.
Erik the Outgolfer
@EriktheOutgolfer gracias :)
Stephen
1

Dx

Solo escribí este bot para poder tener una carita sonriente en mi nombre 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]]])
Roman Gräf
fuente
1

Todos mienten

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"

Miente sobre su movimiento ("¡Jugaré a las Tijeras!"), Y asume que el oponente también estaba mintiendo y que tratarán de vencer lo que dije que sería mi movimiento ("hmm, Rock vence a las Tijeras, así que estoy jugando eso "), pero en realidad juego el movimiento que supera ese movimiento (" ¡Papel! ¡Sorpresa! ").

No un arbol
fuente
3
A mí me suena como el primer nivel de la estrategia de Iocaine Powder :-) "Ahora, un hombre inteligente pondría el veneno en su propia copa, porque sabría que solo un gran tonto alcanzaría lo que le dieron. No soy un gran tonto, así que claramente no puedo elegir el vino delante de ti. Pero debes haber sabido que no era un gran tonto, habrías contado con él, por lo que claramente no puedo elegir el vino delante de mí ... . "
Antony
1

Bot de confianza

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

Siempre afirma tirar tijeras, pero hará lo que sea mejor que lo que dijo el oponente. Dibujará confiablemente consigo mismo.

Un taco
fuente
Esto sería más efectivo si siempre fuera honesto contra sí mismo.
Gryphon - Restablece a Monica el
@Gryphon Probablemente, pero no hago python lo suficientemente bien como para querer intentar hacer algo que coopere así.
ATaco
Olvidalo entonces.
Gryphon - Restablece a Monica el
1

Nombre del bot: mentiroso mentiroso

No puedo 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)
Juan ferrer
fuente
1

RockBot

Asume que el oponente será honesto e intenta vencerlo, pero se niega 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"])
Slepz
fuente
1
Esto parece un error porque, en su línea final, "P", "S" no está entre corchetes (no es una lista). Cambié eso en mi versión, pero si pudieras hacer lo mismo aquí, sería genial. Gracias.
Gryphon - Restablece a Monica el
¿No perderá esto horriblemente con las tijeras constantes?
Comodín el
@Wildcard sí, pero funcionará bastante bien contra el robot de papel
Slepz
1

Nombre del bot: dontlietome

Determina si el oponente está mintiendo o no, dependiendo de cuántas veces haya mentido en las últimas 10 rondas. Selecciona el movimiento dependiendo de si el oponente está mintiendo o no. Si se determina que el oponente está mintiendo, entonces juega lo que fue la pista.

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
coolioasjulio
fuente
En la línea "if is_trustworthy (opp_moves, self.length):", self no está definido. Además, en la línea "return lose_against_map [opp_hint]", lose_against_map tampoco está definido. La longitud del self parece resolverse eliminando el self. pero el otro problema sigue en pie. Hasta que eso se solucione, me temo que esto no es válido.
Gryphon - Restablece a Monica el
Vaya, escribí esto usando un Objeto y olvidé eliminar algunas referencias propias y copiar completamente el código. Los arreglaré tan pronto como llegue a casa.
coolioasjulio
OKAY. Si es solo un pequeño error, lo corrijo (como lo he hecho en algunos otros bots, y lo habría hecho si fuera solo el problema propio), pero una función que falta es una historia diferente.
Gryphon - Restablece a Monica el
@Gryphon arreglé los errores. (retirado del mismo, agregó la referencia lost_against_map, y fija la sentencia if comprobar si es redondo honesta)
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
KSmarts
fuente
0

Promediador

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
Erik el Outgolfer
fuente
0

Solo un poco mejor que mi 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)
12Me21
fuente
0

csbot con esteroides

Creo que se debe seguir la sugerencia que @ user1502040 hace en los comentarios. De lo contrario, este bot tendría una ventaja que consideraría injusto. Lo presento para que se pueda evaluar la diferencia que hace. Con la siembra aleatoria sugerida, los esteroides se neutralizarían y el bot sería equivalente a csbot, por lo que solo uno debería participar en el 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
Christian Sievers
fuente