/// <summary> /// Does the a basic sudo genetic algorithm to determine the most optimal values for KingsWorth, PawnsWorth, KingsDangerValue, PawnsDangerValue. /// This was not originally part of the project. This was my attempt at letting the AI tell me what works best for these values. /// <para> /// This method essentially works by using a WinningGenome and RandomGenome. The starting winning genome is based on the initial settings file. /// The random genome is based on the current winning genome with slighly increased or decreased values. The algorithm runs through n simulations /// and tracks the number of wins the random genome gets. If the random genome wins more than 50% of the time, it becomes the new winning genome. /// The new randome genome is based on that winner and the loop starts over. /// </para> /// </summary> private void DoGeneticAlgo() { GeneticProgress currentProgress = GeneticProgress.GetGeneticProgressInstance(); WinningGenome winningGenome = WinningGenome.GetWinningGenomeInstance(); RandomGenome randomGenome = RandomGenome.GetRandomGenomeInstance(); while (currentProgress.NumberOfGames < Settings.NumberOfSimulations) { try { RunAIDuel(); } catch (AIException ex) { //Dont count this game Logger.Error("AI Exception was caught: " + ex.Message); //reset game InitializeCheckers(); continue; } currentProgress.NumberOfGames++; object winner = checkerBoard.GetWinner(); if (winner != null && winner is PlayerColor winningPlayer && winningPlayer == PlayerColor.Red) { currentProgress.NumberOfRandomGenomeWins++; } Logger.Info("AI Game Finished, Winner was " + winner); Logger.Info(string.Format( "Current Stats -- NumberOfGamesPlayed: {0}, NumberOfRandomGenomeWins {1}", currentProgress.NumberOfGames, currentProgress.NumberOfRandomGenomeWins)); //reset game InitializeCheckers(); } //Simulations on this genetic variation finished. If more losses than wins, the new random genome was better if (currentProgress.NumberOfRandomGenomeWins > currentProgress.NumberOfGames / 2) { //Random Genome won more than half the games. This means we have a new winner winningGenome.SetNewWinningGenome(randomGenome); } //mutate new genome randomGenome.MutateGenomeAndSave(); //reset progress currentProgress.ResetValues(); currentProgress.NumberOfRounds++; }
/// <summary> /// Main loop for the basic genetic algorithm /// </summary> private void GeneticAlgoLoop() { int roundNumber = 0; while (roundNumber < Settings.NumberOfRounds) { DoGeneticAlgo(); Logger.Info("Finished Round Number: " + roundNumber++); } //finish up and delete temp file GeneticProgress.GetGeneticProgressInstance().Delete(); }