FirstOrderMarkovPredictFirst

AuthorAlex
Submission date2018-12-29 17:50:47.323878
Rating5956
Matches played259
Win rate60.23

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

Source code:

import random
import itertools

# First Order Markov Chain

def create_matrix():
    keys = ['R', 'P', 'S']
    key_len = len(keys)
    for i in itertools.product(keys, ''.join(keys)):
        keys.append(''.join(i))
    keys = keys[key_len:]
    for key in keys:
        markov_matrix[key] = {
            'R': {'prob' : default_prob,
                    'n_obs' : 0
            },
            'P': {'prob' : default_prob,
                    'n_obs' : 0
            },
            'S': {'prob' : default_prob,
                    'n_obs' : 0
            }
        }

def update_weights(pair , move):
    for i in markov_matrix[pair]:
        markov_matrix[pair][i]['n_obs'] = decay * markov_matrix[pair][i]['n_obs']

    markov_matrix[pair][move]['n_obs'] = markov_matrix[pair][move]['n_obs'] + 1
    n_total = 0
    for i in markov_matrix[pair]:
        n_total += markov_matrix[pair][i]['n_obs']
    
    for i in markov_matrix[pair]:
        markov_matrix[pair][i]['prob'] = markov_matrix[pair][i]['n_obs'] / n_total

def random_predict():
    return random.choice(['R' , 'P' ,'S'])

def predict(pair):
    moves = markov_matrix[pair]
    if(max(moves.values() , key = lambda x : x['prob']) == min(moves.values() , key = lambda x : x['prob'])):
        return random_predict()
    else:
        return max([(i[1], i[0]) for i in moves.items()] , key= lambda x : x[0]['prob'])[1]        

if input == '':
    default_prob = 1/3
    decay = 0.9
    markov_matrix = {}
    counter = {'R':'P' , 'P':'S' ,'S':'R'}
    create_matrix()
    pair_diff2 = ''
    pair_diff1 = ''

else:
    pair_diff2 = pair_diff1
    pair_diff1 = output + input

if pair_diff2 != '':
    output = counter[predict(pair_diff1)]
    update_weights(pair_diff2 , input)
else:
    output = random_predict()