Ehrlicher Stein, Papier, Schere


58

Viele Leute halten RPS für ein Glücksspiel. Wenn beide Spieler unvorhersehbar spielen, ist es die beste Strategie, nach dem Zufallsprinzip zu spielen. Lassen Sie uns jedoch ein wenig Vorhersehbarkeit einführen.

Jeder Bot hat die Möglichkeit, dem anderen Bot mitzuteilen, was er gleichzeitig spielen wird. Dann gibt es eine Pause, in der jeder Bot weiß, was der andere Spieler angekündigt hat. Wenn es diese Waffe ausspielt, die es angekündigt hat, erhält es zusätzlich zu seinen Punkten einen Punkt für einen Sieg, eine Niederlage oder ein Unentschieden.

Ein Sieg ist zwei Punkte wert, ein Unentschieden, ein Punkt und ein Verlust 0 Punkte.

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

Es ist in Ihrem besten Interesse, ehrlich zu sein (aber auch sicherzustellen, dass Ihr Gegner Ihnen nicht glaubt).

Die Matches werden in einem Round-Robin-Format gespielt und das Ziel ist es, Ihre eigene Gesamtpunktzahl über die von Ihnen gespielten Matches hinweg zu maximieren.

E / A-Format:

  • Ihr Bot wird eine Python 2.7-Funktion sein, die 4 Argumente akzeptiert und einen eindeutigen Namen haben muss (der verwendet wird, um Ihre Einreichung darzustellen).
  • Die ersten beiden Argumente lauten immer der Reihe nach: die letzten Züge des Gegners, gefolgt von Ihren letzten Zügen. Hierbei handelt es sich um eine Liste in der Reihenfolge von der ersten bis zur letzten Runde, wobei jeder Index eine Liste mit dem Zug enthält, den der Gegner angeblich ausführen würde, gefolgt von dem Zug, den er tatsächlich ausgeführt hat.
  • Mit den nächsten beiden Argumenten kann Ihr Bot feststellen, ob es sich um eine "ehrliche" oder eine "echte" Runde handelt. Wenn es sich um eine "ehrliche" Runde handelt, sind beide "Keine". Wenn es sich um eine "echte" Runde handelt, handelt es sich um den Zug, den Ihr Gegner angekündigt hat, gefolgt von dem Zug, den Sie angekündigt haben.
  • Alle Argumente oder Teile von Argumenten, die Bewegungen darstellen, verwenden "R", "P" und "S", um Stein, Papier bzw. Schere darzustellen.
  • Ihre Funktion sollte entweder ein "R" für Stein, ein "P" für Papier oder ein "S" für Schere zurückgeben. Bots, die die Möglichkeit haben, andere Werte zurückzugeben, werden disqualifiziert.
  • Jeder Bot wird 200 Mal gegen jeden anderen Bot und 100 Mal gegen sich selbst ausgeführt. Ziel ist es, am Ende des Wettbewerbs der Bot mit den meisten Punkten zu sein.
  • In Bezug auf die Diskussion in den Kommentaren dürfen die Einsendungen keine Dateien lesen oder in diese schreiben oder in irgendeiner Weise den Code des Gegners sabotieren oder lesen.

Beispiele:

Dies sind vier Beispiel-Bots, die ich schnell zusammengestellt habe. Sie werden als zusätzliche Bots am Wettbewerb teilnehmen. Wenn Sie bis zum letzten verlieren, müssen Sie noch etwas arbeiten.

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

Regler:

Und hier ist der Controller, den ich verwenden werde. Neue Einreichungen werden zu Beginn importiert und dem bot_map-Wörterbuch hinzugefügt.

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

Endergebnisse:

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
Wie ist der Status?
user1502040

Antworten:


11

Mason

