public void CreateMutants(ProgressCallback progressCallback) { progressCallback(1); Directory.CreateDirectory(mutantsPath); dbContext.Configuration.AutoDetectChangesEnabled = false; using (var file = new FileStream(mutantsBinPath, FileMode.Create)) { using (var writer = new BinaryWriter(file)) { mutants = new Mutant[dbContext.NumMutants]; for (var i = 0; i < dbContext.NumMutants; ++i) { mutants[i] = mutantFactory.CreateMutant(i); mutants[i].WriteBytes(writer); dbContext.Mutants.Add(new MutantStat { Id = i }); progressCallback(1 + (i + 1) * 97 / dbContext.NumMutants); } } } progressCallback(99); dbContext.Configuration.AutoDetectChangesEnabled = true; dbContext.SaveChanges(); progressCallback(100); }
private void ButtonResetStats_Click(object sender, EventArgs e) { var result = MessageBox.Show("Are you sure to reset all mutant stats?", "Warning", MessageBoxButtons.OKCancel); if (result == DialogResult.OK) { dbContext.Configuration.AutoDetectChangesEnabled = false; foreach (var mutant in dbContext.Mutants) { mutant.Score = 0; mutant.Turns = 0; mutant.ScorePer100Turns = -100000; } dbContext.Configuration.AutoDetectChangesEnabled = true; dbContext.SaveChanges(); } }
private void ShowWorld() { var worldForm = new WorldForm() { DbContext = dbContext }; worldForm.RunOnMap = RunOnMap; worldForm.ViewMutant = ViewMutant; worldForm.LoadMutant = LoadMutant; worldForm.RunEvolution = RunEvolution; worldForm.StopEvolution = StopEvolution; worldForm.ResizeMutants = ResizeMutants; worldForm.Closed += (sender, e) => { dbContext.SaveChanges(); ExitThread(); }; worldForm.Show(); }
public void Run() { NativeMethods.PreventSystemSleep(); isStopped = false; dbContext.Configuration.AutoDetectChangesEnabled = false; dbContext.MapResets = 0; int consecutiveStaleTurns = 0; do { Collisions.Clear(); Position?[] newPositions = new Position?[numMutants]; Parallel.For(0, numMutants, new ParallelOptions { MaxDegreeOfParallelism = settings.numParallelThreads == 0 ? -1 : settings.numParallelThreads }, (i, state) => { var mutant = mutantManager.GetMutant(i); var car = Cars[i]; var decision = mutant.MakeDecision(Map, car, mutantMemory[i], settings.maxInstructionsToRun); switch (decision) { case Decision.Move: newPositions[i] = car.NextPosition(); break; case Decision.TurnBack: car.TurnBack(); break; case Decision.TurnLeft: car.TurnLeft(); break; case Decision.TurnRight: car.TurnRight(); break; case Decision.Stay: break; } }); Dictionary <Position, List <int> > positionBookings = new Dictionary <Position, List <int> >(); for (int i = 0; i < numMutants; ++i) { if (!newPositions[i].HasValue) { continue; } var pos = newPositions[i].Value; if (Collisions.Contains(pos)) { continue; } if (Map[pos] != PaneState.Blank) { Collisions.Add(pos); continue; } try { positionBookings.Add(pos, new List <int>()); positionBookings[pos].Add(i); } catch (ArgumentException) { if (settings.driveThru) { positionBookings[pos].Add(i); } else { Collisions.Add(pos); positionBookings.Remove(pos); } } } if (positionBookings.Count <= numMutants / 20) { ++consecutiveStaleTurns; } else { consecutiveStaleTurns = 0; } int[] scoreChanges = new int[numMutants]; ++turnsNoSucceed; foreach (var pair in positionBookings) { foreach (var i in pair.Value) { var car = Cars[i]; if (settings.driveThru) { car.Position = pair.Key; } else { Map[car.Position] = PaneState.Blank; car.Position = pair.Key; Map[car.Position] = car.Direction; } int score = car.IsDirectionRight() ? 8 : -8; if (car.Goal.Equals(car.Position)) { SetRandomGoal(i); consecutiveStaleTurns = 0; turnsNoSucceed = 0; } scoreChanges[i] = score; } } if (positionBookings.Count > 0) { for (int i = 0; i < numMutants; ++i) { var mutantStat = dbContext.Mutants.Find(GetMutantId(i)); mutantStat.Turns += 1; UpdateMutantScore(i, mutantStat, scoreChanges[i]); } } int totalDuplicates = 0; int totalMutatedBytes = 0; bool resetMap = false; bool recreateMutants = false; ++turnsNoReplicate; for (; ;) { var oldHighScore = mutantsByScore.Last().Key; var oldLowScore = mutantsByScore.First().Key; if (oldLowScore + settings.eliminateThreshold > oldHighScore) { if (totalDuplicates > 0) { break; } if (turnsNoSucceed < (Map.Width + Map.Height) * 2) { break; } if (turnsNoReplicate < Map.Width * Map.Height) { resetMap = consecutiveStaleTurns >= (Map.Width + Map.Height) / 2; break; } } else { consecutiveStaleTurns = 0; } turnsNoReplicate = 0; var winners = mutantsByScore.Last().Value; var losers = mutantsByScore.First().Value; var numReplicates = Math.Min(winners.Count, losers.Count); var replicated = winners.Take(numReplicates).ToList(); var eliminated = losers.Take(numReplicates).ToList(); recreateMutants = (oldHighScore - oldLowScore) < settings.eliminateThreshold / 2; if (oldHighScore == oldLowScore) { int[] sorted = new int[numMutants]; for (int i = 0; i < numMutants; ++i) { sorted[i] = i; } numReplicates = numMutants / 2; eliminated = sorted.Take(numReplicates).ToList(); replicated = sorted.Skip(numMutants - numReplicates).ToList(); } else if (oldLowScore + settings.eliminateThreshold > oldHighScore) { int[] sorted = new int[numMutants]; int i = 0; foreach (var item in mutantsByScore) { foreach (var id in item.Value) { sorted[i++] = id; } } numReplicates = numMutants / 4; eliminated = sorted.Take(numReplicates).ToList(); replicated = sorted.Skip(numMutants - numReplicates).ToList(); } int[] mutatedBytes = new int[replicated.Count]; Parallel.For(0, replicated.Count, new ParallelOptions { MaxDegreeOfParallelism = settings.numParallelThreads == 0 ? -1 : settings.numParallelThreads }, (i, state) => { var winner = GetMutantId(replicated[i]); var loser = GetMutantId(eliminated[i]); if (recreateMutants) { mutantManager.Recreate(loser); mutatedBytes[i] += dbContext.MutantSize; } else { mutatedBytes[i] += mutantManager.Replicate(winner, loser, settings.mostBytesToMutate); } mutantMemory[eliminated[i]] = new sbyte[256]; }); totalMutatedBytes += mutatedBytes.Sum(); for (int i = 0; i < replicated.Count; ++i) { var winner = replicated[i]; var loser = eliminated[i]; var winnerStat = dbContext.Mutants.Find(GetMutantId(winner)); var loserStat = dbContext.Mutants.Find(GetMutantId(loser)); // loserStat.Turns = 0; loserStat.Generation = winnerStat.Generation + 1; var scoreTransfer = (oldHighScore - oldLowScore) / 4; UpdateMutantScore(winner, winnerStat, -scoreTransfer); UpdateMutantScore(loser, loserStat, scoreTransfer); Map[Cars[loser].Position] = PaneState.Blank; Cars[loser].Position = GetRandomBlankPosition(); SetRandomCarDirection(loser); if (!settings.driveThru) { Map[Cars[loser].Position] = Cars[loser].Direction; } SetRandomGoal(loser); } totalDuplicates += replicated.Count; } ++dbContext.TotalTurns; dbContext.TotalReplicates += totalDuplicates; dbContext.TotalMutatedBytes += totalMutatedBytes; UpdateEvent?.Invoke(this, new EventArgs()); Application.DoEvents(); if (resetMap) { SetUpMap(); consecutiveStaleTurns = 0; ++dbContext.MapResets; } } while (!isStopped); mutantManager.Flush(); dbContext.Configuration.AutoDetectChangesEnabled = true; dbContext.SaveChanges(); NativeMethods.AllowSystemSleep(); }