private void GetFitness(NeuralNetwork bot, bool visible = false) { bot.fitness = 0; for (int i = 0; i < TEST_CASES; i++) { /* modify depending on what you want to predict, this is all that changes from problem to problem * ------------------------------------------------------------------------------------------------*/ SnakeGame game = new SnakeGame(10); int size = game.boardSize; while (game.gameInProgress) { double[] inputs = new double[16]; int[][] directions = new int[8][]; int idx = 0; for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { if (x != 0 || y != 0) { directions[idx++] = new int[] { x, y } } ; } } for (int j = 0; j < 8; j++) { int[] position = new int[2] { game.snake.headLocation.X, game.snake.headLocation.Y }; double distance = 1; inputs[2 * j + 1] = 0; bool foundSnake = false; while (true) { position[0] += directions[j][0]; position[1] += directions[j][1]; if (position[0] == -1 || position[0] == size || position[1] == -1 || position[1] == size) { if (!foundSnake) { inputs[2 * j] = 1.0 / (distance * distance); } break; } BoardElements current = game.board[position[0], position[1]]; switch (current) { //case BoardElements.Mine: case BoardElements.Snake: if (!foundSnake) { inputs[2 * j] = 1.0 / (distance * distance); foundSnake = true; } break; case BoardElements.Apple: inputs[2 * j + 1] = 1.0; break; } distance++; if (foundSnake) { break; } } } bot.SetInputs(inputs); double[] outputs = bot.Predict(); int index = 0; double max = outputs[0]; for (int k = 0; k < 4; k++) { if (outputs[k] > max) { index = k; max = outputs[k]; } } switch (index) { case 0: game.changeDirection(-1, 0); break; case 1: game.changeDirection(1, 0); break; case 2: game.changeDirection(0, -1); break; case 3: game.changeDirection(0, 1); break; default: break; } if (visible) { Console.CursorVisible = false; game.advance(true); Thread.Sleep(200); } else { game.advance(); } } bot.fitness += (int)game.points; } /* stay inside this for loop * ------------------------------------------------------------------------------------------------*/ } }
static void PlaySnake() { GeneticAlg_Snake simulation = new GeneticAlg_Snake(250, 16, 10, 4); for (int _ = 0; _ < 500; _++) { simulation.AdvanceGeneration(); } NeuralNetwork bot = simulation.bestBot; Console.WriteLine("Play?"); Console.WriteLine("(Y)Yes"); Console.WriteLine("(N)No"); string input = Console.ReadLine(); while (input.ToUpper() == "Y") { SnakeGame game = new SnakeGame(10); int size = game.boardSize; while (game.gameInProgress) { double[] inputs = new double[16]; int[][] directions = new int[8][]; int idx = 0; for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { if (x != 0 || y != 0) { directions[idx++] = new int[] { x, y } } ; } } for (int j = 0; j < 8; j++) { int[] position = new int[2] { game.snake.headLocation.X, game.snake.headLocation.Y }; double distance = 1; inputs[2 * j + 1] = 0; bool foundSnake = false; while (true) { position[0] += directions[j][0]; position[1] += directions[j][1]; if (position[0] == -1 || position[0] == size || position[1] == -1 || position[1] == size) { if (!foundSnake) { inputs[2 * j] = 1.0 / (distance * distance); } break; } BoardElements current = game.board[position[0], position[1]]; switch (current) { case BoardElements.Snake: if (!foundSnake) { inputs[2 * j] = 1.0 / (distance * distance); foundSnake = true; } break; case BoardElements.Apple: inputs[2 * j + 1] = 1.0; break; } distance++; if (foundSnake) { break; } } } bot.SetInputs(inputs); double[] outputs = bot.Predict(); int index = 0; double max = outputs[0]; for (int k = 0; k < 4; k++) { if (outputs[k] > max) { index = k; max = outputs[k]; } } switch (index) { case 0: game.changeDirection(-1, 0); break; case 1: game.changeDirection(1, 0); break; case 2: game.changeDirection(0, -1); break; case 3: game.changeDirection(0, 1); break; default: break; } Console.Clear(); game.advance(true); Thread.Sleep(500); } Console.WriteLine("Play?"); Console.WriteLine("(Y)Yes"); Console.WriteLine("(N)No"); input = Console.ReadLine(); } }