Versucht, Informationen über andere Bots zu sammeln, wie zum Beispiel, wie ehrlich sie sind und wie sie durch meinen ersten Zug beeinflusst werden. Ich versuche dann, andere offensichtliche Bots zu finden, die einem Muster folgen, und nutze diese, um mir mehr Punkte zu geben. Schließlich hat der Maurer eine Geheimwaffe: Kenntnis einer Geheimgesellschaft, in der beide Bots, die sich gegenseitig beteiligen, eine vollständige Auslosung vornehmen und jeweils 500 Punkte erhalten. Leider ist das Geheimnis eher ... Gut geheim und ändert sich jedes Mal, wenn der Maurer es tut.

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: Stärkung des Lernens

Verwendet einen verstärkenden Lernansatz und geht dieses Spiel auf ähnliche Weise an wie das n-bewaffnete Banditenproblem. Dies geschieht auf zwei Arten: Es wird versucht zu lernen, welche Erklärung gegen jeden Gegner besser ist und sich an diese hält (nützlich gegen konstante Bots), und es wird versucht, das Ergebnis verschiedener Züge in früheren ähnlichen Situationen zu lernen (ähnlich in Bezug auf die relativen Spiele) (zB Stein gegen Papier ähnelt einem früheren Papier gegen Schere). Die anfänglichen Annahmen sind optimistisch, so dass dieser Spieler annehmen wird, dass es 3 Punkte gibt, wenn er ehrlich ist, und dass Lügen 2 Punkte gibt, und daher immer ehrlich ist, bis das Gegenteil bewiesen ist.

Update: Die ersten Turnierergebnisse zeigten ein Problem mit diesem Bot, das darin bestand, dass er in den Erklärungen seines Gegners keine Muster erkennen konnte (was dazu führte, dass er gegen Rotatoren nicht optimal spielte). Ich habe dann dem Code für die ehrlichen Runden eine Mustervergleichskomponente hinzugefügt, die mithilfe eines regulären Ausdrucks nach dem längsten Suffix in der Geschichte der Gegnererklärungen sucht, das irgendwo zuvor in dieser Geschichte vorhanden war, und welche Aktion danach ausgeführt wurde . Wir gehen davon aus, dass der Gegner den gleichen Zug noch einmal spielen wird, und verwenden das vorhergehende Verstärkungslernen, um zu entscheiden, wie die beste Antwort darauf aussehen soll.

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

Probieren Sie es online!


6

Ich habe Python noch nie wirklich benutzt, also bin ich mir sicher, dass ich irgendwo einen Fehler gemacht habe.

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

Es sollte die letzten 10 Runden überprüfen, um festzustellen, wie oft der Gegner gelogen hat, und dann abhängig davon eine andere Antwort wählen.


6

Hier ist mein adaptiver Bot. Es analysiert die letzten 2 Züge des Gegners, um festzustellen, ob es ein ehrlicher Bot ist oder nicht, und spielt dementsprechend:

Edit 1: Wenn der andere Bot ein konstanter Bot ist (dh immer die gleiche Waffe spielt), zerquetscht dieser Bot ihn, indem er die siegreiche Waffe spielt und gleichzeitig ehrlich ist.

Edit 2: Verbesserter Detektor für konstante Bots, um auch mit Rotator-Bots zu arbeiten.

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]

Seien Sie ehrlich, solange der andere Spieler es ist, und entdecken Sie einfache deterministische Bots. Spielen Sie den Zug, der den erwarteten Wert maximiert, bei dem wir hauptsächlich unsere Punkte sammeln, aber auch dem anderen Spieler keine Punkte geben möchten. Aber die eigenen Punkte sind um den Faktor zehn besser, daher die ungewöhnlichen Zahlen in der valueFunktion. Gegnerische Züge werden danach erwartet, wie oft wir sie in dieser Situation zuvor gesehen haben (deklarierte Züge), aber kürzlich gesehene Züge werden stärker gewichtet als zuvor gesehene Züge. Bei zufälligen Anfangszügen (Situationen, die noch nie zuvor gesehen wurden) und etwas mehr Unschärfe enthalten die Gewichte kleine zusätzliche Zufallszahlen.

