public static IMctsableGameState calculateGameStateFromNode(MctsNode node) { List <IGameTreeNode> pathInTheGameTree = new List <IGameTreeNode>(); IGameTreeNode currentNode = node; pathInTheGameTree.Add(node); while (currentNode.previousNode != null) { pathInTheGameTree.Insert(0, currentNode.previousNode); currentNode = currentNode.previousNode; } MctsRootNode rootNode = currentNode as MctsRootNode; if (rootNode == null) { throw new InvalidOperationException("CLASS: MctsNode, METHOD: calculateGameStateFromNode - no root node available in game tree!"); } IMctsableGameState gameState = rootNode.initialGameState.duplicate(); pathInTheGameTree.RemoveAt(0); foreach (MctsNode pathNode in pathInTheGameTree) { gameState.makeMove(pathNode.move); } return(gameState); }
public static MctsNode finalChildSelection(MctsRootNode node) { MctsNode selectedChild = finalChildSelectionService(node) as MctsNode; if (selectedChild == null) { throw new InvalidOperationException("CLASS: MctsRootNode, METHOD: finalChildSelection - final child selection service returns no mcts node!"); } return(selectedChild); }
/// <summary> /// Calculates the best move depending on the given game state and the given constraints. /// </summary> /// <param name="initalGameState">A game state.</param> /// <param name="time">A time in milliseconds until a move is finally selected.</param> /// <param name="childSelectionService"> A child selection service which is used during the mcts algorithm.</param> /// <param name="finalChildSelectionService"> A child selection service to finally select a child.</param> /// <exception cref="ArgumentNullException">Is thrown, if at least one of the given parameters is null.</exception> /// <exception cref="ArgumentException">Is thrown, if the given game state is a terminal game state.</exception> /// <exception cref="ArgumentException">Is thrown, if the given number of milliseconds is lower or equal than zero.</exception> public static IMove calculateOptimalMoveInGivenTime(IMctsableGameState initalGameState, int time, IChildSelectionService childSelectionService, IFinalChildSelectionService finalChildSelectionService) { if (initalGameState == null || childSelectionService == null || finalChildSelectionService == null) { throw new ArgumentNullException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveInGivenTime - at least one of the given parameters is null!"); } if (initalGameState.isGameOver()) { throw new ArgumentException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveInGivenTime - the given game state is a terminal game state!"); } if (time <= 0) { throw new ArgumentException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveInGivenTime - the number of milliseconds is negative or zero!"); } MctsNode.childSelectionService = childSelectionService.childSelection; MctsRootNode.finalChildSelectionService = finalChildSelectionService.finalChildSelection; MctsRootNode root = new MctsRootNode(initalGameState); BackpropagationContainer result; root.expandNode(); CancellationTokenSource tokenSource = new CancellationTokenSource(); iterations = 0; Task workingTask = Task.Factory.StartNew(() => { while (!tokenSource.Token.IsCancellationRequested) { result = mctsSearch(initalGameState.duplicate(), root); iterations++; root.addResult(result.gameResult); root.addResultToAMAFChilds(result); } }, tokenSource.Token); tokenSource.CancelAfter(time); workingTask.Wait(); tokenSource.Dispose(); return(MctsRootNode.finalChildSelection(root).move); }
/// <summary> /// Calculates the best move depending on the given game state and the given constraints. /// </summary> /// <param name="initalGameState">A game state.</param> /// <param name="iterations">A number of iterations until a move is finally selected.</param> /// <param name="childSelectionService"> A child selection service which is used during the mcts algorithm.</param> /// <param name="finalChildSelectionService"> A child selection service to finally select a child.</param> /// <exception cref="ArgumentNullException">Is thrown, if at least one of the given parameters is null.</exception> /// <exception cref="ArgumentException">Is thrown, if the given game state is a terminal game state.</exception> /// <exception cref="ArgumentException">Is thrown, if the number given iterations is lower or equal than zero.</exception> public static IMove calculateOptimalMoveWithGivenIterations(IMctsableGameState initalGameState, int iterations, IChildSelectionService childSelectionService, IFinalChildSelectionService finalChildSelectionService) { if (initalGameState == null || childSelectionService == null || finalChildSelectionService == null) { throw new ArgumentNullException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveWithGivenIterations - at least one of the given parameters is null!"); } if (initalGameState.isGameOver()) { throw new ArgumentException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveWithGivenIterations - the given game state is a terminal game state!"); } if (iterations <= 0) { throw new ArgumentException("CLASS: MctsAlgorithm, METHOD: calculateOptimalMoveWithGivenIterations - the number of iterations is negative or zero!"); } MctsNode.childSelectionService = childSelectionService.childSelection; MctsRootNode.finalChildSelectionService = finalChildSelectionService.finalChildSelection; MctsRootNode root = new MctsRootNode(initalGameState); BackpropagationContainer result; root.expandNode(); for (int i = 1; i <= iterations; i++) { result = mctsSearch(initalGameState.duplicate(), root); root.addResult(result.gameResult); root.addResultToAMAFChilds(result); } MctsAlgorithm.iterations = iterations; return(MctsRootNode.finalChildSelection(root).move); }