public static async Task RunCompetitions(string mapPath, CompetetionMode competetionMode, CancellationToken cancellationToken = default) { switch (competetionMode) { case CompetetionMode.NoContainer: break; case CompetetionMode.ContainerPerCompetetion: await DockerService.BuildImageAsync(Directory.GetCurrentDirectory(), Program.DockerImageName, cancellationToken); await DockerService.StopAndRemoveAllContainersAsync(cancellationToken); break; case CompetetionMode.ReusableContainer: await DockerService.BuildImageAsync(Directory.GetCurrentDirectory(), Program.DockerImageName, cancellationToken); await DockerService.StopAndRemoveAllContainersAsync(cancellationToken); await ContainerRepository.InitalizeContainers(_geneProcessLimit, Program.DockerImageName, cancellationToken); break; } _arenaStartTime = DateTime.Now; Console.WriteLine("welcome to Colosseum. enjoy the show :)"); List <Gene> lastGeneration = null; var lastGenerationFile = new FileInfo("generationInfo.json"); if (lastGenerationFile.Exists) { Console.WriteLine($"loading last generation from {lastGenerationFile.FullName}"); try { var content = await File.ReadAllTextAsync(lastGenerationFile.FullName, cancellationToken); lastGeneration = JsonConvert.DeserializeObject <List <Gene> >(content); } catch (Exception ex) { Console.WriteLine($"loading last generation failed. error:{Environment.NewLine}{ex}"); } } var generationNumber = 1; var arenaDir = new DirectoryInfo("arena"); arenaDir.Create(); var currentRunDir = arenaDir.CreateSubdirectory(DateTime.Now.ToString("s").Replace(" ", "-").ToValidFileName()); currentRunDir.Create(); var port = _startPort; var cts = new CancellationTokenSource(); cancellationToken.Register(() => cts.Cancel()); while (true) { var generationProcessStartTime = DateTime.Now; var generationDir = currentRunDir.CreateSubdirectory(generationNumber.ToString()); generationDir.Create(); var newGeneration = _generationGenerator.Genetic(lastGeneration); lastGeneration = new List <Gene>(); var competitionTasks = new List <Task>(); switch (competetionMode) { case CompetetionMode.NoContainer: await cleanSystem(cancellationToken); break; case CompetetionMode.ContainerPerCompetetion: await DockerService.StopAndRemoveAllContainersAsync(cancellationToken); break; case CompetetionMode.ReusableContainer: break; } Console.WriteLine($"running generation #{generationNumber}"); Console.WriteLine($"this generation will have {newGeneration.Count} genes and we'll process up to {_geneProcessLimit} genes simultaneously"); Console.WriteLine("-----------"); Console.WriteLine("no.\tsuccess\tscore\t\tid\t\telapsed\t\tsystem elapsed\t\tPPM\t\tcurrent time"); foreach (var gene in newGeneration) { competitionTasks.AddThreadSafe(processGene(gene, mapPath, lastGeneration, port, generationDir, competetionMode, cancellationToken)); port++; } await Task.WhenAll(competitionTasks).CancelOnFaulted(cts); var generationInfoFilePath = Path.Combine(generationDir.FullName, "generationInfo.json"); await File.WriteAllTextAsync(generationInfoFilePath, JsonConvert.SerializeObject(newGeneration, Formatting.Indented), cancellationToken); var generationScoreAverage = newGeneration.Average(x => x.Score); Console.WriteLine($"generation score average: {generationScoreAverage}, generation elapsed time: {DateTime.Now - generationProcessStartTime}"); generationNumber++; } }