BrainBot
import numpy as np
class BrainBot(Bot):
def __init__(self, index, end_score):
super().__init__(index, end_score)
self.brain = [[[-0.1255, 0.338, 0.5265, -0.2728], [-0.2064, -1.9173, 0.1845, -0.2536], [-0.6737, -0.1334, -0.7055, 0.0797], [-0.6055, -0.0126, 0.9261, -0.603], [0.447, -0.5381, -1.7416, 0.0596], [0.1649, -0.6795, -1.1039, -0.0138], [-0.2782, -0.2005, -1.2967, -0.8073], [0.2329, -0.5591, 1.6192, -0.218]], [[0.7411, 0.3139, 0.435, 1.002, -0.3148, -0.7791, -0.6532, -0.4672, -0.4655], [0.1982, 0.3713, 0.0426, -0.9227, 1.6118, 0.9431, 0.5612, 0.1208, 0.1115]]]
def decide(self, input_data):
x = np.array(input_data)
wI = 0
for w in self.brain:
x = [1.0 / (1 + np.exp(-el)) for el in np.dot(w, x)]
if wI<len(self.brain)-1:
x.append(-1)
return np.argmax(x)
def make_throw(self, scores, last_round):
while True:
oppMaxInd = -1
oppMaxScore = 0
for i in range(len(scores)):
if i==self.index: continue
if scores[i] > oppMaxScore:
oppMaxScore = scores[i]
oppMaxInd = i
if last_round:
yield scores[self.index]+sum(self.current_throws)<oppMaxScore+1
else:
s = [oppMaxScore/self.end_score,
scores[self.index]/self.end_score,
sum(self.current_throws)/self.end_score,
1.0 if last_round else 0.0]
yield self.decide(s)==1
This bot has a "brain" that is given the input [highest opponent score, own score, round score, is it final round] which it multiplies by a series of matrices to obtain the resulting decision vector. Also, I added some logic for the endgame, since it seems my algorithm couldn't take that into account (although the bit about "is it last round" is given in the input).
I used an evolutionary algorithm to try to find good coefficients for the matrices. It didn't work perfectly but the bot seems to do better than a random one. I'd be very interested to see if this idea can be improved. (How to do this for example with some machine learning techniques. How could we generate training data about choices when to make throw and when not?)