Update: Nutzen Sie die erwarteten Ergebnisse auch in der ehrlichen Runde. Um dies tun zu können, normalisiere und berücksichtige den zusätzlichen Punkt, den der Gegner für die Ehrlichkeit erhält - er konnte unsere Entscheidung in der realen Runde nicht beeinflussen, wird aber jetzt benötigt. Ich dachte von Anfang an darüber nach, dachte aber fälschlicherweise, dass es sich nicht lohnen würde. Ich habe gesehen, dass es möglich ist, trusting_botweniger Punkte zu geben (aber dieser Bot ist sowieso kein starker Gegner), aber ich habe übersehen, dass rockbotdurch gutes Spiel in der ehrlichen Runde zusätzliche Punkte erzielt werden können, obwohl das Spiel in dieser Runde zufällig ist.


Dies scheint nicht immer ein Ergebnis zu liefern.
user1502040

Ich denke, dein if mydecl == None:ist falsch.
user1502040

@ user1502040 Warum denkst du so? Ich habe noch nie ein Problem beobachtet.
Christian Sievers


4

Verrat

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

Die Idee ist, dass ich in den ersten 50 Zügen ehrlich spiele und dann, wenn ich den Gegner dazu gebracht habe zu denken, ich sei ehrlich, unehrlich zu spielen und zu versuchen, das zu spielen, was dem Gegner entgegenwirken würde (basierend darauf, ob er ehrlich oder unehrlich war) in der Vergangenheit). Wenn ich den Punkt erreiche, an dem ich so oft ehrlich als unehrlich gespielt habe, ändere ich die Taktik und wähle den wahrscheinlichsten Zug des Gegners auf der Grundlage vorher bekannter Konfigurationen.


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

3

Bot Name: Ich erinnere mich, wie du lügst

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

Getestet für mehrere 100-Runden-Läufe und stellte sich heraus, dass der Sieger im Durchschnitt etwa 220 Punkte erzielt. Eher ehrlich finde ich;)

Das erste Mal, dass ich an KOTH-Herausforderungen teilnehme, daher denke ich, dass es noch Raum für Verbesserungen gibt


3

Wie du mir so ich dir

Der klassische Axelrodianer: hoffnungsvoll und doch kleinlich; Einfach und doch robust. Dies ist kein Gefangenendilemma, und ich habe keinen Versuch unternommen, den Zug des Gegners vorherzusagen. Ich bezweifle daher, dass er wirklich wettbewerbsfähig sein wird. Aber "kooperieren" bringt immer noch die meisten Punkte für die Teilnehmer, also denke ich, wird es zumindest mittelmäßig gehen.

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

Zwei Drittel

Verwendet die Strategie, die Peter Taylor in der Sandbox und in diesem Kommentar erwähnt hat .

Es nutzt das Nash-Gleichgewicht .

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

Dieser Fehler ist für mich. Geben Sie in Zeile 13 random.choice (moves) zurück. Ich denke, es liegt wahrscheinlich daran, dass Sie .choice für ein Wörterbuch verwenden. Bis das behoben ist, ist diese Einsendung leider ungültig.
Gryphon - Setzen Sie Monica

@Gryphon Es ist kein Wörterbuch, es ist eine Menge.
Text

Ach, entschuldigung. Ich habe nur kleine Klammern gesehen und dachte "Wörterbuch". Mein Fehler. Irgendeine Idee, warum die random.choice dann in dieser Zeile fehlerhaft ist?
Gryphon - Setzen Sie Monica

@Gryphon Es scheint, als ob Sie random.choiceeine zufällige Indexnummer auswählen und dann das Objekt in der Liste an diesem Index zurückgeben müssen. Da Sets keine Reihenfolge haben, unterstützen sie auch keine Indizierung und funktionieren daher nicht mit random.choice. Eine einfache Lösung hierfür wäre, das Set vor dem Aufruf in eine Liste umzuwandeln random.choice.
Text

Ah. Ich habe kein Python auf diesem Computer, daher kann ich das momentan nicht beheben, aber ich werde es in meinem Code beheben, wenn ich nach Hause komme. Wenn @ mbomb007 hier Abhilfe schaffen würde, wäre das großartig.
Gryphon - Setzen Sie Monica

