public IEnumerator DoGeneration(int identifier, FighterController opponentFighterController) { int simulationsPerFrame = 5; int simulationsLeft = 5; NeuralNetworkPopulation nnp = fighterPopulations[identifier]; for (int i = 0; i < nnp.Population.Count; i++) { int turn = 0; NeuralFighterController fighter = GameManager.Instance.gameObject.AddComponent <NeuralFighterController>(); FighterController opponentFighter = (FighterController)GameManager.Instance.gameObject.AddComponent(opponentFighterController.GetType()); Dictionary <int, FighterController> fighters = new Dictionary <int, FighterController> { { 0, fighter }, { 1, opponentFighter } }; Dictionary <int, BattleAction> previousFigherActions = new Dictionary <int, BattleAction> { { 0, new BattleAction(ActionType.NOTHING, 1) }, { 1, new BattleAction(ActionType.NOTHING, 0) } }; fighter.NeuralNetwork = nnp.Population[i]; fighter.Awake(); fighter.Start(); opponentFighter.Awake(); opponentFighter.Start(); while (fighter.Health > 0 && opponentFighter.Health > 0 && turn < NeuralParameters.MAX_TURNS) { BattleAction fighterAction = fighter.GetAction(fighters, previousFigherActions); BattleAction opponentAction = opponentFighter.GetAction(fighters, previousFigherActions); previousFigherActions[0] = fighterAction; previousFigherActions[1] = opponentAction; fighter.Health -= getReceivedDamage(fighterAction, opponentAction); opponentFighter.Health -= getReceivedDamage(opponentAction, fighterAction); turn++; } if (opponentFighter.Health < 0) { opponentFighter.Health = 0; } if (fighter.Health < 0) { fighter.Health = 0; } float fitness = fighter.Health - opponentFighter.Health - turn; if (opponentFighter.Health > 0 && fighter.Health > 0) { if (fitness > 0) { fitness *= NeuralParameters.POSITIVE_OUT_OF_TIME_MULTIPLIER; } else { fitness *= NeuralParameters.NEGATIVE_OUT_OF_TIME_MULTIPLIER; } } else if (opponentFighter.Health > 0 && fighter.Health <= 0) { fitness *= NeuralParameters.LOSE_MULTIPLIER; } nnp.Population[i].Fitness = fitness; Genome genome = nnp.GeneticAlgorithm.Population[i]; genome.Fitness = fitness; nnp.GeneticAlgorithm.Population[i] = genome; Destroy(fighter); Destroy(opponentFighter); if (--simulationsLeft < 0) { yield return(null); simulationsLeft = simulationsPerFrame; } } nnp.Epoch(); nnp.EliteEpoch(previousElite); Debug.Log(string.Format("Best fitness: {0} - Average fitness: {1} - Worst fitness: {2}", nnp.BestFitness, Mathf.Round(nnp.AverageFitness * 100f) / 100f, nnp.WorstFitness)); if (GameManager.Instance.DebugRun) { Debug.Break(); } }