/// <summary> /// Tests the newly generated population in Metastone. /// </summary> private void TestNewPopulation(List <HSGAIndividual> currentPop, int currentGenerationNum) { for (int i = 0; i < _MaxPopulation; i++) { // get back all the cards we removed from the lists during // previous mutations/validations JSONHandler.RemoveAllCards(); JSONHandler.GetAllCards(numOfFiles, initialDirectory); // Reassemble the deck string for the current individual. currentPop[i].deck = JSONHandler.GenerateDeckString(currentPop[i], comboBox1.Text); GeneFunctions gene = new GeneFunctions(); // check if deck is legal bool isLegal = JSONHandler.ValidateDeck(currentPop[i].cardList); //if deck isnt legal, no need to test it in metastone if (isLegal == true) { // test each individual against each hero class type. for (int opponentNum = 0; opponentNum < 9; opponentNum++) { // send over individual and opponent class numbers GenerateMetastoneValues(comboBox1.SelectedIndex, opponentNum); // run gradlew run command in cmd in metastone directory GenerateAndValidatePopulation(currentPop[i].deck); // retreive the sim stats from text file. Dictionary <string, float> currentStats = new Dictionary <string, float>(); currentStats = ParseMetastoneResults(); // accumulate current win rate per game. gene.CalculatePerGameStats(currentStats, opponentNum); } } // calc fitness - fitness function // calc legality gene.CalculateFitness(isLegal); currentPop[i].winRateFitness = gene.winRateFitness; currentPop[i].legalFitness = gene.legalityFitness; currentPop[i].standardDeviationFitness = gene.standardDeviationFitness; // send individual stats to its correspondent folder. using (StreamWriter w = File.CreateText(generationDirectory + "\\Generation" + currentGenerationNum + "\\Individual" + i + ".txt")) { w.WriteLine("Total Wins: " + currentPop[i].winRateFitness); w.WriteLine("Legality: " + currentPop[i].legalFitness); w.WriteLine("Standard Deviation: " + currentPop[i].standardDeviationFitness); w.WriteLine(); w.WriteLine("Decklist:"); for (int j = 0; j < currentPop[i].cardList.Count; j++) { string s = currentPop[i].cardList[j]._CardID; w.WriteLine(s); } } } }
/// <summary> /// Produces offspring decks from the current population. /// </summary> private List <HSGAIndividual> ProduceNextGeneration(List <HSGAIndividual> localCurrentPop) { List <string> cards = new List <string>(); List <HSGAIndividual> localNewPop = new List <HSGAIndividual>(); while (localNewPop.Count != 10) { GeneFunctions gene = new GeneFunctions(); List <HSGAIndividual> parents = new List <HSGAIndividual>(); List <HSGAIndividual> children = new List <HSGAIndividual>(); // select parents parents.Add(gene.SelectIndividual(localCurrentPop, logger)); parents.Add(gene.SelectIndividual(localCurrentPop, logger)); //crossover children = gene.Crossover(parents, crossoverProbability, logger); //mutation children[0].cardList = MutateIndividual(children[0].cardList); // sort the newly edited list List <Card> test = new List <Card>(); test.AddRange(children[0].cardList.OrderBy(Card => Card._CardID.Split('_')[1].ToCharArray()[0]) .ThenBy(Card => Card._CardID.Split('_').Count() >= 3 ? Card._CardID.Split('_')[2].ToCharArray()[0] : Card._CardID.Split('_')[1].ToCharArray()[0]).ToList()); children[0].cardList.Clear(); children[0].cardList.AddRange(test); cards.Clear(); for (int i = 0; i < children[0].cardList.Count; i++) { cards.Add(children[0].cardList[i]._CardID); } children[1].cardList = MutateIndividual(children[1].cardList); cards.Clear(); for (int i = 0; i < children[1].cardList.Count; i++) { cards.Add(children[1].cardList[i]._CardID); } // add children to new population localNewPop.Add(children[0]); localNewPop.Add(children[1]); } return(localNewPop); }
/// <summary> /// Generates a single, validated and randomised deck. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GenDeckButton_Click(object sender, EventArgs e) { GeneFunctions g = new GeneFunctions(); List <HSGAIndividual> l = new List <HSGAIndividual>(); l.Add(new HSGAIndividual()); l.Add(new HSGAIndividual()); l.Add(new HSGAIndividual()); l.Add(new HSGAIndividual()); l[0].winRateFitness = 25f; l[0].standardDeviationFitness = 1.2f; l[0].legalFitness = -1f; l[1].winRateFitness = 43f; l[1].standardDeviationFitness = 1.1f; l[1].legalFitness = -1f; l[2].winRateFitness = 50f; l[2].standardDeviationFitness = 2.0f; l[2].legalFitness = -1f; l[3].winRateFitness = 5f; l[3].standardDeviationFitness = 0.11f; l[3].legalFitness = -1f; g.SelectIndividual(l, logger); }
private List <HSGAIndividual> ProduceInitialPopulation(int initialGenNum) { selectedClass = comboBox1.GetItemText(comboBox1.SelectedItem); JSONHandler.filePath = deckDirectory; List <HSGAIndividual> currentPop = new List <HSGAIndividual>(); // assemble the initial population // test each individual in the population for (int i = 0; i < _MaxPopulation; i++) { JSONHandler.RemoveAllCards(); JSONHandler.GetAllCards(numOfFiles, initialDirectory); HSGAIndividual GeneIndividual = new HSGAIndividual(); // Create the deck for the current individual. Tuple <string, List <Card> > t = new Tuple <string, List <Card> >("", null); t = JSONHandler.GenerateSpecificDeck(selectedClass); GeneIndividual.deck = t.Item1; // cList = JSONHandler.GetFinalDeckList(); GeneIndividual.cardList = t.Item2; GeneFunctions gene = new GeneFunctions(); // check if deck is legal - dont really need to do it here // because initial population will be legal regardless bool isLegal = JSONHandler.ValidateDeck(GeneIndividual.cardList); //if deck isnt legal, no need to test it in metastone if (isLegal == true) { // test each individual against each hero class type. for (int opponentNum = 0; opponentNum < 9; opponentNum++) { // send over individual and opponent class numbers GenerateMetastoneValues(comboBox1.SelectedIndex, opponentNum); // run gradlew run command in cmd in metastone directory GenerateAndValidatePopulation(GeneIndividual.deck); // retreive the sim stats from text file. Dictionary <string, float> currentStats = new Dictionary <string, float>(); currentStats = ParseMetastoneResults(); // accumulate current win rate per game. gene.CalculatePerGameStats(currentStats, opponentNum); } } // calc fitness - fitness function // calc legality gene.CalculateFitness(isLegal); GeneIndividual.winRateFitness = gene.winRateFitness; GeneIndividual.legalFitness = gene.legalityFitness; GeneIndividual.standardDeviationFitness = gene.standardDeviationFitness; // Add the individual to the population currentPop.Add(GeneIndividual); // send individual stats to its correspondent folder. using (StreamWriter w = File.CreateText(generationDirectory + "\\Generation" + initialGenNum + "\\Individual" + i + ".txt")) { w.WriteLine("Total Wins: " + GeneIndividual.winRateFitness); w.WriteLine("Legality: " + GeneIndividual.legalFitness); w.WriteLine("Standard Deviation: " + GeneIndividual.standardDeviationFitness); w.WriteLine(); w.WriteLine("Decklist:"); for (int j = 0; j < GeneIndividual.cardList.Count; j++) { string s = GeneIndividual.cardList[j]._CardID; w.WriteLine(s); } } } return(currentPop); }