Skip to content

Instantly share code, notes, and snippets.

@TilBlechschmidt
Created March 6, 2016 20:11
Show Gist options
  • Save TilBlechschmidt/3183acd71dc6f0243933 to your computer and use it in GitHub Desktop.
Save TilBlechschmidt/3183acd71dc6f0243933 to your computer and use it in GitHub Desktop.
Gist
pub fn step<R: Rng>(&mut self, rng: &mut R) {
let games_per_ref = self.games_per_client / self.score_references.len();
let mut pb = ProgressBar::new(self.current_generation.len()*self.score_references.len()*games_per_ref);
let mut avg_scores: Vec<(usize, f32)> = self.current_generation.iter().enumerate().map(|(index, contestant)| {
let threads = self.score_references.iter().map(|reference| { // TODO: Run this in multiple threads
thread::spawn(move || {
let rng = rand::thread_rng();
(0..games_per_ref).map(|game_id| {
//TODO: Use the same game field for the same generation.
let mut g;
//if game_id%2 == 0 { // Change sides for every second game
g = Game::new_random(contestant, reference, &mut rng);
//} else {
// g = Game::new_random(reference, contestant, rng);
//}
let scores = g.run();
pb.inc();
scores[0]
}).collect::<Vec<_>>()
})
});
let scores = Vec::new();
for handle in threads {
scores.extend(handle.join().unwrap()); // TODO: Remove unwrap
}
let score_sum = scores.iter().fold(0, |acc, score| score + acc);
//.fold(0, |acc, score| score + acc )
// let score_sum =
// self.score_references.iter().flat_map(|reference| { // TODO: Run this in multiple threads
// (0..games_per_ref).map(|game_id| {
// //TODO: Use the same game field for the same generation.
// let mut g;
// //if game_id%2 == 0 { // Change sides for every second game
// g = Game::new_random(contestant, reference, rng);
// //} else {
// // g = Game::new_random(reference, contestant, rng);
// //}
// let scores = g.run();
// pb.inc();
// scores[0]
// }).collect::<Vec<_>>()
// }).fold(0, |acc, score| score + acc );
let avg_score = score_sum as f32 / (games_per_ref * self.score_references.len()) as f32;
(index, avg_score)
}).collect();
avg_scores.sort_by(|a, b| if a.1 < b.1 {Ordering::Greater} else {Ordering::Less});
let new_score_refs = avg_scores
.iter().take(self.score_references.len())
.map(|&(index, _)| self.current_generation[index].clone())
.collect();
let generation_size = self.current_generation.len();
let mutation_per_survivor = (generation_size - self.survivor_count) / self.survivor_count;
let new_generation = avg_scores.iter().take(self.survivor_count).flat_map(|&(index, _)| {
let survivor = self.current_generation[index].clone();
let mut mutations = (0..mutation_per_survivor).map(|_| {
let mut mutation = survivor.clone();
mutation.mutate(self.mutation_amount, self.mutation_strength, rng);
mutation
}).collect::<Vec<_>>();
mutations.push(survivor);
mutations
}).collect::<Vec<_>>();
if !(generation_size == new_generation.len()) {
println!("GENERATION SIZE CHANGED {} ---> {}", self.current_generation.len(), new_generation.len());
}
println!("Best average score of generation is: {}", avg_scores[0].1);
self.current_generation = new_generation;
self.score_references = new_score_refs;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment