/// <summary> /// Gets the average score a brain gets over a number of boards /// </summary> /// <returns></returns> private double AverageScore(Brain brain, int runs) { double minScore = 999999999; double avgTime = 0; double prevScore = 0; double avgTurns = 0; for (int i = 0; i < runs; i++) { NewBoard(i); while (Board1.Progress1Tick()) { RunBrain(Board1, brain); } prevScore += CalculateScore(Board1); minScore = Math.Min(CalculateScore(Board1), minScore); avgTime += Board1.Tick; avgTurns += Board1.Turns; } avgTime /= runs; avgTurns /= runs; Console.WriteLine(minScore); Console.WriteLine(avgTime); Console.WriteLine(avgTurns); return(prevScore / runs); }
/** * <summary>Generates new brains, the size of the brain is determined by height * width</summary> * <param name="hlHeight">determines thd width of the hidden layer</param> * <param name="hlWidth">determines the height of the hidden layers</param> */ private void ModeGenerateNewBrains(int hlWidth, int hlHeight) { NewBoard(); DrawFieldRectangles(); NewBrain(hlWidth, hlHeight); while (savedFilesCount < savedFilesMax) { RedrawField(); bool gameOver = true; for (int i = 0; i < 1000; i++) { if (Board1.Progress1Tick()) { RunBrain(); gameOver = false; } else { gameOver = true; break; } } if (!gameOver) { continue; } Board1.GameOver = true; //gameover double score = CalculateScore(); if (score > ScoreTreshold) { try { string filename = "SnakeBrainFile" + Math.Floor(score).ToString() + "-" + DateTime.Now.Ticks.ToString() + ".dat"; FileStream SnakeBrainFile = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write); Formatter.Serialize(SnakeBrainFile, SnakeBrain); SnakeBrainFile.Close(); savedFilesCount++; //MessageBox.Show("Saved snakebrain as " + filename); } catch (Exception err) { MessageBox.Show("Error saving snake brain."); MessageBox.Show(err.Message); } //MessageBox.Show("You crashed into your own tail and died or you ran out of time, your final score was " + string.Format("{0:N2}", score) + "\n\nGrow more quickly and grow larger to gain a larger score"); } NewBoard(); NewBrain(hlWidth, hlHeight); } MessageBox.Show("End of program, " + savedFilesCount.ToString() + " brain files generated.\nReview the executables' folder to see the brain files"); Restart(); }
private void DemoAICycle() { RedrawField(); if (Board1.Progress1Tick()) { RunBrain(); } else {//gameOver NewBoard(); } }
private void DemoAICycle() { RedrawField(); if (Board1.Progress1Tick()) { RunBrain(Board1, SnakeBrain); } else {//gameOver Counter++; NewBoard(Counter); } }
/// <summary> /// runs the main brain a few times after mutating it and returns its average score /// </summary> /// <param name="mutateMagnitude">The magnitude by which mutations can happen</param> /// <param name="iterations">The number of times the snake plays the game before returning the average score.</param> /// <param name="mutateNRR">Determines how much mutation magnitude distrubution conforms to a normal distribution.</param> /// <returns>the average score</returns> private double ModeTrainAI(double mutateMagnitude = .1, int mutateNRR = 4, int iterations = 100, int mutationChance = 5) { SnakeBrain.Mutate(mutateMagnitude, mutateNRR, mutationChance); double averageScore = 0; for (int i = 0; i < iterations; i++) { NewBoard(i); while (Board1.Progress1Tick()) { RunBrain(); } averageScore += CalculateScore(); } return(averageScore / iterations); }
/// <summary> /// runs the main brain a few times after mutating it and returns its average score /// </summary> /// <param name="mutateMagnitude">The magnitude by which mutations can happen</param> /// <param name="iterations">The number of times the snake plays the game before returning the average score.</param> /// <param name="mutateNRR">Determines how much mutation magnitude distrubution conforms to a normal distribution.</param> /// <param name="randomly">Whether or not to use deterministic brain changes</param> /// <param name="incrementor">if non-random then this must should increment by 1 each call</param> /// <returns>the average score</returns> private double ModeTrainAI(double mutateMagnitude = .1, int mutateNRR = 4, int iterations = 100, int nrOfMutations = 2, bool randomly = false, int incrementor = 0) { if (randomly) { SnakeBrain.Mutate(mutateMagnitude, mutateNRR, nrOfMutations); } double averageScore = 0; for (int i = 0; i < iterations; i++) { NewBoard(i); while (Board1.Progress1Tick()) { RunBrain(Board1, SnakeBrain); } averageScore += CalculateScore(Board1); } return(averageScore / iterations); }
private void ModeTrainAIButton_Click(object sender, RoutedEventArgs e) { if (!double.TryParse(ModeTrainAIDegreeBox.Text, out double degree)) { MessageBox.Show("Invalid interval value, please input a double (aka. decimal) value"); return; } if (!int.TryParse(ModeTrainAIIterationsBox.Text, out int iterations)) { MessageBox.Show("Invalid iterations value, please input an integer"); return; } if (!int.TryParse(ModeTrainAIMutationChanceBox.Text, out int mutationChance)) { MessageBox.Show("Invalid mutation chance value, please input an integer"); return; } mutationChance = 100 / mutationChance; if (!int.TryParse(ModeTrainAINRRBox.Text, out int nrr)) { MessageBox.Show("Invalid NRR value, please input an integer"); return; } if (!double.TryParse(ModeTrainAITresholdBox.Text, out double treshold)) { MessageBox.Show("Invalid treshold value, please input a double"); return; } OpenFileDialog dlg = new OpenFileDialog { DefaultExt = ".dat", Filter = "Data Files (*.dat)|*.dat" }; bool?result = dlg.ShowDialog(); if (result != true) { MessageBox.Show("Couldn't recover file path"); return; } if (!File.Exists(dlg.FileName)) { MessageBox.Show("Couldn't find that file"); return; } try { FileStream SnakeBrainInstanceFromFile = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read); SnakeBrain = (Brain)Formatter.Deserialize(SnakeBrainInstanceFromFile); SnakeBrainInstanceFromFile.Close(); } catch (Exception err) { MessageBox.Show("Could not load selected snake brain file for this demo"); MessageBox.Show(err.Message); return; } int len = MainGrid.Children.Count; for (int i = 0; i < len; i++) { MainGrid.Children.RemoveAt(0); } NewBoard(); DrawFieldRectangles(); Brain prevBrain = DeepCopy(SnakeBrain); double prevScore = 0; for (int i = 0; i < iterations; i++) { NewBoard(); while (Board1.Progress1Tick()) { RunBrain(); } prevScore += CalculateScore(); } prevScore /= iterations; MinScore = prevScore * 0.75; int count = 1000000000; while (--count > 0) { double score = ModeTrainAI(degree, nrr, iterations, mutationChance); if (score / treshold > prevScore && score > MinScore) { if (score * .75 > MinScore) { MinScore = score * .75; try { string filename = "TrainedSnakeBrainFile" + Math.Floor(score).ToString() + "-" + SnakeBrain.HiddenLayerWidth + "-" + SnakeBrain.HiddenLayerHeight + "-" + iterations.ToString() + "-" + DateTime.Now.Ticks.ToString() + ".dat"; FileStream SnakeBrainFile = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write); Formatter.Serialize(SnakeBrainFile, SnakeBrain); SnakeBrainFile.Close(); savedFilesCount++; } catch (Exception err) { MessageBox.Show("Error saving snake brain."); MessageBox.Show(err.Message); } } prevScore = score; prevBrain = DeepCopy(SnakeBrain); } else { SnakeBrain = DeepCopy(prevBrain); } if (savedFilesCount > savedFilesMax) { break; } } }