Roche honnête, papier, ciseaux


58

Beaucoup de gens considèrent RPS comme un jeu de hasard. Si les deux joueurs jouent de manière imprévisible, la meilleure stratégie consiste à jouer au hasard. Cependant, introduisons un peu de prévisibilité.

Chaque bot aura une chance de dire à l'autre bot ce qu'il va jouer simultanément. Ensuite, il y a une pause pendant laquelle chaque bot saura ce que l'autre joueur a annoncé. S'il joue cette arme, il annonce qu'il marquera un point en plus de ses points pour une défaite ou un match nul.

Une victoire vaut deux points, un match nul, un point et une perte de 0 points.

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

Il est dans votre intérêt d'être honnête (mais aussi de vous assurer que votre adversaire ne vous croit pas).

Les matchs se joueront dans un format de tournoi à la ronde et l'objectif sera de maximiser votre score total pour tous les matchs que vous jouez.

Format I / O:

  • Votre bot sera une fonction Python 2.7 prenant 4 arguments et doit avoir un nom unique (qui sera utilisé pour représenter votre soumission).
  • Les deux premiers arguments seront toujours, dans l'ordre: les mouvements passés de l'adversaire, suivis de vos mouvements passés. Ce sera une liste dans l'ordre du premier au dernier tour, chaque index contenant une liste avec le coup que l'adversaire a prétendu qu'il ferait, suivi du coup qu'il a réellement fait.
  • Les deux arguments suivants permettront à votre bot de déterminer s’il s’agit d’un tour «honnête» ou «réel». Si c'est un tour "honnête", ils ne seront aucun. Si c'est un "vrai" round, ils seront, dans l'ordre, le coup que votre adversaire a déclaré qu'ils feraient, suivi du coup que vous avez déclaré que vous feriez.
  • Tous les arguments ou parties d'arguments représentant des déplacements utiliseront respectivement "R", "P" et "S" pour représenter la roche, le papier et les ciseaux.
  • Votre fonction doit renvoyer un "R" pour le rock, un "P" pour le papier ou un "S" pour les ciseaux. Les robots qui ont la possibilité de renvoyer d'autres valeurs seront disqualifiés.
  • Chaque bot sera attaqué 200 fois sur un bot et 100 fois. L'objectif est d'être le bot avec le plus de points à la fin de la compétition.
  • En ce qui concerne la discussion dans les commentaires, les soumissions ne peuvent pas lire ou écrire dans un fichier, ni saboter ou lire le code de l'adversaire.

Exemples:

Ce sont quatre exemples de robots que je mets rapidement en place. Ils rejoindront la compétition en tant que bots supplémentaires. Si vous perdez jusqu'au dernier, vous avez du travail à faire.

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

Manette:

Et voici le contrôleur que je vais utiliser. Les nouvelles soumissions seront importées au début et ajoutées au dictionnaire 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

Scores finaux:

csbot                    3430397
thompson                 3410414
rlbot                    3340373
have_we_been_here_before 3270133
mason                    3227817
deepthought              3019363
adaptive_bot             2957506
THEbot                   2810535
dontlietome              2752984
irememberhowyoulie       2683508
learningbot4             2678388
betrayal                 2635901
averager                 2593368
honestrandom             2580764
twothirds                2568620
mirrorbot                2539016
tit4tat                  2537981
honestscissors           2486401
trusting_bot             2466662
rotate_scissors          2456069
rotate_paper             2455038
rotate_rock              2454999
honestpaper              2412600
honestrock               2361196
rockBot                  2283604
trustingRandom           2266456
user5957401bot           2250887
randombot                2065943
Dx                       1622238
liarliar                 1532558
everybodylies            1452785

1
Quel est le statut?
user1502040

Réponses:


11

le maçon

Essaie de collecter des informations sur d'autres robots, comme leur honnêteté et l'impact de mon premier geste. J'essaie ensuite de trouver d'autres robots évidents qui suivent un modèle et les exploitent pour me donner plus de points. Enfin, le maçon a une arme secrète: la connaissance d’une société secrète dans laquelle les deux robots participants s’affrontent pour un tirage au sort complet, gagnant 500 points chacun. Malheureusement, le secret est plutôt ... Bien secret et change à chaque fois que le maçon le fait.

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: apprentissage par renforcement

