sclass AIStrategy_Racer_RandomWithVary extends AIStrategy {
// user must set
F0 random;
F1 vary;
// user can set
int discardEvery = 5000;
// internal
AIStrategy_RandomWithVariation leader, overtaker;
new Best leadersBest;
int roundsSinceChange;
public bool step() { go(); false; }
AIStrategy_RandomWithVariation newAI() {
ret copyFields(this, new AIStrategy_RandomWithVariation, 'random, 'vary);
}
void go {
if (tossACoin()) {
if (leader == null) leader = newAI();
A guess = leader.guess();
if (guess == null) ret;
double score = submit(guess);
leader.updateBest(guess, score);
leadersBest.put(guess, score);
} else {
if (overtaker == null) overtaker = newAI();
A guess = overtaker.guess();
if (guess == null) ret;
double score = submit(guess);
overtaker.updateBest(guess, score);
if (score > leadersBest.score()) {
// displace leader!
if (verbose)
print("Overtake at " + formatScore(overtaker.best.score()) + " vs " + formatScore(leadersBest.score()));
leader = overtaker;
overtaker = null;
roundsSinceChange = 0;
} else if (roundsSinceChange++ >= discardEvery) {
// make new overtaker
if (verbose)
print("Discarding overtaker at " + formatScore(overtaker.best.score()) + " vs " + formatScore(leadersBest.score()));
overtaker = null;
roundsSinceChange = 0;
}
}
}
}