Giveaway 5

Authorflug
Submission date2019-06-04 22:48:20.601154
Rating3363
Matches played229
Win rate33.19

Use rpsrunner.py to play unranked matches on your computer.

Source code:

#Giveaway version 5
#Trying to lose as many rounds as possible and get to the bottom of the leaderboard

#Just repeats R, P, or S constantly, but evaluates which of the three
#actually gives the worst results in any given match and sticks with 
#that one.

#This version is based on noticing that programs that repeat just R, P, or S do
#very bad, almost as bad as the worst RPS programs, including those deliberately
#designed to be bad--many of those with very highly designed and complex 
#algorithms. So literally a one-liner is almost equally bad.

#But we can probably do even worse if we can choose
#among constant R, P, and S depending on which seems to be 
#worst in any given match. This could probably be implemented in 
#10 lines or so but I'm too lazy for that.

import random

debug = 0
activateHold = 0
output = ""

if input == "":
   saveinput = ""
   saveoutput = ""
   rounds=0
   won=0
   lost=0   
   draw=0
   hold=0
   strategiestried = 0   
     
   strategynamesall = ["constantr","constantp","constants", "random"]
   strategynamespick = ["constantr","constantp","constants"]
   
   choice1 = random.choice(strategynamespick)
   
   if (debug == 1): print "STARTING: ", choice1, rounds
   winlist = []
   strategylist = []
   winsperstrategylist = dict.fromkeys(strategynamesall,0)
   roundsperstrategylist = dict.fromkeys(strategynamesall,0)
   lastChange=0  

   badcount = {}
   badcount['R'] = badcount['P'] = badcount['S'] = 0

else:
    rounds += 1;
    badcount[input] += 1


roundsperstrategylist[choice1] += 1
   
   
if saveoutput==input:
   draw += 1
   winlist.append(0)
   winsperstrategylist[choice1] += 0
elif (input == "R" and saveoutput == "S") or (input == "S" and saveoutput == "P") or (input == "P" and saveoutput == "R"): 
   lost += 1
   winlist.append(-1)
   winsperstrategylist[choice1] += -1   
else:
    won += 1
    winlist.append(1)
    winsperstrategylist[choice1] += 1
    
# Change the constant answer periodically
if (rounds % 67 == 0):
   currConstant = random.choice(["S","P","R"])  


recents = 35
minChange = 35
decisionPoint = -1
recentTot = 0
origChoice = choice1
initialRounds = (minChange+1) * len(strategynamespick)
#if (debug == 1): print initialRounds

if (hold == 0 and rounds - lastChange > minChange):
   for x in range(recents):
       if (rounds-x>0):
          recentTot += winlist[rounds-x]
   #if (debug == 1): print "rdrlm: ", recentTot, decisionPoint, rounds, lastChange, minChange
   if (recentTot > decisionPoint):
      if (strategiestried < len(strategynamespick) - 1 ):
         #print "strategiestried: ", strategiestried, len(strategynamespick)
         if (strategynamespick.index(choice1) + 1 < len(strategynamespick)):
            choice1 = strategynamespick[strategynamespick.index(choice1) + 1]         
         strategiestried += 1
         if (debug == 1): print "SELECTING NEXT TRIAL STRATEGY: ", choice1, rounds
      else:
           choice2 = random.choice(strategynamespick)
           for n in strategynamespick:
               nsuccess = 0
               if ( roundsperstrategylist[n] != 0):
                  nsuccess = float(winsperstrategylist[n])/float(roundsperstrategylist[n])
                  
               csuccess = 0
               if roundsperstrategylist[choice2] != 0:
                  float(winsperstrategylist[choice2])/float(roundsperstrategylist[choice2])   
                  
               if (roundsperstrategylist[n] >= minChange) and (roundsperstrategylist[choice2] < 1 or nsuccess <= csuccess):
                  if (debug == 1): print n, choice2, ": ", roundsperstrategylist[n], roundsperstrategylist[choice2], nsuccess, csuccess
                  choice2 = n 
           choice1 = choice2    
           if (debug == 1): print "CHANGING STRATEGICALLY: ", choice1, rounds
           if (debug == 1): print winsperstrategylist 
           if (debug == 1): print roundsperstrategylist   
      lastChange=rounds            

#choice1 = "constant"    
   
##OR if we have a decent little loss buildup, we just try to hold it   
#if (hold == 1 or won < (lost - 150) or (rounds > 500 and won < (lost - 40))):
if (activateHold == 1 and (hold == 1 or won < (lost - 25) or (rounds > 500 and won < (lost - 15)))):   
   choice1 = "random"
   if hold == 0:
      if (debug == 1): print rounds, won, lost, draw 
      if (debug == 1): print "HOLDING: ", choice1, rounds
   hold = 1


##getting too close for comfort, switch back to losing   
if (hold == 1 and won > (lost - 5)):
    choice2 = random.choice(strategynamespick)
    for n in strategynamespick:
      nsuccess = 0
      if ( roundsperstrategylist[n] != 0):
        nsuccess = float(winsperstrategylist[n])/float(roundsperstrategylist[n])
      csuccess = 0
      if roundsperstrategylist[choice2] != 0:
        float(winsperstrategylist[choice2])/float(roundsperstrategylist[choice2])
      if (roundsperstrategylist[n] >= minChange) and (roundsperstrategylist[choice2] < 1 or nsuccess <= csuccess):
        if (debug == 1): print n, choice2, ": ", roundsperstrategylist[n], roundsperstrategylist[choice2], nsuccess, csuccess
        choice2 = n
    choice1 = choice2
    if (debug == 1): print "LEAVING HOLD STRATEGICALLY: ", choice1, rounds
    if (debug == 1): print winsperstrategylist 
    if (debug == 1): print roundsperstrategylist   
    hold = 0
## Just keep outputting the same response each time
#  Most bots trying to win should beat this handily
#  But it would be easily defeated by another giveaway bot
if choice1 == "constantr":  
   if random.randint(0,6)==1: 
      output = "R"
   else: output = random.choice(["R","P","S"])
   
elif choice1 == "constantp":
   if random.randint(0,6)==1:   
      output = "P"
   else: output = random.choice(["R","P","S"])
   
elif choice1 == "constants":   
   if random.randint(0,6)==1:
      output = "S"
   else: output = random.choice(["R","P","S"])        
     
   
## If we're losing badly enough we can switch to random mode and no one should
#  be able to recover and beat us   

elif choice1 == "random":
   output = random.choice(["R","P","S"])
   
else:
   print "HELPME!"
   output = currConstant
      

strategylist.append(choice1)

if (rounds % 999 == 0 and rounds > 1): 
   #if (debug == 1): print '[%s]' % ', '.join(map(str, strategylist))
   #if (debug == 1): print ("Giveaway strategies: ", strategylist) 
   if (debug == 1): print winsperstrategylist 
   if (debug == 1): print roundsperstrategylist   
   if (debug == 1): print "END:", rounds, won, lost, draw
   if (won>lost and debug == 1): print "WON\n"
   elif (debug == 1): print "LOST\n"

saveinput = input  
saveoutput = output