3

Tiefer Gedanke

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

Nur ein paar Anmerkungen dazu:

  • DeepThought denkt gern. Viel. Es tut mir leid, aber ich weiß nicht wirklich, wie ich es beheben soll. Ich beschuldige Python.
  • DeepThought versucht ehrlich zu sein. Wenn Sie ehrlich sind, erhalten Sie einen zusätzlichen Punkt, der dem erwarteten Wert für normales RPS entspricht
  • Aber: DeepThought erreicht im Durchschnitt sogar mehr als 2 Punkte pro Spiel. Er verwendet eine gewisse Erkennung, um einige häufig vorkommende Verhaltensweisen zu finden (z. B. Tricks, Ehrlichkeit usw.) und passt sich dem an.
  • DeepThought ist rein deterministisch, es wird sich also gegen sich selbst richten, weil es an beiden Enden immer die gleiche Entscheidung trifft.
  • Um nicht an sich selbst zu liegen, hat es eine spezielle Erkennung, wie auch einige andere Bots hier. Dies ist ein sehr aggressiver Vorgang, der sogar nach einer Runde (und auch in der ersten Runde) als wahr vorausgesetzt wird. Grundsätzlich gehe ich davon aus, dass es sich um ein Mirror Match handelt, solange der Gegner genau meine Züge ausführt.
  • Der interessante Teil (und der Teil, der Dutzende von Fehlalarmen enthält) ist die Überprüfung auf einen deterministischen Bot, der nur von seinem eigenen vorherigen Ergebnis abhängt. Diese Prüfung sucht nach einem Muster der Größe n, das zweimal wiederholt wird und das die letzten n-1 Züge beschreiben kann, wobei der Anspruch des Gegners vorhergesagt und der Zug im Voraus ausgeführt wird. Dieser Teil braucht leider einige Zeit.

Ich bin neu für beide, Koth und Python, also sag mir, ob ich irgendetwas in diesem Bot durcheinander gebracht habe. Ich denke nicht, dass es das verstärkte Lernen überbieten kann (weil ich vermute, dass es meine Bewegungen zu schnell lernen wird), aber lassen Sie es uns versuchen.

Ich mag diese Herausforderung, und wenn ich etwas Zeit finde, möchte ich einen Ansatz für organisches Rechnen hinzufügen (obwohl die höheren Dimensionen möglicherweise zu wenig Druck ausüben). Dürfen mehrere Vorschläge hinzugefügt werden? Oder ist es verboten, das Boosten Ihres Hauptbots zu verhindern, indem Sie einige einsetzen, die nur darauf abzielen, sich gegen Ihren Hauptbot zu verlieren?

EDIT: Ein Code-Tippfehler wurde behoben, der mich als nicht englischsprachigen Muttersprachler charakterisierte


Es ist nicht verboten, mehrere Einträge zu veröffentlichen, aber es ist verboten, einen Eintrag zu veröffentlichen, der einen anderen Bot unterstützt (auch einen, der nicht von Ihnen stammt). Es ist in Ordnung, gegen einen anderen Bot zu verlieren, solange dies nicht beabsichtigt ist.
Gryphon - Setzen Sie Monica

Beim Ausführen ist ein Fehler aufgetreten, da für die 32. Zeile Ihrer DeepThought-Funktion return resultein zusätzlicher Einzug erforderlich ist. Ich glaube, es sollte innerhalb der gigantischen if-Anweisung liegen, die unmittelbar danach returnfolgt , da die Variable nur in dieser it-Anweisung deklariert wird. Ich habe diese Änderung in meinem Code vorgenommen und sie wird nun fehlerfrei ausgeführt. Wenn es Ihnen nichts ausmacht, diese Änderung hier vorzunehmen, wäre das großartig.
Gryphon - Wiedereinsetzung von Monica

