# neuralevolution

This program has been disqualified.

 Author pyfex Submission date 2011-07-20 15:49:15.571996 Rating 7029 Matches played 228 Win rate 70.61

## Source code:

``````# See http://overview.cc/RockPaperScissors for more information about rock, paper, scissors
# Trying out a new approach. Use a neural network. The weights are adjusted using an
# evolutionary technique.

if input == "":
from collections import defaultdict
import random
import operator
from itertools import izip
split = {'R': [1, 0, 0], 'P': [0, 1, 0], 'S': [0, 0, 1], '':[0, 0, 0]}
rps = ['R', 'P', 'S']
beat = {'P': 'S', 'S': 'R', 'R': 'P'}
cede = {'P': 'R', 'S': 'P', 'R': 'S'}
score = {'RR': 0, 'PP': 0, 'SS': 0, 'PR': 1, 'RS': 1, 'SP': 1,'RP': -1, 'SR': -1, 'PS': -1,}
hist = ""
patterns = defaultdict(str)
patterns2 = defaultdict(str)
output = random.choice(rps)
class Gene:
def __init__(self, length, initrandom=True):
self.length = length
if initrandom:
self.rockweight = [0] * (length+1)
v = random.random()
self.rockweight[random.randint(0,length-1)] = v
self.rockweight[length] = v / 2
self.paperweight = [0] * (length+1)
v = random.random()
self.paperweight[random.randint(0,length-1)] = v
self.paperweight[length] = v / 2
self.scissorsweight = [0] * (length+1)
v = random.random()
self.scissorsweight[random.randint(0,length-1)] = v
self.scissorsweight[length] = v / 2
else:
self.rockweight = [0] * (length+1)
self.paperweight = [0] * (length+1)
self.scissorsweight = [0] * (length+1)
self.performance = {'R': 1, 'P':1, 'S': 1}
self.totalperformance = 1
self.bestperformance = 0
self.candidates = []

def evaluate(self, neuroinp):
candidates = []
net = sum([i*w for i, w in izip(neuroinp, self.rockweight)])
if net > self.rockweight[-1]:
candidates.append('R')
net = sum([i*w for i, w in izip(neuroinp, self.paperweight)])
if net > self.paperweight[-1]:
candidates.append('P')
net = sum([i*w for i, w in izip(neuroinp, self.scissorsweight)])
if net > self.scissorsweight[-1]:
candidates.append('S')
self.candidates = candidates
return candidates

def teach(self, hand):
for h in rps:
if (h == hand) == (h in self.candidates):
self.performance[h] += 1
self.totalperformance += 1
self.bestperformance = max([self.performance[h] for h in rps])

def crossover(self, other):
new = Gene(self.length, initrandom=False)
for h in rps:
new.performance[h] = (self.performance[h] + other.performance[h]) / 2
new.totalperformance = (self.totalperformance + other.totalperformance) / 2

sep = self.performance['P'] / float(self.performance['P'] + other.performance['P'])
if sep > 0.75:
new.paperweight = self.paperweight[:]
elif sep < 0.25:
new.paperweight = other.paperweight[:]
else:
for i, (s, w) in enumerate(izip(self.paperweight, other.paperweight)):
new.paperweight[i] = (self.paperweight[i] + other.paperweight[i]) / 2

sep = self.performance['R'] / float(self.performance['R'] + other.performance['R'])
if sep > 0.75:
new.rockweight = self.rockweight[:]
elif sep < 0.25:
new.rockweight = other.rockweight[:]
else:
for i, (s, w) in enumerate(izip(self.rockweight, other.rockweight)):
new.rockweight[i] = (self.rockweight[i] + other.rockweight[i]) / 2

sep = self.performance['S'] / float(self.performance['S'] + other.performance['S'])
if sep > 0.75:
new.scissorsweight = self.scissorsweight[:]
elif sep < 0.25:
new.scissorsweight = other.scissorsweight[:]
else:
for i, (s, w) in enumerate(izip(self.scissorsweight, other.scissorsweight)):
new.scissorsweight[i] = (self.scissorsweight[i] + other.scissorsweight[i]) / 2
return new

genelength = 15
genes = [Gene(genelength) for e in xrange(50)]
g1 = Gene(genelength, initrandom=False)
g1.rockweight =     [1, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0.5]
g1.paperweight =    [0, 1, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0.5]
g1.scissorsweight = [0, 0, 1,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0.5]

genes = [g1] + genes
rnd = 0
my = opp = my2 = opp2 = ''
else:
for g in genes:
g.teach(input)
genes.sort(key=operator.attrgetter('totalperformance'), reverse=True)
del genes[-1]
del genes[-1]
del genes[-1]
del genes[-1]
del genes[-1]

for i in range(min(len(hist)/2,5), 0, -1):
pattern = patterns[hist[-i*2:]]
if pattern:
for j in range(min(len(pattern)/2,5), 0, -1):
patterns2[pattern[-2*j]] += output + input
patterns[hist[-i*2:]] += output + input

hist += output + input
my = opp = my2 = opp2 = ''
for i in range(min(len(hist)/2,5), 0, -1):
pattern = patterns[hist[-2*i:]]
if pattern:
my, opp = pattern[-2:]
for j in range(min(len(pattern)/2,5), 0, -1):
pattern2 = patterns2[pattern[-2*j]]
if pattern2:
my2, opp2 = pattern2[-2:]
break
break

neuroinp = split[opp] + split[my] + split[opp2] + split[my2] + split[input]
a, b = random.sample(genes, 2)
genes.append(a.crossover(b))
a, b = random.sample(genes[:25], 2)
genes.append(a.crossover(b))
a, b = random.sample(genes[:5], 2)
genes.append(a.crossover(b))
a, b = random.sample(genes[:10], 2)
genes.append(a.crossover(b))
n = Gene(genelength)
n.totalperformance = (a.totalperformance + b.totalperformance) / 2
genes.append(n)

for g in genes:
g.evaluate(neuroinp)
bestgene = genes[0]
worstgene = genes[-1]
candidates = bestgene.candidates

if candidates == []:
candidates = ['R', 'P', 'S']
output = beat[random.choice(candidates)]``````