public bool Equals(AngryBirdsGen otherGen) { // if (ReferenceEquals(null, otherGen)) return false; // if (ReferenceEquals(this, otherGen)) return true; // the amount of birds must be the same if(level.birdsAmount != otherGen.level.birdsAmount) return false; // the amount of stacks must be the same if(level.GetTotalObjectsAmount() != otherGen.level.GetTotalObjectsAmount()) return false; for(int i = 0; i < level.GetStacksAmount() && i < otherGen.level.GetStacksAmount(); i++) { // the height of each stack must be the same if(level.GetStack(i).Count != otherGen.level.GetStack(i).Count) return false; if(level.GetStack(i).Count > 0) { LinkedListNode<ShiftABGameObject> obj1 = level.GetStack(i).First; LinkedListNode<ShiftABGameObject> obj2 = otherGen.level.GetStack(i).First; for(; obj1 != level.GetStack(i).Last.Next && obj2 != otherGen.level.GetStack(i).Last.Next; obj1 = obj1.Next, obj2 = obj2.Next) { if(!obj1.Value.Equals(obj2.Value)) return false; } } } return true; }
private void SaveLog() { float fitness = Mathf.Infinity; AngryBirdsGen genome = new AngryBirdsGen(); _geneticAlgorithm.GetBest(out genome, out fitness); float experimentTime = Time.realtimeSinceStartup - _lastExperimentTime; _logContent += "====== RESULTS ======\n"; _logContent += "Execution time: " + experimentTime + "\n"; _logContent += "Convergence: " + _generationIdx + "\n"; _logContent += "Cache size:" + _fitnessCache.Count + "\n"; _logContent += "Fitness calculations: " + _fitnessEvaluation + "\n"; _logContent += "Fitness recovered: " + _fitnessRecovered + "\n"; _logContent += "Best Fitness: " + fitness + "\n"; _logContent += "Linearity: " + genome.level.GetLevelLinearity() + "\n"; _logContent += "Density: " + genome.level.GetLevelDensity() + "\n"; _logContent += "Frequency pig: " + genome.level.GetABGameObjectFrequency(GameWorld.Instance.Templates.Length) + "\n";; _logContent += "Frequency bird: " + genome.level.GetBirdsFrequency() + "\n"; _logContent += "Fitness Evolution: " + _genLog + "\n"; _logContent += "Cache Size Evolution: " + _cacheLog + "\n"; _logContent += "Cache Usage Evolution: " + _recoverLog + "\n"; _genLog = ""; _cacheLog = ""; _recoverLog = ""; _lastExperimentTime = Time.realtimeSinceStartup; }
private void SaveGenerationLog() { float fitness = Mathf.Infinity; AngryBirdsGen genome = new AngryBirdsGen(); _geneticAlgorithm.GetBest(out genome, out fitness); _genLog += fitness + " "; _cacheLog += _fitnessCache.Count + " "; _recoverLog += _fitnessRecovered + " "; //Debug.Log("Step : " + step++ + " Best Fitness: " + fitness); //Debug.Log("Cache Size: " + _fitnessCache.Count); //Debug.Log("Cache Usage: " + _fitnessRecovered); }
public void InitAngryBirdsGenome(out AngryBirdsGen genome) { genome = new AngryBirdsGen(); genome.level.birdsAmount = UnityEngine.Random.Range(0, ABLevel.BIRDS_MAX_AMOUNT); genome.level = GenerateRandomLevel(); }
public void Crossover(ref Genome<AngryBirdsGen> genome1, ref Genome<AngryBirdsGen> genome2, out Genome<AngryBirdsGen> child1, out Genome<AngryBirdsGen> child2) { child1 = new Genome<AngryBirdsGen>(); child2 = new Genome<AngryBirdsGen>(); AngryBirdsGen genes1 = new AngryBirdsGen(); AngryBirdsGen genes2 = new AngryBirdsGen(); if(UnityEngine.Random.value <= _geneticAlgorithm.CrossoverRate) { int maxGenomeSize = Mathf.Max (genome1.Genes.level.GetStacksAmount(), genome2.Genes.level.GetStacksAmount()); for(int i = 0; i < maxGenomeSize; i++) { if(genome1.Genes.level.GetStacksAmount() == genome2.Genes.level.GetStacksAmount()) { if(UnityEngine.Random.value < 0.5f) genes1.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes1.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); if(UnityEngine.Random.value < 0.5f) genes2.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes2.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); } else if(genome1.Genes.level.GetStacksAmount() < genome2.Genes.level.GetStacksAmount()) { if(i < genome1.Genes.level.GetStacksAmount()) { if(UnityEngine.Random.value < 0.5f) genes1.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes1.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); if(UnityEngine.Random.value < 0.5f) genes2.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes2.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); } else { if(UnityEngine.Random.value < 0.5f) genes1.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); if(UnityEngine.Random.value < 0.5f) genes2.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); } } else { if(i < genome2.Genes.level.GetStacksAmount()) { if(UnityEngine.Random.value < 0.5f) genes1.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes1.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); if(UnityEngine.Random.value < 0.5f) genes2.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); else genes2.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); } else { if(UnityEngine.Random.value < 0.5f) genes1.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); if(UnityEngine.Random.value < 0.5f) genes2.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); } } } // Integer crossover for birds genes1.level.birdsAmount = (int)(0.5f * genome1.Genes.level.birdsAmount + 0.5f * genome2.Genes.level.birdsAmount); genes2.level.birdsAmount = (int)(1.5f * genome1.Genes.level.birdsAmount - 0.5f * genome2.Genes.level.birdsAmount); } else { for(int i = 0; i < genome1.Genes.level.GetStacksAmount(); i++) { genes1.level.AddStack(CopyStack(genome1.Genes.level.GetStack(i))); } genes1.level.birdsAmount = genome1.Genes.level.birdsAmount; for(int i = 0; i < genome2.Genes.level.GetStacksAmount(); i++) { genes2.level.AddStack(CopyStack(genome2.Genes.level.GetStack(i))); } genes2.level.birdsAmount = genome2.Genes.level.birdsAmount; } genes1.level.FixLevelSize(); genes2.level.FixLevelSize(); child1.Genes = genes1; child2.Genes = genes2; }
private float CheckStopCriteria() { float fitness = Mathf.Infinity; AngryBirdsGen genome = new AngryBirdsGen(); _geneticAlgorithm.GetBest(out genome, out fitness); if(_lastGenerationBestFitness == fitness) _sameBestFitnessCount++; else _sameBestFitnessCount = 0; _lastGenerationBestFitness = (float)fitness; return fitness; }
private void EndEvolution() { AudioSource.PlayClipAtPoint(finishSound, new Vector3(0f, -2.25f, 0f)); CaptureScreenshot(); _experimentsIdx++; // Save the results SaveLog(); if(_experimentsIdx < _experimentsAmount) { // Run next experiment Application.LoadLevel(Application.loadedLevel); } else { float fitness = Mathf.Infinity; AngryBirdsGen genome = new AngryBirdsGen(); _geneticAlgorithm.GetBest(out genome, out fitness); // Save results WriteLogToFile(_logFile, _logContent); // Default time scale Time.timeScale = 1f; // Play level starting audio GameWorld.Instance.GetComponent<AudioSource>().PlayOneShot(GameWorld.Instance._clips[0]); GameWorld.Instance.GetComponent<AudioSource>().PlayOneShot(GameWorld.Instance._clips[1]); // Clear the level and decode the best genome of the last generation GameWorld.Instance.DecodeLevel(genome.level.gameObjects, genome.level.birdsAmount); // Save file in xml for future use LevelLoader.SaveXmlLevel(genome.level); // Disable simulation GameWorld.Instance._isSimulation = false; // Disable AI and allow player to test the level if(GameWorld.Instance._birdAgent != null) Destroy(GameWorld.Instance._birdAgent.gameObject); // Destroy the generator Destroy(this.gameObject); } }
private void CaptureScreenshot() { float fitness = Mathf.Infinity; AngryBirdsGen genome = new AngryBirdsGen(); _geneticAlgorithm.GetBest(out genome, out fitness); GameWorld.Instance.DecodeLevel(genome.level.gameObjects, genome.level.birdsAmount); string info; float aestheticFitness = AestheticFitness(out info); Application.CaptureScreenshot("Level " + screenshotId++ + "Def Fit " + fitness.ToString("F05") + "-Fit " + aestheticFitness.ToString("F05") + "-Pop " + _populationSize.ToString() + "-Gen " + _generationSize.ToString() + info + ".png"); }
public float EvaluateUsingAI(AngryBirdsGen genome, int genomeIdx) { //Debug.Log ("fitness = " + _fitnessCache[genome]); return _fitnessCache[genome]; }