Utilise une approche d’apprentissage par renforcement, abordant ce jeu d’une manière similaire au problème des bandits à n bras. Il le fait de deux manières: essaie de savoir quelle déclaration est la meilleure contre chaque adversaire et s’en tient à celle-là (utile contre les robots constants), et essaie de connaître le résultat de divers mouvements dans des situations précédentes similaires (semblable en ce qui concerne les jeux relatifs). , par exemple, le rock vs le papier est similaire à un précédent papier vs ciseaux). Les hypothèses de départ sont optimistes, donc ce joueur supposera qu'être honnête lui donnera 3 points et que mentir donnera 2, et sera donc toujours honnête jusqu'à preuve du contraire.

Mise à jour: Les premiers résultats du tournoi ont mis en évidence un problème avec ce bot, qui était son incapacité à détecter des motifs dans les déclarations de ses adversaires (ce qui le faisait jouer de manière sous-optimale contre les rotateurs). J'ai ensuite ajouté un composant de correspondance de motif au code pour les tours honnêtes, qui utilise une expression régulière pour rechercher le suffixe le plus long de l'historique des déclarations de l'adversaire présent quelque part dans l'historique, et quel mouvement a été joué par la suite. . Nous supposons que l'adversaire jouera à nouveau le même mouvement et utilisons l'apprentissage par renforcement comme auparavant pour décider quelle devrait être la meilleure réponse à cette question.

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

Essayez-le en ligne!


6

Je n'ai jamais vraiment utilisé beaucoup de python, alors je suis sûr que j'ai commis une erreur quelque part.

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

Il convient de vérifier les 10 derniers tours pour voir combien de fois l'adversaire a menti, puis de choisir une réponse différente en fonction de cela.


6

Voici mon bot adaptatif. Il analyse les 2 derniers mouvements de l'adversaire pour déterminer s'il s'agit d'un bot honnête ou non et joue en conséquence:

Edit 1: Si l’autre bot est un bot constant (c’est-à-dire qu'il utilise toujours la même arme), ce dernier l’écrase en jouant avec l’arme gagnante et en étant honnête en même temps.

Edit 2: Détecteur de bot constant amélioré pour travailler aussi avec les robots rotateurs.

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]

Soyez honnête aussi longtemps que l'autre joueur et détectez de simples robots déterministes. Jouez le coup qui maximise la valeur attendue, où nous allons surtout chercher nos points, mais nous aimons aussi ne pas donner de points à l'autre joueur. Mais les points propres sont meilleurs d'un facteur dix, d'où les nombres inhabituels dans la valuefonction. Les mouvements de l'adversaire sont attendus en fonction de la fréquence à laquelle nous les avons vus auparavant dans cette situation (mouvements déclarés), mais les mouvements récemment observés pèsent plus lourd que les mouvements vus précédemment. Pour les mouvements initiaux aléatoires (situations jamais vues auparavant) et un peu de fuzzyness supplémentaire, les poids comprennent de petits nombres aléatoires supplémentaires.

Mise à jour: Utilisez les résultats attendus également dans le tour honnête. Pour ce faire, normalisez et tenez compte du point supplémentaire que l’opposant pourrait obtenir pour l’honnêteté - cela ne pourrait pas influer sur notre décision au cours du tour réel mais est nécessaire maintenant. J'ai envisagé de le faire depuis le début, mais à tort j'ai pensé que cela n'en valait pas la peine. J'ai vu qu'il serait possible de donner trusting_botmoins de points (bien que ce bot ne soit pas un adversaire puissant de toute façon), mais j'ai oublié que des points supplémentaires pourraient être obtenus rockbotgrâce à un bon jeu dans le tour honnête même si son jeu dans ce tour est aléatoire.


Cela ne semble pas toujours donner un résultat.
user1502040

Je pense que votre if mydecl == None:est erroné.
user1502040

@ user1502040 Pourquoi pensez-vous cela? Je n'ai jamais observé de problème.
Christian Sievers


4

Trahison

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

