public override ISearchStrategy <object, TicTacToeState, TicTacToeMove, object, TicTacToeMove> SetupMCTS() { var builder = MCTS <object, TicTacToeState, TicTacToeMove, object, TicTacToeMove> .Builder(); builder.Iterations = 10000; builder.PlayoutStrategy = new AgentPlayout <object, TicTacToeState, TicTacToeMove, object, TicTacToeMove>(Agent); builder.EvaluationStrategy = EvaluationStrategy; builder.SolutionStrategy = new ActionSolution <object, TicTacToeState, TicTacToeMove, object, TicTacToeMove, TreeSearchNode <TicTacToeState, TicTacToeMove> >(); return(builder.Build()); }
/// <summary> /// Constructs a new instance of MCTSBot with default strategies. /// </summary> /// <param name="allowPerfectInformation">[Optional] Whether or not this bot is allowed perfect information about the game state (i.e. no obfuscation and therefore no determinisation). Default value is false.</param> /// <param name="ensembleSize">[Optional] The size of the ensemble to use. Default value is 1.</param> /// <param name="playoutBotType">[Optional] The type of playout bot to be used during playouts. Default value is <see cref="PlayoutBotType.MAST"/>.</param> /// <param name="mastSelectionType">[Optional] The type of selection strategy used by the MAST playout. Default value is <see cref="MASTPlayoutBot.SelectionType.EGreedy"/>.</param> /// <param name="retainTaskStatistics">[Optional] Whether or not to retain the PlayerTask statistics between searches. Default value is false.</param> /// <param name="budgetType">[Optional] The type of budget that this bot will use. Default value is <see cref="BudgetType.Iterations"/>.</param> /// <param name="iterations">[Optional] The budget for the amount of iterations MCTS can use. Default value is <see cref="Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET"/>.</param> /// <param name="time">[Optional] The budget for the amount of milliseconds MCTS can spend on searching. Default value is <see cref="Constants.DEFAULT_COMPUTATION_TIME_BUDGET"/>.</param> /// <param name="minimumVisitThresholdForExpansion">[Optional] The minimum amount of times a node has to be visited before it can be expanded. Default value is <see cref="Constants.DEFAULT_MCTS_MINIMUM_VISIT_THRESHOLD_FOR_EXPANSION"/>.</param> /// <param name="minimumVisitThresholdForSelection">[Optional] The minimum number of visits before using the NodeEvaluation to select the best node. Default value is <see cref="Constants.DEFAULT_MCTS_MINIMUM_VISIT_THRESHOLD_FOR_SELECTION"/>.</param> /// <param name="playoutTurnCutoff">[Optional] The amount of turns after which to stop a simulation. Default value is <see cref="Constants.DEFAULT_PLAYOUT_TURN_CUTOFF"/>.</param> /// <param name="ucbConstantC">[Optional] Value for the c-constant in the UCB1 formula. Default value is <see cref="Constants.DEFAULT_UCB1_C"/>.</param> /// <param name="dimensionalOrdering">[Optional] The ordering for dimensions when using Hierarchical Expansion. Default value is <see cref="DimensionalOrderingType.None"/>.</param> /// <param name="useHeuristicEvaluation">[Optional] Whether or not to use the HeuristicBot's evaluation function. Default value is false.</param> /// <param name="debugInfoToConsole">[Optional] Whether or not to write debug information to the console. Default value is false.</param> public HMCTSBot(bool allowPerfectInformation = false, int ensembleSize = 1, PlayoutBotType playoutBotType = PlayoutBotType.MAST, MASTPlayoutBot.SelectionType mastSelectionType = MASTPlayoutBot.SelectionType.EGreedy, bool retainTaskStatistics = false, BudgetType budgetType = BudgetType.Iterations, int iterations = Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET, long time = Constants.DEFAULT_COMPUTATION_TIME_BUDGET, int minimumVisitThresholdForExpansion = Constants.DEFAULT_MCTS_MINIMUM_VISIT_THRESHOLD_FOR_EXPANSION, int minimumVisitThresholdForSelection = Constants.DEFAULT_MCTS_MINIMUM_VISIT_THRESHOLD_FOR_SELECTION, int playoutTurnCutoff = Constants.DEFAULT_PLAYOUT_TURN_CUTOFF, double ucbConstantC = Constants.DEFAULT_UCB1_C, DimensionalOrderingType dimensionalOrdering = DimensionalOrderingType.None, bool useHeuristicEvaluation = false, bool debugInfoToConsole = false) { PerfectInformation = allowPerfectInformation; EnsembleSize = ensembleSize; PlayoutBotType = playoutBotType; MASTSelectionType = mastSelectionType; RetainTaskStatistics = retainTaskStatistics; BudgetType = budgetType; Iterations = iterations; Time = time; MinimumVisitThresholdForExpansion = minimumVisitThresholdForExpansion; MinimumVisitThresholdForSelection = minimumVisitThresholdForSelection; PlayoutTurnCutoff = playoutTurnCutoff; UCBConstantC = ucbConstantC; DimensionalOrdering = dimensionalOrdering; _debug = debugInfoToConsole; // Create the ensemble search Ensemble = new EnsembleStrategySabberStone(enableStateObfuscation: true, enablePerfectInformation: PerfectInformation); // Simulation will be handled by the Playout. var sabberStoneStateEvaluation = new EvaluationStrategyHearthStone(useHeuristicEvaluation); Playout = new PlayoutStrategySabberStone(); // Set the playout bots switch (PlayoutBotType) { case PlayoutBotType.Random: MyPlayoutBot = new RandomBot(filterDuplicatePositionTasks: true); OpponentPlayoutBot = new RandomBot(filterDuplicatePositionTasks: true); break; case PlayoutBotType.Heuristic: MyPlayoutBot = new HeuristicBot(); OpponentPlayoutBot = new HeuristicBot(); break; case PlayoutBotType.MAST: MyPlayoutBot = new MASTPlayoutBot(MASTSelectionType, sabberStoneStateEvaluation); OpponentPlayoutBot = new MASTPlayoutBot(MASTSelectionType, sabberStoneStateEvaluation); break; default: throw new InvalidEnumArgumentException($"PlayoutBotType `{PlayoutBotType}' is not supported."); } // We'll be cutting off the simulations after X turns, using a GoalStrategy. Goal = new GoalStrategyTurnCutoff(PlayoutTurnCutoff); // Expansion, Application and Goal will be handled by the GameLogic. GameLogic = new SabberStoneGameLogic(Goal, true, DimensionalOrdering); // Create the INodeEvaluation strategy used in the selection phase. var nodeEvaluation = new ScoreUCB <SabberStoneState, SabberStoneAction>(UCBConstantC); // Build MCTS Builder = MCTS <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction> .Builder(); Builder.ExpansionStrategy = new MinimumTExpansion <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction>(MinimumVisitThresholdForExpansion); Builder.SelectionStrategy = new BestNodeSelection <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction>(MinimumVisitThresholdForSelection, nodeEvaluation); Builder.EvaluationStrategy = sabberStoneStateEvaluation; switch (BudgetType) { case BudgetType.Iterations: Builder.Iterations = EnsembleSize > 0 ? Iterations / EnsembleSize : Iterations; // Note: Integer division by design. break; case BudgetType.Time: Builder.Time = EnsembleSize > 0 ? Time / EnsembleSize : Time; // Note: Integer division by design. break; default: throw new InvalidEnumArgumentException($"BudgetType `{BudgetType}' is not supported."); } Builder.BackPropagationStrategy = new EvaluateOnceAndColourBackPropagation <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction>(); Builder.FinalNodeSelectionStrategy = new BestRatioFinalNodeSelection <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction>(); Builder.SolutionStrategy = new SolutionStrategySabberStone(true, nodeEvaluation); Builder.PlayoutStrategy = Playout; }