meta2

This program has been disqualified.


Authorben haley
Submission date2012-08-12 06:37:55.964460
Rating6579
Matches played83
Win rate66.27

Source code:

""" Use multiple top strategies from the leaderboard and select
the one that is performing the best historically.

benjamin.haley@gmail.com Aug 2012

borrowed stragies from:
    pyfex (http://www.rpscontest.com/entry/135001)
    ben haley (http://www.rpscontest.com/entry/533009)
"""

import random

class s1:
    def __init__(self):
      self.hist = ""
      self.opp_played = []
      self.beat = {'P': 'S', 'S': 'R', 'R': 'P'}
      self.beat2 = {'PP': 'S', 'SS': 'R', 'RR':'P', 'PS': 'S', 'PR': 'P', 'RS': 'R', 'RP': 'P', 'SP': 'S', 'SR': 'R'}
      self.complement = {'PS': 'R', 'PR': 'S', 'RS': 'P', 'RP': 'S', 'SP': 'R', 'SR': 'P'}
      
      self.score = {'RR': 0, 'PP': 0, 'SS': 0, 'PR': 1, 'RS': 1, 'SP': 1,'RP': -1, 'SR': -1, 'PS': -1,}
      self.output = random.choice(["R", "P", "S"])

      self.candidates1 = [self.output, self.output]
      self.candidates2 = [self.output] * 5
      self.performance1 = [0, 0]
      self.performance2 = [(0,0)] * 5

    def predict(self, input):
      self.hist += self.output.lower()+input
      self.opp_played.append(input)
      self.performance1[0] += self.score[self.candidates1[0]+input]
      self.performance1[1] += self.score[self.candidates1[1]+input]
      
      for i, p in enumerate(self.candidates2):
        self.performance2[i] = ({1:self.performance2[i][0]+1, 0: self.performance2[i][0], -1: 0}[self.score[p+input]],  
                       self.performance2[i][1]+self.score[p+input])

      index1 = self.performance1.index(max(self.performance1))
      index2 = self.performance2.index(max(self.performance2, key=lambda x: x[0]**3+x[1]))
      self.candidates1[1] = self.beat[random.choice(self.opp_played)]
      
      for length in range(min(10, len(self.hist)-2), 0, -2):
        search = self.hist[-length:]
        idx = self.hist.rfind(search, 0, -2)
        if idx != -1:
          my = self.hist[idx+length].upper()
          opp = self.hist[idx+length+1]
          self.candidates2[0] = self.beat[opp]
          self.candidates2[1] = self.beat[self.beat[my]]
          self.candidates2[2] = self.beat2[self.beat[my] + self.beat[self.beat[opp]]]
          self.candidates2[3] = self.beat2[self.beat[opp] + self.beat[self.beat[my]]]
          self.candidates2[4] = self.complement[''.join(sorted(set(self.candidates2[0] + self.candidates2[1] + self.candidates2[3])))]
          break
      else:
          candidates = [random.choice(['R', 'P', 'S'])] * 5
     
      self.candidates1[0] = self.candidates2[index2]
      
      self.output = self.candidates1[index1]
      return self.output


from zlib import compress

class s2:
    def __init__(self):
        self.moves = {
            'rock':'r',
            'paper':'p',
            'scissors':'s'
        }

        self.comebacks = {
            ('rock',): ('paper',),
            ('paper',): ('scissors',),
            ('scissors',): ('rock',),
            ('paper', 'rock'): ('paper',),
            ('paper', 'scissors'): ('scissors',),
            ('rock', 'scissors'): ('rock',),
            ('paper', 'rock', 'scissors'): ('paper', 'rock', 'scissors'),
        }
        self.rmoves = dict((v.upper(), k) for k, v in self.moves.items())
        self.my_moves = []
        self.opp_moves = []
        self.output = random.choice('RPS')

    def complexity(self, string):
        """ What is the compressed size of a string?
        (larger is more complex)"""
        return len(compress(string, 9))

    def get_move_string(self, my_moves, opp_moves):
        """translate a list of moves into a compressible string"""
        return ''.join([self.moves[me] + self.moves[opp] for me, opp in zip(my_moves, opp_moves)])

    def expected(self, my_moves, opp_moves):
        """The most likely next move of the opponent"""
        history = self.get_move_string(opp_moves, my_moves)
        exps = [(self.complexity(history + self.moves[m]), m) for m in self.moves.keys()]
        brilliance = 0.91 #complexity(history) / float(complexity(shuffle_(history)))
        patients = 0 if brilliance < 0.90 else \
                   1 if brilliance < 0.96 else \
                   2
        res = tuple(sorted([e[1] for e in exps if e[0] <= min(exps)[0] + patients]))
        return res

    def player(self, my_moves, opp_moves):
        return random.choice(self.comebacks[self.expected(my_moves, opp_moves)])

    def shuffle_(self, string):
        array = list(string)
        shuffle(array)
        return ''.join(array)
        
    def predict(self, input):
        self.opp_moves += [self.rmoves[input]]
        my_move = self.player(self.my_moves, self.opp_moves)
        self.my_moves.append(my_move)
        self.output = my_move[0].upper()
        

if input == '':
    history = ''
    s1_ns = {}
    s2_ns = {}
    record = {'s1':0, 's2':0}
    values = {
        'RR':  0,
        'RP':  1,
        'RS': -1,
        'PR': -1,
        'PP':  0,
        'PS':  1,
        'SR':  1,
        'SP': -1,
        'SS':  0,
    }
    s1_ = s1()
    s2_ = s2()

else:
    history += input
    record['s1'] += values[input + s1_guess]
    record['s2'] += values[input + s2_guess]
    s1_.predict(input)
    s2_.predict(input)

s1_guess = s1_.output
s2_guess = s2_.output
output = s1_guess if record['s1'] > record['s2'] else s2_guess
print record, s1_guess, s2_guess, output, s1_guess == s2_guess