L'idée est que pour les 50 premiers coups, je joue honnêtement, puis une fois que j'ai persuadé mon adversaire de penser que je suis honnête, je joue malhonnêtement, j'essaie de jouer ce qui contrecarrerait ce que l'adversaire va jouer (selon qu'il soit honnête ou malhonnête autrefois). Lorsque j'arrive au point où j'ai joué aussi souvent que honnêtement que malhonnêtement, je change de tactique et choisis le coup le plus probable de l'adversaire en fonction des configurations connues précédentes.


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

3

Nom du bot: Je me souviens comment tu te mens

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

Testé pour plusieurs manches de 100 tours, il s'est avéré que le vainqueur marquait environ 220 points en moyenne. Plutôt honnête je pense;)

C'est la première fois que je participe aux défis KOTH, alors je pense qu'il y a encore matière à amélioration


3

Tit pour Tat

Le concurrent classique Axelrodian: plein d'espoir, mais mesquin; simple, mais robuste. Ce n'est pas le dilemme du prisonnier et je n'ai fait aucune tentative pour prédire le coup de l'adversaire, alors je doute fort que ce soit vraiment compétitif. Mais "coopérer" produit toujours le plus grand nombre de points pour les concurrents, donc je pense que ça ira au moins de façon médiocre.

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

Les deux tiers

Utilise la stratégie mentionnée par Peter Taylor dans le bac à sable et dans ce commentaire .

Il utilise l' équilibre 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

Cette erreur pour moi. Sur la ligne 13, renvoyez random.choice (déménagements). Je pense que c'est probablement parce que vous utilisez .choice dans un dictionnaire. Tant que ce n'est pas corrigé, je crains que cette soumission ne soit invalide.
Gryphon - Rétablir Monica

@Gryphon Ce n'est pas un dictionnaire, c'est un ensemble.
LyricLy

Ah désolé. Je viens de voir des crochets et penser à un "dictionnaire". Ma faute. Avez-vous une idée de la raison pour laquelle random.choice se trompe sur cette ligne?
Gryphon - Rétablir Monica

@Gryphon Il semblerait que random.choicecela repose sur la sélection d'un numéro d'index aléatoire, puis sur le renvoi de l'objet dans la liste à cet index. Comme les ensembles n'ont pas d'ordre, ils ne supportent pas non plus l'indexation et ne fonctionnent donc pas avec random.choice. Une solution simple à cela consisterait à convertir l'ensemble en une liste avant d'appeler random.choice.
LyricLy

Ah Je n'ai pas de python sur cet ordinateur, donc je ne peux pas le réparer pour le moment, mais je le ferai dans mon code quand je rentrerai à la maison. Si @ mbomb007 le résolvait ici, ce serait génial.
Gryphon - Rétablir Monica

3

Pensée profonde

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

Quelques notes à ce sujet:

  • DeepThought aime penser. Beaucoup. Je suis désolé pour ça, mais je ne sais pas vraiment comment le réparer. Je blâme Python.
  • DeepThought essaye d'être honnête. Être honnête vous fournit un point supplémentaire, qui correspond à la valeur attendue pour normale RPS
  • Mais: DeepThought obtient en moyenne plus de 2 points par match. Il utilise des techniques de détection pour trouver des comportements courants (comme tromper, être honnête, etc.) et s’adapte en fonction de cela.
  • DeepThought est purement déterministe, il va donc s'appuyer sur lui-même, car il fera toujours la même décision des deux côtés.
  • Pour ne pas mentir contre lui-même, il a une détection spéciale, comme certains autres robots ici aussi. C’est une question très agressive, qui suppose même d’être vraie après un tour (et au premier tour également). Fondamentalement, tant que les mouvements de l'adversaire sont exactement les miens, je suppose que c'est un match miroir.
  • La partie intéressante (et la partie comportant des dizaines de faux positifs) est la vérification d’un bot déterministe, qui ne dépend que de son propre résultat précédent. Ce contrôle recherche tout motif de taille n, répété deux fois, et qui pourrait décrire les derniers n-1 mouvements, prédire la réclamation de l’opposant et se déplacer à l’avance. Malheureusement, cette partie prend du temps.

Koth et Python sont nouveaux pour moi, alors dites-moi si j'ai tout gâché dans ce bot. Je ne pense pas qu'il puisse battre un apprentissage renforcé (parce que je suppose qu'il va apprendre mes mouvements trop rapidement), mais essayons.

J'aime ce défi et, si je trouve un peu de temps, j'aimerais ajouter une approche informatique organique (même si la pression sur les dimensions supérieures est peut-être trop faible). Est-il permis d'ajouter plusieurs suggestions? Ou est-il interdit d'empêcher votre bot principal de se coincer en en insérant quelques-uns qui ne visent qu'à perdre votre principal?

EDIT: correction du code-typo qui me caractérisait comme anglophone non natif


Il n'est pas interdit de poster plusieurs entrées, mais il est interdit de poster une entrée qui soutient un autre bot (même un autre que le vôtre). Il est acceptable de perdre contre un autre bot, tant que ce n'est pas intentionnel.
Gryphon - Rétablir Monica

J'ai eu une erreur en exécutant ceci, car la 32ème ligne de votre fonction DeepThought return resultnécessite un retrait supplémentaire. Je crois que cela devrait être à l'intérieur de la gigantesque instruction si elle est juste après, car la variable returnn'est déclarée que dans cette instruction. J'ai apporté cette modification à mon code et il s'exécute maintenant sans erreur. Si cela ne vous dérange pas de faire ce changement ici, ce serait génial.
Gryphon - Rétablir Monica

3
Vous semblez jouer avec l'état du générateur aléatoire global, ce qui n'est probablement pas acceptable. Je considérais faire une chose semblable, et a trouvé cette solution: créer un nouvel objet aléatoire R=random.Random(seed)et l' utiliser comme ceci: R.choice(...).
Christian Sievers

@Gryphon corrigé. Probablement quelques erreurs qui se sont produits lors de la transformation de mon script local à proprement parler, où everythin doit être intdented un temps supplémentaire
alex berne

1
@alexberne Vous pouvez sélectionner le code que vous avez collé et cliquer sur le {}bouton de la barre d'outils pour mettre automatiquement en retrait chaque ligne.
Selçuk

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

avoir_we_been_here_before

Il demande simplement "sommes-nous déjà venus ici" et choisit le coup qui aurait donné le meilleur résultat moyen de ces jeux précédents.

Edit: club d'honnêteté. J'ai ajouté un petit bloc de code car un autre bot (maçon) s'est extrêmement bien débrouillé en formant un club secret avec lui-même. Notez cependant que jouer honnêtement contre des adversaires honnêtes a en moyenne exactement le même avantage quand on joue contre soi-même, et peut-être qu’il ya aussi des avantages mutuels plus larges?

Edit2: Au moment de l’écriture, les deux robots devant moi exploitent tous les deux les rotateurs. Je vais donc ajouter un autre bloc de code afin de suivre ce mouvement aussi. J'imagine que mon code doit paraître un peu vieux jeu. Je m'en tiens à des constructions connues dans tous les langages de programmation car je ne connais pas vraiment 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: L'Exploiteur Honnête

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

Je viens de me rendre compte que j'ai eu un vote négatif par erreur, désolé. Annulera lorsque vous éditez. (On ne peut pas le changer.)
Christian Sievers

@ChristianSievers édité
Cinaski

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

Entrée intéressante. Je l'exécuterai bientôt, devrait pouvoir publier les résultats cet après-midi.
Gryphon - Rétablir Monica

OK, j'ai légèrement retourné les paramètres.
user1502040

Je l'ai. Désolé, la mise à jour prend si longtemps, c'est juste que chaque fois que c'est presque terminé, quelqu'un met à jour son bot, ou j'en reçois un nouveau, et je dois le lancer à nouveau.
Gryphon - Réintégrer Monica

@Gryphon, vous pouvez conserver un tableau des résultats de toutes les paires. Ainsi, lorsqu'un bot est mis à jour, il vous suffit de lancer 200 * (num_bots - 1) + 100 nouveaux matchs.
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

Je vais essayer un simple bot qui refait le dernier jeu de son adversaire dans ces conditions


Bienvenue chez 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]

L'idée ici est de maximiser le score tout en jouant soi-même tout en restant compétitif au hasard lors d'autres étapes contre d'autres méchants bots.


1
Le mot isest un mot clé, donc ce n'est pas valide.
Erik l'Outgolfer

@EriktheOutgolfer merci :)
Stephen,

