public static void Forza4MCTSEval(Tuple <string, int> p, int min_backups, int max_backups = 100) { bool done = false; int current_backups = min_backups; int prev_backups = 0; /// if the max number of backups is not specified, double the number of backups until it is found if (max_backups == 0) { bool foundUpperLimit = false; current_backups = min_backups; do { Console.WriteLine(">> CURRENT BACKUPS = " + current_backups); TwoPlayersGameStats stats = Forza4Eval(new Tuple <string, int>("MCTS", current_backups), p); if (stats.Quality < cQualityThreshold && stats.Wins(1) < stats.Wins(2)) { current_backups = 2 * current_backups; } else { foundUpperLimit = true; } } while (!foundUpperLimit); max_backups = (int)(current_backups * (1f + cUpperLimitIncrease)); } Console.WriteLine("MAX BACKUPS = " + max_backups); /// binary search for the smallest number of backups to match the target AI int lowerLimit = min_backups; int upperLimit = max_backups; do { current_backups = (min_backups + max_backups) / 2; TwoPlayersGameStats stats = Forza4Eval(new Tuple <string, int>("MCTS", current_backups), p); Console.WriteLine("current backups " + current_backups + "=>" + stats.Quality); if (stats.Quality > cQualityThreshold || lowerLimit >= upperLimit || Math.Abs(upperLimit - lowerLimit) < cMinBackUpDifference) { done = true; } else { if (stats.Wins(1) < stats.Wins(2)) { lowerLimit = current_backups; } else { upperLimit = current_backups; } Console.Write("BACKUPS => [" + prev_backups + " " + current_backups + "]"); } } while (!done && current_backups < max_backups); if (current_backups >= max_backups) { Console.WriteLine("LIMITE TROPPO BASSO"); } else { Console.WriteLine("Complexity = " + current_backups); } }
static TwoPlayersGameStats Forza4Eval(Tuple <string, int> p1, Tuple <string, int> p2, int no_matches = 100) { Forza4GameState state = new Forza4GameState(); TwoPlayersGameStats stats = new TwoPlayersGameStats(); IForza4SimulationStrategy player1; IForza4SimulationStrategy player2; /// set up experiment parameters and labels string label1 = p1.Item1; string label2 = p2.Item1; if (p1.Item2 < 0) { player1 = Forza4Player(p1.Item1); } else { player1 = Forza4Player(p1.Item1, p1.Item2); label1 = label1 + "(" + p1.Item2 + ")"; } if (p2.Item2 < 0) { player2 = Forza4Player(p2.Item1); } else { player2 = Forza4Player(p2.Item1, p2.Item2); label2 = label2 + "(" + p2.Item2 + ")"; } //Console.WriteLine (label1 + " vs " + label2 + "\n"); int move_counter = 0; IGameMove current_move; stats.Reset(); for (int p = 0; p < no_matches; p++) { int start_player = ((p % 2 == 0) ? 1 : 2); state.Restart(start_player); move_counter = 0; //// ERRORE NELLA SELEZIONE DEL GIOCATORE! :) while (!state.EndState()) { // when player1 starts it plays even move (0 -> the first, 2 -> the third, etc.) if (start_player == 1) { if (move_counter % 2 == 0) { current_move = player1.selectMove(state); } else { current_move = player2.selectMove(state); } // when player2 starts it plays even move (0 -> the first, 2 -> the third, etc.) } else { if (move_counter % 2 == 0) { current_move = player2.selectMove(state); } else { current_move = player1.selectMove(state); } } move_counter = move_counter + 1; state.DoMove(current_move); } //Console.WriteLine (p + "\tWINNER\t" + state.Winner() + "\t" + stats.PrettyPrintRates()); if (state.Winner() == 1 || state.Winner() == 2) { stats.PlayerWon(state.Winner(), start_player); } else { stats.PlayersTied(); } } Console.WriteLine(player1.getFriendlyName() + " vs " + player2.getFriendlyName() + "\n"); Console.WriteLine("P1WINS\t" + stats.Wins(1) + "\tP2WINS\t" + +stats.Wins(2) + "\tTIES\t" + stats.Ties() + "\n\n"); Console.WriteLine("\tP1-1ST\tP2-1S\nP1\t" + stats.Wins(1, 1) + "\t" + stats.Wins(1, 2) + "\nP2\t" + stats.Wins(2, 1) + "\t" + stats.Wins(2, 2) + "\n"); return(stats); }
/// <summary> /// Evaluate the complexity of an artificial intelligence algorithm using vanilla MCTS /// </summary> /// <param name="p">P.</param> public static void TicTacToeMCTSEval(Tuple <string, int> p, int min_backups, int max_backups = 100) { bool done = false; int current_backups = min_backups; int prev_backups = 0; /// if the max number of backups is not specified, double the number of backups until it is found if (max_backups == 0) { bool foundUpperLimit = false; current_backups = min_backups; do { TwoPlayersGameStats stats = TicTacToeEval(new Tuple <string, int>("MCTS", current_backups), p); if (stats.Quality < cQualityThreshold && stats.Wins(1) < stats.Wins(2)) { current_backups = 2 * current_backups; } else { foundUpperLimit = true; } } while (!foundUpperLimit); max_backups = (int)(current_backups * (1f + cUpperLimitIncrease)); } Console.WriteLine("==\tMaxBackups\t" + max_backups); /// binary search for the smallest number of backups to match the target AI int lowerLimit = min_backups; int upperLimit = max_backups; do { string str_output = string.Empty; current_backups = (min_backups + max_backups) / 2; str_output = ">>\t" + min_backups + "\t" + max_backups + "\t" + current_backups; TwoPlayersGameStats stats = TicTacToeEval(new Tuple <string, int>("MCTS", current_backups), p); //Console.WriteLine("current backups " + current_backups + "=>" + stats.Quality); str_output = str_output + "\t" + stats.Wins(1, 1); str_output = str_output + "\t" + stats.Wins(1, 2); str_output = str_output + "\t" + stats.Wins(2, 1); str_output = str_output + "\t" + stats.Wins(2, 2); str_output = str_output + "\t" + string.Format("{0:F3}", stats.Quality); Console.WriteLine(str_output); if (stats.Quality > cQualityThreshold || lowerLimit >= upperLimit || Math.Abs(upperLimit - lowerLimit) < cMinBackUpDifference) { done = true; } else { if (stats.Wins(1) < stats.Wins(2)) { lowerLimit = current_backups; } else { upperLimit = current_backups; } } } while (!done && current_backups < max_backups); if (current_backups >= max_backups) { Console.WriteLine("LIMITE TROPPO BASSO"); } else { Console.WriteLine("Complexity = " + current_backups); } }