This program has been disqualified.
Author | Byron Knoll |
Submission date | 2011-05-28 23:23:56.520201 |
Rating | 7818 |
Matches played | 110 |
Win rate | 78.18 |
#!/usr/bin/env python
#
# Iocaine Powder
# Originally devised by Dan Egnor for the first annual RoShamBo
# programming competition. Translated into python by David Bau.
# See http://ofb.net/~egnor/iocaine.html
import random
def beat(i):
return (i + 1) % 3
def loseto(i):
return (i - 1) % 3
def recall(age, hist):
"""Looking at the last 'age' points in 'hist', finds the
last point with the longest similarity to the current point,
returning 0 if none found."""
end, length = 0, 0
for past in xrange(1, min(age + 1, len(hist) - 1)):
if length >= len(hist) - past: break
for i in xrange(-1 - length, 0):
if hist[i - past] != hist[i]: break
else:
for length in xrange(length + 1, len(hist) - past):
if hist[-past - length - 1] != hist[-length - 1]: break
else: length += 1
end = len(hist) - past
return end
class Stats:
def __init__(self):
self.sum = [[0, 0, 0]]
def add(self, move, score):
self.sum[-1][move] += score
def advance(self):
self.sum.append(self.sum[-1])
def max(self, age, default, score):
if age >= len(self.sum): diff = self.sum[-1]
else: diff = [self.sum[-1][i] - self.sum[-1 - age][i] for i in xrange(3)]
m = max(diff)
if m > score: return diff.index(m), m
return default, score
class Predictor:
def __init__(self):
self.stats = Stats()
self.lastguess = -1
def addguess(self, lastmove, guess):
if lastmove != -1:
diff = (lastmove - self.prediction) % 3
self.stats.add(beat(diff), 1)
self.stats.add(loseto(diff), -1)
self.stats.advance()
self.prediction = guess
def bestguess(self, age, best):
bestdiff = self.stats.max(age, (best[0] - self.prediction) % 3, best[1])
return (bestdiff[0] + self.prediction) % 3, bestdiff[1]
ages = [1000, 20, 5]
class Iocaine:
def __init__(self):
self.predictors = []
self.predict_history = self.predictor((len(ages), 2, 3))
self.predict_frequency = self.predictor((len(ages), 2))
self.predict_fixed = self.predictor()
self.predict_random = self.predictor()
self.predict_meta = [Predictor() for a in xrange(len(ages))]
self.stats = [Stats() for i in xrange(2)]
self.histories = [[], [], []]
def predictor(self, dims=None):
if dims: return [self.predictor(dims[1:]) for i in xrange(dims[0])]
self.predictors.append(Predictor())
return self.predictors[-1]
def move(self, them):
if them != -1:
self.histories[1].append(them)
self.histories[2].append((self.histories[0][-1], them))
for watch in xrange(2):
self.stats[watch].add(self.histories[watch][-1], 1)
rand = random.randrange(3)
for a, age in enumerate(ages):
best = [recall(age, hist) for hist in self.histories]
for mimic in xrange(2):
for watch, when in enumerate(best):
if not when: move = rand
else: move = self.histories[mimic][when]
self.predict_history[a][mimic][watch].addguess(them, move)
mostfreq, score = self.stats[mimic].max(age, rand, -1)
self.predict_frequency[a][mimic].addguess(them, mostfreq)
self.predict_random.addguess(them, rand)
self.predict_fixed.addguess(them, 0)
for meta, age in enumerate(ages):
best = (-1, -1)
for predictor in self.predictors:
best = predictor.bestguess(age, best)
self.predict_meta[meta].addguess(them, best[0])
best = (-1, -1)
for meta in xrange(len(ages)):
best = self.predict_meta[meta].bestguess(age, best)
self.histories[0].append(best[0])
return best[0]
moveArray = ["R", "P", "S"]
if input == "":
iocaine = Iocaine()
param = -1
elif input == "R":
param = 0
elif input == "P":
param = 1
elif input == "S":
param = 2
output = moveArray[iocaine.move(param)]