1

Dx

J'ai seulement écrit ce bot pour que je puisse avoir un smiley dans mon nom 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

Tout le monde ment

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"

Il ment à propos de son coup ("Je vais jouer aux ciseaux!"), Et suppose que l'adversaire mentait aussi et qu'ils essaieraient de battre ce que j'avais dit que mon coup serait ("hmm, Rock bat Scissors alors je joue que "), mais je joue en fait le coup qui bat ce coup (" Paper! Surprise! ").


3
Cela ressemble au premier niveau de la stratégie de poudre de poudre pour moi :-) "Maintenant, un homme intelligent mettrait le poison dans son propre gobelet, car il saurait qu'un seul imbécile parviendrait à obtenir ce qu'on lui aurait donné. Je ne suis pas un grand imbécile, donc je ne peux clairement pas choisir le vin devant vous. Mais vous devez avoir su que je n’étais pas un grand imbécile, vous auriez compté dessus, donc je ne peux clairement pas choisir le vin devant moi .. . "
Antony

1

Bot de confiance

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

Il prétend toujours lancer des ciseaux, mais fera tout ce qui est en contradiction avec ce que l’adversaire a dit. Dessine de manière fiable avec lui-même.


Cela serait plus efficace s'il était toujours honnête contre lui-même.
Gryphon - Réintégrer Monica

