Author | ffenliv |
Submission date | 2019-01-28 15:20:19.300484 |
Rating | 2660 |
Matches played | 244 |
Win rate | 27.05 |
Use rpsrunner.py to play unranked matches on your computer.
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 = 20 # options to weight results from each possible history path differently
D_WEIGHT = 40
T_WEIGHT = 30
P_WEIGHT = 20
M_S_WEIGHT = 5
M_D_WEIGHT = 5
M_T_WEIGHT = 3
M_P_WEIGHT = 2
def get_output(s_response, d_response, t_response, p_response, m_s_response, m_d_response, m_t_response, m_p_response):
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]
response = BEATS[choice]
if round < 50 or 100 <= round <= 125 or 225 <= round <= 230 or 310 <= round <= 340 or 450 <= round <= 500 or 615 <= round <= 652 or 699 <= round <= 712 or 767 <= round <= 790 or 834 <= round <= 867:
lim_MOVES = MOVES
lim_MOVES.remove(response)
choice = random.choice(lim_MOVES)
#inv_response = BEATS[response]
return choice
else:
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)
pre_response = MOVES[random.choice(max_rolls)] # response is random choice from max_rolls
if pre_response < 10:
response = random.choice(MOVES)
return response
else:
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
if round % randint(1,29) == 0:
output = random.choice(MOVES)
my_history.append(output)
else:
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)