Author | __nr__ |
Submission date | 2018-05-20 16:23:41.960220 |
Rating | 6637 |
Matches played | 295 |
Win rate | 62.71 |
Use rpsrunner.py to play unranked matches on your computer.
#!/usr/bin/env python
import sys
import time
import random
import math
import re
import operator
'''
Author: __NR__
Concept: history match then frequency counting with non-seeded randomness
- revised matching function (highest frequency match, not first)
[Reference] EbTech's "Boltzmann Counter," a variation on frequency counting, is
used when history fails. See http://www.rpscontest.com/entry/13015
[Reference] dllu, https://daniel.lawrence.lu/programming/rps/
'''
random_startPoint = {0:10, 1:20, 2:30} # high arc
random_dict = {1:"R", 2:"P", 3:"S"}
random_pick = random_dict[random.randint(1,3)]
beat_list = {"R":"P", "P":"S", "S":"R"}
def get_top_match(match, history):
match_count = {}
true_match = match
# print "true_match", true_match
# print "history", history
matches = re.finditer(true_match + ".", history, re.MULTILINE)
for matchNum, my_match in enumerate(matches):
matchNum = matchNum + 1
key_variable = re.sub(true_match, '', my_match.group())
if key_variable not in match_count:
match_count[key_variable] = 1
else:
match_count[key_variable] += 1
return max(match_count.iteritems(), key=operator.itemgetter(1))[0]
def second_defense(rockCount, paperCount, scissorsCount, random_pick, another_random):
'''
modified frequency counting
[Reference] EbTech's "Boltzmann Counter"
'''
if rockCount == paperCount == scissorsCount:
return random_pick
else:
# print rockCount, paperCount, scissorsCount
if another_random < math.exp(rockCount):
newVariable = "R"
elif another_random < math.exp(rockCount) + math.exp(paperCount):
newVariable = "P"
else:
newVariable = "S"
return newVariable
if input == "":
history = ''
masterCount = 0
newVariable = random_pick
rockCount = paperCount = scissorsCount = 0
startPoint = random_startPoint[random.randint(0,2)]
elif masterCount < startPoint:
history += input
newVariable = random_pick
masterCount += 1
rockCount *= 0.95
scissorsCount *= 0.95
paperCount *= 0.95
if input == "R":
paperCount += 0.1
scissorsCount -= 0.1
if input == "P":
scissorsCount += 0.1
rockCount -= 0.1
if input == "S":
rockCount += 0.1
paperCount -= 0.1
else:
# tick counters
rockCount *= 0.95
scissorsCount *= 0.95
paperCount *= 0.95
if input == "R":
paperCount += 0.1
scissorsCount -= 0.1
if input == "P":
scissorsCount += 0.1
rockCount -= 0.1
if input == "S":
rockCount += 0.1
paperCount -= 0.1
another_random = random.random()*(math.exp(rockCount)+math.exp(scissorsCount)+math.exp(paperCount))
# print "new variable: ", input
# print "history length", len(history)
# original match is the full length of all known history plus new value
match = history + input
for idx, val in enumerate(history):
# the match here is pared down until it is small enough to pattern-match
match = match[idx:]
# print "match attempted", match
# print "history full", history
# if the pattern does not exist in history, keep winding down match
if len(match) <= random.randint(1,2):
# print "down to random"
newVariable = second_defense(rockCount, paperCount, scissorsCount, random_pick, another_random)
break
# if the pattern exists in the history, find the next value
else:
if match in history:
# simple way of grabbing next value
try:
# find all variables that come after a match
# pick the highest count of variables
# newVariable = get_top_match(match, history)
befor_keyowrd, keyword, after_keyword = history.partition(match)
newVariable = beat_list[after_keyword[1]]
# print "we have a match, and it worked!", newVariable
except:
# print "we have a match, but it failed"
newVariable = second_defense(rockCount, paperCount, scissorsCount, random_pick, another_random)
break
history += input
# print "________________"
output = newVariable
# time.sleep(.5)