/// <summary> /// Creates a new generation by using GenerateBoxes and GenerateBoats. /// Previous generations will be removed and the best parents will be selected and used to create the new generation. /// The best parents (top 1) / all the parents of the generation will be stored as a Prefab in the [savePrefabsAt] folder. Their name /// will use the [generationCount] as an identifier. /// </summary> public void MakeNewGeneration() { GenerateBoxes(); //Fetch parents _activeBoats.RemoveAll(item => item == null); _activeBoats.Sort(); //Winner: BoatLogic lastBoatWinner = _activeBoats[0]; Debug.Log("Last winner boat had: " + lastBoatWinner.GetPoints() + " points!"); scoreWriter.WriteLine(roundCount + " " + lastBoatWinner.GetPoints()); //we save the generation sorted by how well each boat performed or we save just the best boat if (saveCompleteGenerations) { string guid = AssetDatabase.CreateFolder(savePrefabsAt, "Complete Gen-" + roundCount); string newFolderPath = AssetDatabase.GUIDToAssetPath(guid); for (int i = 0; i < _activeBoats.Count; i++) { _activeBoats[i].name = "(" + (i + 1) + ")" + _activeBoats[i].name + "Gen-" + roundCount; PrefabUtility.SaveAsPrefabAsset(_activeBoats[i].gameObject, newFolderPath + "/" + _activeBoats[i].name + ".prefab"); } } else { lastBoatWinner.name += "Gen-" + roundCount; lastBoatWinnerData = lastBoatWinner.GetData(); PrefabUtility.SaveAsPrefabAsset(lastBoatWinner.gameObject, savePrefabsAt + "/" + lastBoatWinner.name + ".prefab"); } if (_activeBoats.Count == 0) { GenerateBoats(); return; } _boatParents = new BoatLogic[boatParentSize]; if (!stochastic) { for (int i = 0; i < boatParentSize; i++) { _boatParents[i] = _activeBoats[i]; } } else { stochasticSearch(); } GenerateBoats(_boatParents); }
/// <summary> /// Creates a new generation by using GenerateBoxes and GenerateBoats/Pirates. /// Previous generations will be removed and the best parents will be selected and used to create the new generation. /// The best parents (top 1) of the generation will be stored as a Prefab in the [savePrefabsAt] folder. Their name /// will use the [generationCount] as an identifier. /// </summary> public void MakeNewGeneration() { GenerateBoxes(); //Fetch parents _activeBoats.RemoveAll(item => item == null); _activeBoats.Sort(); Vector3 shipData = GetShipData(); if (_activeBoats.Count == 0) { GenerateBoats(_boatParents); } _boatParents = new BoatLogic[boatParentSize]; for (int i = 0; i < boatParentSize; i++) { _boatParents[i] = _activeBoats[i]; } BoatLogic lastBoatWinner = _activeBoats[0]; lastBoatWinner.name += "Gen-" + generationCount; lastBoatWinnerData = lastBoatWinner.GetData(); PrefabUtility.SaveAsPrefabAsset(lastBoatWinner.gameObject, savePrefabsAt + lastBoatWinner.name + ".prefab"); _activePirates.RemoveAll(item => item == null); _activePirates.Sort(); Vector3 pirateData = GetPirateData(); _pirateParents = new PirateLogic[pirateParentSize]; for (int i = 0; i < pirateParentSize; i++) { _pirateParents[i] = _activePirates[i]; } PirateLogic lastPirateWinner = _activePirates[0]; lastPirateWinner.name += "Gen-" + generationCount; lastPirateWinnerData = lastPirateWinner.GetData(); PrefabUtility.SaveAsPrefabAsset(lastPirateWinner.gameObject, savePrefabsAt + lastPirateWinner.name + ".prefab"); _dataCollector.AddData(shipData, pirateData); //Winners: Debug.Log("Last winner boat had: " + lastBoatWinner.GetPoints() + " points!" + " Last winner pirate had: " + lastPirateWinner.GetPoints() + " points!"); GenerateObjects(_boatParents, _pirateParents); }
//Similarly generate abled boats private void GenerateAbledBoats(BoatLogic[] abledBoatParents) { _activeAbledBoats = new List <BoatLogic>(); List <GameObject> objects = abledBoatGenerator.RegenerateObjects(); foreach (GameObject obj in objects) { BoatLogic boat = obj.GetComponent <BoatLogic>(); if (boat != null) { _activeAbledBoats.Add(boat); if (abledBoatParents != null) { BoatLogic boatParent = abledBoatParents[Random.Range(0, abledBoatParents.Length)]; boat.Birth(boatParent.GetData()); } boat.Mutate(mutationFactor, mutationChance); boat.AwakeUp(); } } }
private void GenerateBoatsArithmeticCrossover(BoatLogic[] boatParents) { _activeBoats = new List <BoatLogic>(); List <GameObject> objects = boatGenerator.RegenerateObjects(); foreach (GameObject obj in objects) { BoatLogic boat = obj.GetComponent <BoatLogic>(); if (boat != null) { _activeBoats.Add(boat); if (boatParents != null) { BoatLogic firstBoatParent = boatParents[Random.Range(0, boatParents.Length)]; BoatLogic secondBoatParent = boatParents[Random.Range(0, boatParents.Length)]; boat.BirthArithmeticCrossover(firstBoatParent.GetData(), secondBoatParent.GetData()); } boat.Mutate(mutationFactor, mutationChance); boat.AwakeUp(); } } }
/// <summary> /// Generates the list of boats using the parents list. The parent list can be null and, if so, it will be ignored. /// Newly created boats will go under mutation (MutationChances and MutationFactor will be applied). /// /// Newly create agents will be Awaken (calling AwakeUp()). /// </summary> /// <param name="boatParents"></param> public void GenerateBoats(BoatLogic[] boatParents = null) { _activeBoats = new List <BoatLogic>(); List <GameObject> objects = boatGenerator.RegenerateObjects(); if (boatParents != null && crossover && (boatParents.Length % 2 != 0 || objects.Count % 2 != 0)) { crossover = false; Debug.Log("Crossover has been automaticaly disabled. It requires an even number of parents and an even number of children to generate."); } BoatLogic prevBoat = null; //used for crossover foreach (GameObject obj in objects) { BoatLogic boat = obj.GetComponent <BoatLogic>(); if (boat != null) { _activeBoats.Add(boat); if (boatParents != null) { if (!crossover) { BoatLogic boatParent = boatParents[Random.Range(0, boatParents.Length)]; boat.Birth(boatParent.GetData()); boat.Mutate(mutationFactor, mutationChance); boat.AwakeUp(); } else //wait to have two children then perform crossover { if (prevBoat == null) { prevBoat = boat; } else { BoatLogic boatParent = boatParents[Random.Range(0, boatParents.Length)]; BoatLogic otherBoatParent = boatParents[Random.Range(0, boatParents.Length)]; // a parent can happen to match himself, then the offspring will be just two copies of himself // this helps limiting how much the parents can mix boat.NPointCrossoverBirth(boatParent.GetData(), otherBoatParent.GetData(), prevBoat, groupedGenes); boat.Mutate(mutationFactor, mutationChance); boat.AwakeUp(); prevBoat.Mutate(mutationFactor, mutationChance); prevBoat.AwakeUp(); prevBoat = null; } } } else { boat.Mutate(mutationFactor, mutationChance); boat.AwakeUp(); } } } }
/// <summary> /// Creates a new generation by using GenerateBoxes and GenerateBoats/Pirates. /// Previous generations will be removed and the best parents will be selected and used to create the new generation. /// The best parents (top 1) of the generation will be stored as a Prefab in the [savePrefabsAt] folder. Their name /// will use the [generationCount] as an identifier. /// </summary> public void MakeNewGeneration() { GenerateBoxes(); //Fetch parents _activeBoats.RemoveAll(item => item == null); _activeBoats.Sort(); if (_activeBoats.Count == 0) { GenerateBoats(_boatParents); } _boatParents = new BoatLogic[boatParentSize]; for (int i = 0; i < boatParentSize; i++) { _boatParents[i] = _activeBoats[i]; } BoatLogic lastBoatWinner = _activeBoats[0]; lastBoatWinner.name += "Gen-" + generationCount; lastBoatWinnerData = lastBoatWinner.GetData(); PrefabUtility.SaveAsPrefabAsset(lastBoatWinner.gameObject, savePrefabsAt + lastBoatWinner.name + ".prefab"); boatRoundScores = 0; foreach (BoatLogic boat in _activeBoats) { boatRoundScores += boat.GetPoints(); } boatTotalScores += boatRoundScores; _activePirates.RemoveAll(item => item == null); _activePirates.Sort(); _pirateParents = new PirateLogic[pirateParentSize]; for (int i = 0; i < pirateParentSize; i++) { _pirateParents[i] = _activePirates[i]; } PirateLogic lastPirateWinner = _activePirates[0]; pirateRoundScores = 0; foreach (PirateLogic pirate in _activePirates) { pirateRoundScores += pirate.GetPoints(); } pirateTotalScores += pirateRoundScores; lastPirateWinner.name += "Gen-" + generationCount; lastPirateWinnerData = lastPirateWinner.GetData(); PrefabUtility.SaveAsPrefabAsset(lastPirateWinner.gameObject, savePrefabsAt + lastPirateWinner.name + ".prefab"); //Winners: //Storing results string path = "Assets/Overallresults.txt"; //Write some text to the test.txt file StreamWriter writer = new StreamWriter(path, true); writer.WriteLine("Generations count" + generationCount + "||Total boats:" + boatTotalScores + "||TotalPiratesScores:" + pirateTotalScores); writer.Close(); path = "Assets/BoatsTotalScores.txt"; writer = new StreamWriter(path, true); writer.WriteLine(boatTotalScores); writer.Close(); path = "Assets/PiratesTotalScores.txt"; writer = new StreamWriter(path, true); writer.WriteLine(pirateTotalScores); writer.Close(); path = "Assets/BoatsRoundScores.txt"; writer = new StreamWriter(path, true); writer.WriteLine(boatRoundScores); writer.Close(); path = "Assets/PiratesRoundScores.txt"; writer = new StreamWriter(path, true); writer.WriteLine(pirateRoundScores); writer.Close(); Debug.Log("Last winner boat had: " + lastBoatWinner.GetPoints() + " points!" + " Last winner pirate had: " + lastPirateWinner.GetPoints() + " points!"); Debug.Log("Total boats:" + boatTotalScores + "||Round boats:" + boatRoundScores + "||TotalPiratesScores:" + pirateTotalScores + "||PiratesRoundScores" + pirateRoundScores); GenerateObjects(_boatParents, _pirateParents); }