Author | david.werecat |
Submission date | 2018-08-01 13:04:07.899590 |
Rating | 6898 |
Matches played | 280 |
Win rate | 69.29 |
Use rpsrunner.py to play unranked matches on your computer.
import random
class MinModel:
def __init__(self, decay):
self.decay = decay
self.prob = [0.0, 0.0, 0.0]
self.pred = [0, 0, 0]
self.last = random.randint(0, 2)
def predict(self):
p0 = self.prob[0]
p1 = self.prob[1]
p2 = self.prob[2]
self.pred[0] = self.last
self.pred[1] = (0 if p0 > p2 else 2) if p0 > p1 else (1 if p1 > p2 else 2)
rp = random.random() * (p0 + p1 + p2)
self.pred[2] = 0 if rp < p0 else (1 if rp < p1 else 2)
return self.pred
def update(self, val):
self.prob[0] *= self.decay
self.prob[1] *= self.decay
self.prob[2] *= self.decay
self.prob[val] += 1.0
self.last = val
class CtxModel:
def __init__(self, order, decay):
self.order = order
self.mask = (order + 1) << 2
self.cmsk = self.mask - 4
self.prob = [0.0 for i in range(0, self.mask)]
self.pred = [0 for i in range(0, order * 3)]
self.decay = decay
self.ctx = 0
self.mask -= 1
def predict(self):
tc = self.ctx
sc = 0
for o in range(0, self.order):
p0 = self.prob[self.ctx]
p1 = self.prob[self.ctx + 1]
p2 = self.prob[self.ctx + 2]
self.pred[sc] = int(self.prob[self.ctx + 3])
sc += 1
self.pred[sc] = (0 if p0 > p2 else 2) if p0 > p1 else (1 if p1 > p2 else 2)
sc += 1
rp = random.random() * (p0 + p1 + p2)
self.pred[sc] = 0 if rp < p0 else (1 if rp < p1 else 2)
sc += 1
tc = (tc >> 2) & self.cmsk
return self.pred
def update(self, val):
self.prob[self.ctx] *= self.decay
self.prob[self.ctx + 1] *= self.decay
self.prob[self.ctx + 2] *= self.decay
self.prob[self.ctx + 3] = val
self.prob[self.ctx + val] += 1.0
def nextctx(self, val):
self.ctx = ((self.ctx + val + 1) << 2) & self.mask
class ModelPicker:
def __init__(self, count, decay):
self.value = [1, -1, 0, 0, 1, -1, -1, 0, 1]
self.count = count
self.preds = [0 for i in range(0, count)]
self.weigh = [0.0 for i in range(0, count)]
self.decay = decay
def setpred(self, idx, val):
self.preds[idx] = val
def setpreds(self, idx, vals):
vl = len(vals)
for vi in range(0, vl):
self.preds[idx] = vals[vi]
idx += 1
def predict(self):
#self.preds[self.weigh.index(max(self.weigh))]
idx = 0
mxv = -10000.0
tmv = 0
for i in range(0, self.count):
tmv = self.weigh[i]
if tmv > mxv:
mxv = tmv
idx = i
return self.preds[idx]
def update(self, val):
val *= 3
for i in range(0, self.count):
self.weigh[i] = (self.weigh[i] * self.decay) + self.value[val + self.preds[i]]
if input == "":
wins = [1,2,0]
nval = {"R":0,"P":1,"S":2,"":0}
cval = ["R","P","S"]
minU = MinModel(0.93)
minT = MinModel(0.93)
ctxU2U = CtxModel(6, 0.93)
ctxU2T = CtxModel(6, 0.93)
ctxT2U = CtxModel(6, 0.93)
ctxT2T = CtxModel(6, 0.93)
ctxB2U = CtxModel(6, 0.93)
ctxB2T = CtxModel(6, 0.93)
sse = ModelPicker(346, 0.93)
else:
tval = nval[input]
minU.update(uval)
minT.update(tval)
ctxU2U.update(uval)
ctxU2U.nextctx(uval)
ctxU2T.update(tval)
ctxU2T.nextctx(uval)
ctxT2U.update(uval)
ctxT2U.nextctx(tval)
ctxT2T.update(tval)
ctxT2T.nextctx(tval)
ctxB2U.update(uval)
ctxB2U.nextctx(uval)
ctxB2U.nextctx(tval)
ctxB2T.update(tval)
ctxB2T.nextctx(uval)
ctxB2T.nextctx(tval)
sse.update(tval)
sse.setpreds(0, minU.predict())
sse.setpreds(3, minT.predict())
sse.setpreds(6, ctxU2U.predict())
sse.setpreds(24, ctxU2T.predict())
sse.setpreds(42, ctxT2U.predict())
sse.setpreds(60, ctxT2T.predict())
sse.setpreds(78, ctxB2U.predict())
sse.setpreds(96, ctxB2T.predict())
for i in range(0, 114):
sse.preds[i + 114] = wins[sse.preds[i]]
sse.preds[i + 228] = wins[sse.preds[i + 114]]
sse.setpreds(342, [0, 1, 2, random.randint(0, 2)])
uval = wins[sse.predict()]
output = cval[uval]