Author | david.werecat |
Submission date | 2018-08-01 16:56:23.776090 |
Rating | 7261 |
Matches played | 279 |
Win rate | 71.68 |
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.last = random.randint(0, 2)
def predict(self, pred, idx):
p0 = self.prob[0]
p1 = self.prob[1]
p2 = self.prob[2]
pred[idx] = self.last
pred[idx + 1] = (0 if p0 > p2 else 2) if p0 > p1 else (1 if p1 > p2 else 2)
rp = random.random() * (p0 + p1 + p2)
pred[idx + 2] = 0 if rp < p0 else (1 if rp < p1 else 2)
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 = [random.randint(0, 2) if i&3 == 3 else 0.0 for i in range(0, self.mask)]
self.decay = decay
self.ctx = 0
self.mask -= 1
def predict(self, pred, idx):
tc = self.ctx
for o in range(0, self.order):
p0 = self.prob[self.ctx]
p1 = self.prob[self.ctx + 1]
p2 = self.prob[self.ctx + 2]
pred[idx] = int(self.prob[self.ctx + 3])
idx += 1
pred[idx] = (0 if p0 > p2 else 2) if p0 > p1 else (1 if p1 > p2 else 2)
idx += 1
rp = random.random() * (p0 + p1 + p2)
pred[idx] = 0 if rp < p0 else (1 if rp < p1 else 2)
idx += 1
tc = (tc >> 2) & self.cmsk
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.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) + VALUE[val + self.preds[i]]
if input == "":
VALUE = [1,-1,0,0,1,-1,-1,0,1]
WINS = [1,2,0]
LOSS = [2,0,1]
NVAL = {"R":0,"P":1,"S":2,"":0}
CVAL = ["R", "P", "S"]
minU = MinModel(0.93)
minT = MinModel(0.93)
ctxU2U = CtxModel(8, 0.93)
ctxU2T = CtxModel(8, 0.93)
ctxT2U = CtxModel(8, 0.93)
ctxT2T = CtxModel(8, 0.93)
ctxB2U = CtxModel(8, 0.93)
ctxB2T = CtxModel(8, 0.93)
sse = ModelPicker(454, 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)
minU.predict(sse.preds, 0)
minT.predict(sse.preds, 3)
ctxU2U.predict(sse.preds, 6)
ctxU2T.predict(sse.preds, 30)
ctxT2U.predict(sse.preds, 54)
ctxT2T.predict(sse.preds, 78)
ctxB2U.predict(sse.preds, 102)
ctxB2T.predict(sse.preds, 126)
for i in range(0, 150):
sse.preds[i + 150] = WINS[sse.preds[i]]
sse.preds[i + 300] = WINS[sse.preds[i + 114]]
sse.setpreds(450, [0, 1, 2, random.randint(0, 2)])
uval = WINS[sse.predict()]
output = CVAL[uval]