MarkovChainLearner[v2]

AuthorEmmanuel Harish Menon
Submission date2019-05-10 22:30:40.788200
Rating4966
Matches played231
Win rate47.62

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

Source code:

'''
Program Name: MarkovChainLearner v2 [SubmissionCode]
Program by: Emmanuel Harish Menon
Last Updated: 8:26 AM 11/5/19
Explanation:
This program uses Markov chains to respond to the probability that the user will pick rock, paper or scissors. It was made for the contest at rpscontest.com
'''
#import modules
import random
from decimal import Decimal

#transition table of nested dictionaries
transitionTable = {"R": {"S": 0, "P": 0, "R": 0}, "S": {"S": 0, "P": 0, "R": 0}, "P": {"S": 0, "P": 0, "R": 0}}

#stores number of plays
playCount = {"R": 0, "P": 0, "S": 0}

#used to determine a random pick
choices = ["R", "P", "S"]

#stores all move history
moveHistory = []

#this function updates values in transition table
def updater(moveHistory, transitionTable):
    #increases the appropriate value in the play count dict
    playCount[moveHistory[-1]] += 1

    #this will run as long as move history is larger than 1
    if len(moveHistory) > 1:
        #stores last two plays into individual vars
        slice1 = moveHistory[-2]
        slice2 = moveHistory[-1] 

        #stores a portion of the nested dict into editDict
        editDict = transitionTable[slice1]

        #updates the relevant variable
        editDict[slice2] += 1

def picker():
    #stores the actual percentages for the markov chains while the transitionTable stores integer values
    percentageTable = {"R": 0, "P": 0, "S": 0}

    #stores a the relevant portion of the nested dict
    editDict = transitionTable[moveHistory[-1]]

    #creates a list of R, P, S based on percentages in percentageTable
    pickList = []

    #iterates through and converts the values in the transition table into percentages
    for k, v in editDict.items():
        if v == 0:
            return choices[random.randint(0, 2)]
        else:
            #converts the float to a decimal to an int
            percentageTable[k] = int(Decimal((v / (playCount[moveHistory[-1]]- 1))*100))
            #adds everything to pick lists
            for i in range(percentageTable[k]):
                pickList.append(k)
    #this list will find the predicted user pick
    pick = pickList[random.randint(0, len(pickList) - 1)]

    #returns a value based on the predicted user's pick
    if pick is "R":
        return "P"
    elif pick is "P":
        return "S"
    elif pick is "S":
        return "R"

if input is not "":
    #add the prev pick to the list
    moveHistory.append(input)
    #update transition table
    updater(moveHistory, transitionTable)

if len(moveHistory) == 0:
    output = choices[random.randint(0, 2)]
else:
    output = picker()