/// <summary> /// DeepCopy Constructor /// </summary> /// <param name="agent">NN to DeepCopy</param> public NNAgent(NNAgent agent) { // DeepCopy of Layers of this NN layers = new int[agent.layers.Length]; for (int i = 0; i < agent.layers.Length; i++) { layers[i] = agent.layers[i]; } bias = agent.bias; // Generate Matrix InitNeurons(); InitWeights(); // Set Weights CopyWeights(agent.weights); }
public static NNAgent Mutate(NNAgent agent, float probability, float amount) { NNAgent mutate = new NNAgent(agent); for (int i = 1; i < mutate.layers.Length; i++) { for (int j = 0; j < mutate.layers[i]; j++) { for (int k = 0; k < mutate.layers[i - 1]; k++) { if (UnityEngine.Random.Range(0, 1) < probability) { mutate.weights[i - 1][j][k] = UnityEngine.Random.Range(0f, 1f) * (amount * 2.0f) - amount; } } } } return mutate; }
public static NNAgent Crossover(NNAgent agentL, NNAgent agentR, float uniformRate) { NNAgent agent = new NNAgent(agentL); for (int i = 1; i < agent.layers.Length; i++) { for (int j = 0; j < agent.layers[i]; j++) { for (int k = 0; k < agent.neurons[i - 1].Length; k++) { if (UnityEngine.Random.Range(0, 1) > uniformRate) { agent.weights[i - 1][j][k] = agentR.weights[i - 1][j][k]; } } } } return agent; }
private void GenerateAgents() { _generation++; if (_generation == 0) { agents = new NNAgent[spawned.Length]; for (int i = 0; i < agents.Length; i++) { agents[i] = new NNAgent(layers, bias); } } else { AddFitnessToChart(); NNAgent[] elitAgents = spawned.OrderByDescending(car => car.GetComponent <CarControlSystem>().fitness).Take(elitism).Select(car => car.agent).ToArray(); int newIndex = 0; for (int i = 0; i < elitism; newIndex++, i++) { agents[newIndex] = new NNAgent(elitAgents[i]); } for (int i = 0; i < mutation; newIndex++, i++) { agents[newIndex] = new NNAgent(elitAgents[i % 5]); agents[newIndex].Mutator(mutationNeuronProb, mutationWeightProb); } for (int i = 0; i < crossover; newIndex++, i++) { agents[newIndex] = NNAgent.Crossover(elitAgents[0], elitAgents[(i + 1) % 2], uniformRate); } for (int i = 0; i < random; newIndex++, i++) { agents[newIndex] = new NNAgent(layers, bias); } } }
private static void testWeights(Dictionary <string, CardClass> classMap, Dictionary <string, List <Card> > deckMap, List <string> deckList, List <double> weights) { Console.WriteLine("Simulate Games"); Random r = new Random(); double wins = 0.0; double losses = 0.0; double numGames = 3000; for (int i = 0; i < numGames; i++) { string p1Deck = deckList[r.Next(deckList.Count)]; string p2Deck = deckList[r.Next(deckList.Count)]; var gameConfig = new GameConfig() { StartPlayer = r.Next(2) + 1, Player1HeroClass = classMap.GetValueOrDefault(p1Deck, CardClass.MAGE), Player2HeroClass = classMap.GetValueOrDefault(p2Deck, CardClass.ROGUE), Player1Deck = deckMap.GetValueOrDefault(p1Deck, Decks.RenoKazakusMage), Player2Deck = deckMap.GetValueOrDefault(p2Deck, Decks.MiraclePirateRogue), FillDecks = true, Shuffle = true, Logging = false }; AbstractAgent player1 = new GreedyAgent(); AbstractAgent player2 = new NNAgent(weights); Console.WriteLine("Game " + i + " " + p1Deck + " " + p2Deck); var gameHandler = new POGameHandler(gameConfig, player1, player2, repeatDraws: false); gameHandler.PlayGames(nr_of_games: 1, addResultToGameStats: true, debug: false); GameStats gameStats = gameHandler.getGameStats(); wins += gameStats.PlayerB_Wins; losses += gameStats.PlayerA_Wins; } Console.WriteLine("Bot winrate: " + (wins / (wins + losses))); Console.WriteLine("Wins: " + wins); Console.WriteLine("Losses: " + losses); Console.WriteLine("Draws: " + (numGames - (wins + losses))); }
private static void runSimulation(Dictionary <string, CardClass> classMap, Dictionary <string, List <Card> > deckMap, List <string> deckList) { int numGames = 3000; Random r = new Random(); Console.WriteLine("Simulate Games"); List <List <double> > games = new List <List <double> >(); for (int i = 0; i < numGames; i++) { double max = 10; double min = -10; List <double> randWeights = Enumerable.Range(0, 24) // create sequence of 100 elements .Select(_ => r.NextDouble() * (max - min) + min) // for each element select random value .ToList(); // convert to array. string p1Deck = deckList[r.Next(deckList.Count)]; string p2Deck = deckList[r.Next(deckList.Count)]; var gameConfig = new GameConfig() { StartPlayer = r.Next(2) + 1, Player1HeroClass = classMap.GetValueOrDefault(p1Deck, CardClass.MAGE), Player2HeroClass = classMap.GetValueOrDefault(p2Deck, CardClass.ROGUE), Player1Deck = deckMap.GetValueOrDefault(p1Deck, Decks.RenoKazakusMage), Player2Deck = deckMap.GetValueOrDefault(p2Deck, Decks.MiraclePirateRogue), FillDecks = true, Shuffle = true, Logging = false }; AbstractAgent player1 = new RandomAgent(); AbstractAgent player2 = new NNAgent(randWeights); Console.WriteLine("Game " + i + " " + p1Deck + " " + p2Deck); var gameHandler = new POGameHandler(gameConfig, player1, player2, repeatDraws: false); gameHandler.PlayGames(nr_of_games: 1, addResultToGameStats: true, debug: false); GameStats gameStats = gameHandler.getGameStats(); // gameStats.printResults(); randWeights.Add(gameStats.PlayerB_Wins); games.Add(randWeights); // Console.WriteLine(String.Join(",", randWeights.Select(p=>p.ToString()).ToArray())); } StringBuilder sb = new StringBuilder(); if (!File.Exists(@"hsdata.csv")) { sb.Append("HERO_HEALTH_REDUCED,HERO_ATTACK_REDUCED,WEAPON_DURABILITY_REDUCED,MINION_HEALTH_REDUCED,MINION_ATTACK_REDUCED,MINION_KILLED,MINION_APPEARED,SECRET_REMOVED,MANA_REDUCED,M_HEALTH,M_ATTACK,M_HAS_CHARGE,M_HAS_DEAHTRATTLE,M_HAS_DIVINE_SHIELD,M_HAS_LIFE_STEAL,M_HAS_STEALTH,M_HAS_TAUNT,M_HAS_WINDFURY,M_IS_RUSH,M_MANA_COST,M_POISONOUS,M_SILENCED,M_SUMMONED,M_CANT_BE_TARGETED_BY_SPELLS,RESULT\r\n"); } for (int i = 0; i < games.Count(); i++) { for (int j = 0; j < games[0].Count(); j++) { sb.Append((j == 0 ? "" : ",") + games[i][j]); } sb.AppendLine(); } File.AppendAllText(@"hsdata.csv", sb.ToString()); Console.WriteLine("Simulation successful"); Console.ReadLine(); }