@Gryphon Probablement, mais je ne python pas assez bien pour vouloir essayer de faire quelque chose qui coopère comme ça.
ATaco

Pas de soucis alors.
Gryphon - Rétablir Monica

1

Nom du bot: Liar Liar

Je ne peux pas arrêter 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

Suppose que l’adversaire sera honnête et essaie de le battre, mais refuse de jouer du rock.

import random
def rockBot(oppHist,myHist,oppMove,myMove):
    if oppMove == None:
        return random.choice(["R","P","S"])
    else:
        if(oppMove == "R"):
            return "P"
        elif(oppMove == "P"):
            return "S"
        elif(myMove != "R"):
            return myMove
        else:
            return random.choice(["P","S"])

1
Cela semble être une erreur car, sur votre dernière ligne, "P", "S" ne sont pas entre crochets (pas une liste). J'ai changé cela dans ma version, mais si vous pouviez faire la même chose ici, ce serait génial. Merci.
Gryphon - Réintégrez Monica

Est-ce que cela ne va pas perdre horriblement aux ciseaux?
Wildcard

@Wildcard oui, mais ça ira très bien contre le bot en papier
Slepz

1

Nom du bot: dontlietome

Détermine si l'adversaire ment ou non en fonction du nombre de fois où il a menti au cours des 10 derniers tours. Sélectionne le déplacement selon que l'adversaire ment ou non. Si l'adversaire est déterminé à mentir, alors joue ce que l'allusion était.

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

Dans la ligne "if is_trustworthy (opp_moves, self.length):", self n'est pas défini. De plus, dans la ligne "return lost_against_map [opp_hint]", lost_against_map n'est pas non plus défini. La longueur de soi semble être résolue en supprimant le soi. mais l'autre problème persiste. Tant que ce n'est pas corrigé, j'ai bien peur que ce ne soit pas valide.
Gryphon - Réintégrez Monica

Oups, j'ai écrit cela en utilisant un objet et j'ai oublié de supprimer certaines références et de copier intégralement le code. Je vais les réparer dès que je rentre à la maison.
coolioasjulio

D'ACCORD. Si c'est juste une petite erreur, je la corrige (comme je l'ai fait dans d'autres bots, et je l'aurais si c'était juste le problème de soi-même), mais une fonction manquante est une histoire différente.
Gryphon - Réintégrez Monica

@Gryphon j'ai corrigé les bugs. (enlevé le moi, ajouté le référencé lost_against_map, et corrigé la déclaration if vérifiant si le tour est honnête)
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

Juste un peu mieux que mon entrée précédente ...

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 sur les stéroïdes

Je pense que la suggestion que @ user1502040 fait dans les commentaires devrait être suivie. Sinon, ce bot aurait un avantage que je jugerais injuste. Je le soumets pour que la différence qu’elle fait puisse être évaluée. Avec l'ensemencement aléatoire suggéré, les stéroïdes seraient neutralisés et le bot équivaudrait à csbot, un seul participant devrait alors participer au concours.

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.