3
Sie scheinen sich mit dem Zustand des globalen Zufallsgenerators herumzuschlagen, was wahrscheinlich nicht in Ordnung ist. Ich hielt eine ähnliche Sache zu tun, und fand diese Lösung: Erstellen Sie ein neues zufälliges Objekt mit R=random.Random(seed)und verwenden Sie es wie folgt aus : R.choice(...).
Christian Sievers

@Gryphon behoben. Wahrscheinlich sind einige Fehler aufgetreten, als ich von meinem lokalen Skript zu se gewechselt habe, bei denen alles ein weiteres Mal
eingefügt

1
@alexberne Sie können den eingefügten Code auswählen und auf die {}Schaltfläche in der Symbolleiste klicken, um jede Zeile automatisch einzurücken.
Selcuk

2
import random
def user5957401bot(a,b,c,d):
    if d == None: 
       return random.choice(["R","P","S"])
    else:
       return random.choice(["R","P","S",d])

2

haben_wir_hier_vorher

Fragt einfach "Waren wir schon einmal hier?" Und wählt den Zug aus, der das beste durchschnittliche Ergebnis in einem solchen früheren Spiel erzielt hätte.

Bearbeiten: Honesty Club. Ich habe einen kleinen Codeblock hinzugefügt, weil ein anderer Bot (Maurer) es sehr gut gemacht hat, mit sich selbst einen geheimen Club zu gründen. Beachten Sie jedoch, dass ein ehrliches Spiel gegen ehrliche Gegner im Durchschnitt genau den gleichen Gewinn bringt, wenn Sie gegen sich selbst spielen.

Edit2: Zum Zeitpunkt des Schreibens der beiden Bots vor mir nutzen beide Rotatoren, also werde ich einen weiteren Codeblock hinzufügen, um auch auf diesen Zug zu springen. Ich denke, mein Code scheint ziemlich altmodisch zu sein - ich halte mich an vertraute Konstrukte, die in jeder Programmiersprache zu finden sind, weil ich Python wirklich nicht kenne.

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: DER ehrliche Ausbeuter

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

Mir ist gerade aufgefallen, dass ich durch einen Klick einen Abstimmungsfehler gemacht habe, sorry. Wird rückgängig gemacht, wenn Sie bearbeiten. (Kann es nicht anders ändern.)
Christian Sievers

@ChristianSievers bearbeitet
Cinaski

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

Interessanter Eintrag. Ich werde es bald ausführen, sollte in der Lage sein, die Ergebnisse heute Nachmittag zu veröffentlichen.
Gryphon - Setzen Sie Monica

OK, ich habe die Parameter leicht umgedreht.
user1502040

Verstanden. Tut mir leid, dass das Update so lange dauert, es ist nur so, dass jedes Mal, wenn es fast fertig ist, jemand seinen Bot aktualisiert, oder ich bekomme einen neuen und muss ihn erneut ausführen.
Gryphon - Setzen Sie Monica

@Gryphon Sie könnten eine Tabelle mit den Ergebnissen aller Paarungen führen. Wenn also ein Bot aktualisiert wird, müssen Sie nur 200 * (num_bots - 1) + 100 neue Matches ausführen.
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

Ich werde einen einfachen Bot ausprobieren, der das letzte Spiel seines Gegners unter diesen Bedingungen wiederholt


Willkommen bei 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]

Die Idee dabei ist, die Punktzahl zu maximieren, während Sie sich selbst spielen, während Sie in anderen Phasen zufällig gegen andere schlechte Bots antreten.


1
Das Wort isist ein Schlüsselwort, das ist also ungültig.
Erik der Outgolfer

@EriktheOutgolfer danke :)
Stephen

1

Dx

Ich habe nur diesen Bot geschrieben, damit ich einen Smiley in meinem Bot-Namen xD haben kann.

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

Jeder lügt

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"

Es liegt an seinem Zug ("Ich spiele Schere!") Und es wird davon ausgegangen, dass der Gegner auch gelogen hat und versucht, meinen Zug zu schlagen ("hmm, Rock schlägt Schere, also spiele ich dass "), aber ich spiele tatsächlich den Zug, der diesen Zug schlägt (" Papier! Überraschung! ").


