rpsbot4

Authorffenliv
Submission date2019-01-24 15:48:15.982728
Rating2602
Matches played243
Win rate23.87

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

Source code:

import random
from random import randint
import math
import re

MOVES = ["R","P","S"]
BEATS = {"R":"P", "P":"S", "S":"R"}
RESULT = {"R":{"R":0, "P":-1, "S":1}, "P":{"R":1, "P":0, "S":-1}, "S":{"R":-1, "P":1, "S":0}}

S_WEIGHT = 2 # options to weight results from each possible history path differently
D_WEIGHT = 4
T_WEIGHT = 3
P_WEIGHT = 2
M_S_WEIGHT = 1
M_D_WEIGHT = 1
M_T_WEIGHT = 1
M_P_WEIGHT = 1


def get_output(s_response, d_response, t_response, p_response, m_s_response, m_d_response, m_t_response, m_p_response):
    if randint(1,45) % randint(1,45) == 0:
        response = random.choice(MOVES)
        return response
    else:
        choices = [s_response, d_response, t_response, p_response, m_s_response, m_d_response, m_t_response, m_p_response]
        t_s_roll = randint(0, S_WEIGHT)
        t_d_roll = randint(0, D_WEIGHT)
        t_t_roll = randint(0, T_WEIGHT)
        t_p_roll = randint(0, P_WEIGHT)
        m_s_roll = randint(0, M_S_WEIGHT)
        m_d_roll = randint(0, M_D_WEIGHT)
        m_t_roll = randint(0, M_T_WEIGHT)
        m_p_roll = randint(0, M_P_WEIGHT)
        rolls = [t_s_roll, t_d_roll, t_t_roll, t_p_roll, m_s_roll, m_d_roll, m_t_roll, m_p_roll]
        max_roll = max(rolls)
        max_index = rolls.index(max_roll)
        max_rolls = [max_index]
        for count, i in enumerate(rolls):
            if i == max_roll and count != max_index:
                max_rolls.append(count)
        guess = random.choice(max_rolls)
        choice = choices[guess]
        if randint(1,45) % randint (1,45) == 0:
            pre_response = BEATS[choice]
            response = BEATS[pre_response]
            return response
        else:
            response = BEATS[choice]
            return response

def get_their_history(opp_history, opp_input, opp_throw, look_back):
    history_join = ''.join(opp_history) # join history into string
    for match in re.finditer(history_join[-look_back:], history_join): #iterate through string to find throw after pattern of look_back length
        if match.end() < len(history_join):
            common_response = history_join[match.end()]
            if common_response == 'R':
                opp_throw[0] += 1
            elif common_response == 'P':
                opp_throw[1] += 1
            elif common_response == 'S':
                opp_throw[2] += 1
    total = sum(opp_throw) # total number for calculating percentages; round would probably do, but I'm half-convinced it'll never work
    rolls = [0,0,0]
    for count, i in enumerate(opp_throw):
        if i > 0: # assign a roll to each possible response, from 0 to their total occurrences; skip the zeros to avoid division errors
            rolls[count] = randint(0, (i*100)/total)
        max_roll = max(rolls) # get the value of the max roll
        max_index = rolls.index(max(rolls)) # get the index of the max roll
        max_rolls = [max_index]
        for count, i in enumerate(rolls): # check for duplicates of the max roll to choose randomly from
            if i == max_roll:
                max_rolls.append(count)
        response = BEATS[MOVES[random.choice(max_rolls)]] # response is random choice from max_rolls
    return response

def get_my_history(my_history, my_input, my_throw, look_back):
    history_join = ''.join(my_history) # join history into string
    for match in re.finditer(history_join[-look_back:], history_join): #iterate through string to find throw after pattern of look_back length
        if match.end() < len(history_join):
            common_response = history_join[match.end()]
            if common_response == 'R':
                my_throw[0] += 1
            elif common_response == 'P':
                my_throw[1] += 1
            elif common_response == 'S':
                my_throw[2] += 1
    total = sum(my_throw) # total number for calculating percentages; round would probably do, but I'm half-convinced it'll never work
    rolls = [0,0,0]
    for count, i in enumerate(my_throw):
        if i > 0: # assign a roll to each possible response, from 0 to their total occurrences; skip the zeros to avoid division errors
            rolls[count] = randint(0, (i*100)/total)
        max_roll = max(rolls) # get the value of the max roll
        max_index = rolls.index(max(rolls)) # get the index of the max roll
        max_rolls = [max_index]
        for count, i in enumerate(rolls): # check for duplicates of the max roll to choose randomly from
            if i == max_roll:
                max_rolls.append(count)
        response = MOVES[random.choice(max_rolls)] # response is random choice from max_rolls
    return response

if(1): #main game loop

    if input == "": # no input means new game; initialize variables and throw a random choice
        their_history = []
        my_history = []
        s_throw = [0,0,0]
        d_throw = [0,0,0]
        t_throw = [0,0,0]
        p_throw = [0,0,0]
        m_s_throw = [0,0,0]
        m_d_throw = [0,0,0]
        m_t_throw = [0,0,0]
        m_p_throw = [0,0,0]
        round = 0
        output = random.choice(MOVES)
        my_history.append(output)

    else:
        if round < 10: # young game, continue throwing random moves
            output = random.choice(MOVES)
            my_history.append(output)
            their_history.append(input) # possibly remove this later, as their initial moves may not have useful information in them
            round += 1

        else: # begin strategizing to find decent throw
            s_response = get_their_history(their_history, input, s_throw, 1)
            d_response = get_their_history(their_history, input, d_throw, 2)
            t_response = get_their_history(their_history, input, t_throw, 3)
            p_response = get_their_history(their_history, input, p_throw, 5)
            m_s_response = get_their_history(my_history, input, m_s_throw, 1)
            m_d_response = get_their_history(my_history, input, m_d_throw, 2)
            m_t_response = get_their_history(my_history, input, m_t_throw, 3)
            m_p_response = get_their_history(my_history, input, m_p_throw, 5)
            their_history.append(input)
            round += 1
            output = get_output(s_response, d_response, t_response, p_response, m_s_response, m_d_response, m_t_response, m_p_response)
            #print(thisHapp, thatHapp)
            my_history.append(output)