# article

 Author PiotrekG Submission date 2018-09-16 12:16:10.926617 Rating 6349 Matches played 267 Win rate 59.18

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

## Source code:

``````from __future__ import division
import random
import itertools

beat = {'R': 'P', 'P': 'S', 'S': 'R'}

class MarkovChain():
def __init__(self, order, decay=1.0):
self.decay = decay
self.matrix = self.create_matrix(order)

@staticmethod
def create_matrix(order):

def create_keys(order):

keys = ['R', 'P', 'S']

for i in range((order * 2 - 1)):
key_len = len(keys)
for i in itertools.product(keys, ''.join(keys)):
keys.append(''.join(i))
keys = keys[key_len:]

return keys

keys = create_keys(order)

matrix = {}
for key in keys:
matrix[key] = {'R': {'prob': 1 / 3,
'n_obs': 0
},
'P': {'prob': 1 / 3,
'n_obs': 0
},
'S': {'prob': 1 / 3,
'n_obs': 0
}
}

return matrix

def update_matrix(self, pair, input):

for i in self.matrix[pair]:
self.matrix[pair][i]['n_obs'] = self.decay * self.matrix[pair][i]['n_obs']

self.matrix[pair][input]['n_obs'] = self.matrix[pair][input]['n_obs'] + 1

n_total = 0
for i in self.matrix[pair]:
n_total += self.matrix[pair][i]['n_obs']

for i in self.matrix[pair]:
self.matrix[pair][i]['prob'] = self.matrix[pair][i]['n_obs'] / n_total

def predict(self, pair):

probs = self.matrix[pair]

if max(probs.values()) == min(probs.values()):
return random.choice(['R', 'P', 'S'])
else:
return max([(i[1], i[0]) for i in probs.items()])[1]

class RandomPredictor():

@staticmethod
def predict():
return random.choice(['R','P','S'])

# the first round
if input == '':

random_predictor = RandomPredictor()
markov_model = MarkovChain(1, 0.9)

pair_diff2 = ''
pair_diff1 = ''

# further rounds
else:
pair_diff2 = pair_diff1
pair_diff1 = output + input

if pair_diff2 != '':
markov_model.update_matrix(pair_diff2, input)
output = beat[markov_model.predict(pair_diff1)]

else:
output = random_predictor.predict()``````