3
Klingt für mich wie die erste Stufe der Iocain-Pulver- Strategie :-) "Jetzt würde ein kluger Mann das Gift in seinen eigenen Becher stecken , weil er wissen würde, dass nur ein großer Dummkopf nach dem greifen würde, was ihm gegeben wurde. Das bin ich nicht Ein großer Narr, also kann ich den Wein vor dir nicht eindeutig auswählen. Aber du musst gewusst haben, dass ich kein großer Narr bin, du hättest damit gerechnet, also kann ich den Wein vor mir eindeutig nicht auswählen. . "
Antony

1

Vertrauender Bot

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

Behauptet immer, eine Schere zu werfen, tut aber, was der Gegner gesagt hat. Wird zuverlässig mit sich selbst zeichnen.


Dies wäre effektiver, wenn es immer ehrlich gegen sich selbst wäre.
Gryphon - Wiedereinsetzung von Monica

@Gryphon Wahrscheinlich, aber ich pythoniere nicht gut genug, um zu versuchen, etwas zu machen, das so zusammenarbeitet.
ATaco


1

Botname: Lügner Lügner

Kann nicht aufhören zu lügen.

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

Nimmt an, dass der Gegner ehrlich ist und versucht, ihn zu schlagen, weigert sich jedoch, Rock zu spielen.

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
Dies scheint ein Fehler zu sein, da in der letzten Zeile "P", "S" nicht in eckigen Klammern steht (keine Liste). Ich habe das in meiner Version geändert, aber wenn Sie dasselbe hier tun könnten, wäre es großartig. Vielen Dank.
Gryphon - Reinstate Monica

Wird das nicht furchtbar gegen eine ständige Schere verlieren?
Wildcard

@Wildcard ja, aber es wird ziemlich gut gegen Papier-Bot
Slepz

1

Name des Bots: dontlietome

Bestimmt, ob der Gegner lügt oder nicht, abhängig davon, wie oft der Gegner in den letzten 10 Runden gelogen hat. Wählt den Zug je nachdem, ob der Gegner lügt oder nicht. Wenn der Gegner entschlossen ist zu lügen, spielt er, was der Hinweis war.

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

In der Zeile "if is_trustworthy (opp_moves, self.length):" ist self nicht definiert. Darüber hinaus ist in der Zeile "return lose_against_map [opp_hint]" lose_against_map ebenfalls nicht definiert. Die Selbstlänge scheint durch Entfernen des Selbst gelöst zu werden. aber das andere problem bleibt bestehen. Bis das behoben ist, fürchte ich, ist das ungültig.
Gryphon - Wiedereinsetzung von Monica

Hoppla, ich habe dies mit einem Objekt geschrieben und vergessen, einige Selbstreferenzen zu entfernen und den Code vollständig zu kopieren. Ich repariere die, sobald ich nach Hause komme.
Coolioasjulio

OKAY. Wenn es nur ein kleiner Fehler ist, korrigiere ich ihn (wie bei einigen anderen Bots), aber eine fehlende Funktion ist eine andere Geschichte.
Gryphon - Wiedereinsetzung von Monica

@Gryphon Ich habe die Fehler behoben. (entfernte das Selbst, fügte das referenzierte hinzu lost_against_mapund
korrigierte

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

Nur ein bisschen besser als mein vorheriger Eintrag ...

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 auf Steroiden

Ich denke, der Vorschlag, den @ user1502040 in den Kommentaren macht, sollte befolgt werden. Andernfalls hätte dieser Bot einen Vorteil, den ich für unfair halte. Ich reiche es ein, damit der Unterschied, den es macht, beurteilt werden kann. Mit der vorgeschlagenen zufälligen Aussaat würden die Steroide neutralisiert und der Bot würde gleichwertig sein csbot, so dass nur einer am Wettbewerb teilnehmen sollte.

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.