/// <summary> /// Sets the Controller that the bot represents within a SabberStone Game. /// </summary> /// <param name="controller">This bot's Controller.</param> public void SetController(Controller controller) { Player = controller; RandomPlayoutBot = new RandomBot(controller, filterDuplicatePositionTasks: true); // Also reset the table of statistics ResetMASTData(); }
/// <summary> /// Creates a new instance. /// </summary> /// <param name="playout">The strategy used to play out a game in simulation.</param> /// <param name="evaluation">The evaluation strategy for determining the value of samples.</param> /// <param name="gameLogic">The game specific logic required for searching through SabberStoneStates and SabberStoneActions.</param> public SabberStoneSideInformationStrategy(IPlayoutStrategy <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction> playout, IStateEvaluation <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction, TreeSearchNode <SabberStoneState, SabberStoneAction> > evaluation, IGameLogic <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction, SabberStoneAction> gameLogic) { PlayoutBot = new RandomBot(); Playout = playout; Evaluation = evaluation; GameLogic = gameLogic; }
/// <summary> /// Creates a new instance of the MASTPlayoutBot. /// </summary> /// <param name="selection">The type of selection to use.</param> /// <param name="evaluation">The EvaluationStrategy used for evaluating a SabberStoneState.</param> /// <param name="eGreedyThreshold">[Optional] Threshold for e-greedy selection. Default value is <see cref="Constants.DEFAULT_E_GREEDY_THRESHOLD"/>.</param> /// <param name="ucbConstantC">[Optional] Value for the c-constant in the UCB1 formula. Default value is <see cref="Constants.DEFAULT_UCB1_C"/>.</param> public MASTPlayoutBot(SelectionType selection, EvaluationStrategyHearthStone evaluation, double eGreedyThreshold = Constants.DEFAULT_E_GREEDY_THRESHOLD, double ucbConstantC = Constants.DEFAULT_UCB1_C) { Selection = selection; RandomPlayoutBot = new RandomBot(filterDuplicatePositionTasks: true); Evaluation = evaluation; EGreedyThreshold = eGreedyThreshold; UCBConstantC = ucbConstantC; MASTTable = new Dictionary <int, PlayerTaskStatistics>(); ActionsTaken = new List <SabberStoneAction>(); }
/// <summary> /// Constructs a new instance of LSIBot 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 M.A.S.T. playout. Default value is <see cref="MASTPlayoutBot.SelectionType.EGreedy"/>.</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="budgetType">[Optional] The type of budget that this bot will use. Default value is <see cref="BudgetType.Iterations"/>.</param> /// <param name="samples">[Optional] The budget for the amount of iterations LSI can use. Default value is <see cref="Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET"/>.</param> /// <param name="time">[Optional] The budget for the amount of milliseconds LSI can spend on searching. Default value is <see cref="Constants.DEFAULT_COMPUTATION_TIME_BUDGET"/>.</param> /// <param name="generationBudgetPercentage">[Optional] The percentage of the budget that should be spent during the generation phase. Default value is <see cref="Constants.DEFAULT_LSI_BUDGET_GENERATION_PERCENTAGE"/>.</param> /// <param name="budgetEstimationType">[Optional] The type of strategy used to estimate the budget for LSI. Default value is <see cref="BudgetEstimationType.AverageSampleTime"/>.</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 LSIBot(bool allowPerfectInformation = false, int ensembleSize = 1, PlayoutBotType playoutBotType = PlayoutBotType.MAST, MASTPlayoutBot.SelectionType mastSelectionType = MASTPlayoutBot.SelectionType.EGreedy, int playoutTurnCutoff = Constants.DEFAULT_PLAYOUT_TURN_CUTOFF, BudgetType budgetType = BudgetType.Iterations, int samples = Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET, long time = Constants.DEFAULT_COMPUTATION_TIME_BUDGET, double generationBudgetPercentage = Constants.DEFAULT_LSI_BUDGET_GENERATION_PERCENTAGE, BudgetEstimationType budgetEstimationType = BudgetEstimationType.AverageSampleTime, bool useHeuristicEvaluation = false, bool debugInfoToConsole = false) { PerfectInformation = allowPerfectInformation; EnsembleSize = ensembleSize; PlayoutBotType = playoutBotType; MASTSelectionType = mastSelectionType; PlayoutTurnCutoff = playoutTurnCutoff; BudgetType = budgetType; Samples = samples; Time = time; GenerationBudgetPercentage = generationBudgetPercentage; BudgetEstimation = budgetEstimationType; _debug = debugInfoToConsole; // Create the ensemble search Ensemble = new EnsembleStrategySabberStone(enableStateObfuscation: true, enablePerfectInformation: PerfectInformation); // Adjust sample sizes for use in the Ensemble long budgetAllowance; switch (BudgetType) { case BudgetType.Iterations: Samples = EnsembleSize > 0 ? Samples / EnsembleSize : Samples; // Note: Integer division by design. budgetAllowance = Samples; break; case BudgetType.Time: Time = EnsembleSize > 0 ? Time / EnsembleSize : Time; // Note: Integer division by design. budgetAllowance = Time; break; default: throw new InvalidEnumArgumentException($"BudgetType `{BudgetType}' is not supported."); } // 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."); } // Set the budget estimation strategy. switch (BudgetEstimation) { case BudgetEstimationType.AverageSampleTime: BudgetEstimationStrategy = new AverageSampleTimeBudgetEstimationStrategy(BudgetType, budgetAllowance, GenerationBudgetPercentage, Playout); break; case BudgetEstimationType.PreviousSearchAverage: BudgetEstimationStrategy = new PreviousSearchAverageBudgetEstimationStrategy(BudgetType, budgetAllowance, GenerationBudgetPercentage, Playout); break; default: throw new InvalidEnumArgumentException($"BudgetEstimationType `{budgetEstimationType}' is not supported."); } // LSI will need a goal-strategy to determine when a simulation is done Goal = new GoalStrategyTurnCutoff(PlayoutTurnCutoff); // LSI will need an evaluation-strategy to evaluate the strength of samples Evaluation = new EvaluationStrategyHearthStone(); // Application will be handled by the GameLogic // Hierarchical Expansion is set to TRUE because of incremental task validation during action sampling. GameLogic = new SabberStoneGameLogic(Goal, hierarchicalExpansion: true); // The side information strategy needs access to several of these. SideInformationStrategy = new SabberStoneSideInformationStrategy(Playout, Evaluation, GameLogic); // The sampling strategy used to sample actions during the generation phase. SamplingStrategy = new SabberStoneLSISamplingStrategy(GameLogic); }
/// <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; }
/// <summary> /// Constructs a new instance. /// </summary> /// <param name="naïveBot">The bot to use when creating samples.</param> public SabberStoneNMCSamplingStrategy(RandomBot naïveBot) { NaïveBot = naïveBot; }
/// <summary> /// Constructs a new instance of NMCTSBot 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="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 NMCTS can use. Default value is <see cref="Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET"/>.</param> /// <param name="time">[Optional] The budget for the amount of milliseconds NMCTS can spend on searching. Default value is <see cref="Constants.DEFAULT_COMPUTATION_TIME_BUDGET"/>.</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="globalPolicy">[Optional] The exploration-threshold for the e-greedy global policy. Default value is <see cref="Constants.DEFAULT_NMCTS_GLOBAL_POLICY"/>.</param> /// <param name="localPolicy">[Optional] The exploration-threshold for the e-greedy local policy. Default value is <see cref="Constants.DEFAULT_NMCTS_LOCAL_POLICY"/>.</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 NMCTSBot(bool allowPerfectInformation = false, int ensembleSize = 1, PlayoutBotType playoutBotType = PlayoutBotType.MAST, MASTPlayoutBot.SelectionType mastSelectionType = MASTPlayoutBot.SelectionType.EGreedy, BudgetType budgetType = BudgetType.Iterations, int iterations = Constants.DEFAULT_COMPUTATION_ITERATION_BUDGET, long time = Constants.DEFAULT_COMPUTATION_TIME_BUDGET, int playoutTurnCutoff = Constants.DEFAULT_PLAYOUT_TURN_CUTOFF, double globalPolicy = Constants.DEFAULT_NMCTS_GLOBAL_POLICY, double localPolicy = Constants.DEFAULT_NMCTS_LOCAL_POLICY, bool useHeuristicEvaluation = false, bool debugInfoToConsole = false) { PerfectInformation = allowPerfectInformation; EnsembleSize = ensembleSize; PlayoutBotType = playoutBotType; MASTSelectionType = mastSelectionType; BudgetType = budgetType; Iterations = iterations; Time = time; PlayoutTurnCutoff = playoutTurnCutoff; GlobalPolicy = globalPolicy; LocalPolicy = localPolicy; _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."); } // And the random sampling bot RandomSamplingBot = new RandomBot(filterDuplicatePositionTasks: true); // We'll be cutting off the simulations after X turns, using a GoalStrategy Goal = new GoalStrategyTurnCutoff(PlayoutTurnCutoff); // Application and Goal will be handled by the GameLogic GameLogic = new SabberStoneGameLogic(Goal, false); // Build NMCTS Builder = NMCTS <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction> .Builder(); Builder.ExplorationStrategy = new ChanceExploration <List <SabberStoneAction>, SabberStoneState, SabberStoneAction, object, SabberStoneAction>(LocalPolicy); Builder.PlayoutStrategy = Playout; Builder.PolicyGlobal = GlobalPolicy; Builder.SamplingStrategy = new SabberStoneNMCSamplingStrategy(RandomSamplingBot); Builder.SolutionStrategy = new SolutionStrategySabberStone(false, new AverageScore <SabberStoneState, SabberStoneAction>()); 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."); } }