Ejemplo n.º 1
0
        public void expandNode()
        {
            if (areChildNodesExpanded)
            {
                return;
            }

            areChildNodesExpanded = true;

            IMctsableGameState gameState = MctsNode.calculateGameStateFromNode(this);

            List <IMove> possibleMoves = gameState.getPossibleMoves();

            INonDeterministicMove possibleNonDeterministicMove;

            MctsNode[] childs = new MctsNode[possibleMoves.Count];

            for (int i = 0; i < possibleMoves.Count; i++)
            {
                possibleNonDeterministicMove = possibleMoves[i] as INonDeterministicMove;

                if (possibleNonDeterministicMove == null)
                {
                    childs[i] = new MctsNode(this, possibleMoves[i], possibleMoves[i].nextPlayer);
                }
                else
                {
                    childs[i] = new MctsChanceNode(this, possibleNonDeterministicMove, possibleNonDeterministicMove.nextPlayer, possibleNonDeterministicMove.getChildDistribution());
                }
            }

            _childNodes = childs;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        private static BackpropagationContainer defaultPolicy(IMctsableGameState gameState)
        {
            IMctsableGameState gameForSimulation = gameState.duplicate();

            Random rng = new Random();

            List <IMove> pathToResult = new List <IMove>(), possibleMoves;
            IMove        chosenMove;

            while (!gameForSimulation.isGameOver())
            {
                possibleMoves = gameForSimulation.getPossibleMoves();

                chosenMove = possibleMoves[rng.Next(possibleMoves.Count)];

                gameForSimulation.makeMove(chosenMove);
                pathToResult.Add(chosenMove);
            }

            return(new BackpropagationContainer(gameForSimulation.getResultOfTheGame(), pathToResult));
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        private static BackpropagationContainer mctsSearch(IMctsableGameState gameState, MctsNode node)
        {
            if (!node.areChildNodesExpanded)
            {
                if (node.playouts == 0)
                {
                    return(defaultPolicy(gameState));
                }

                node.expandNode();
            }

            MctsNode bestNode = MctsNode.childSelection(node, _DEFAULT_EXPLORATION_CONSTANT);

            gameState.makeMove(bestNode.move);

            BackpropagationContainer result;

            if (!gameState.isGameOver())
            {
                result = mctsSearch(gameState, bestNode);
            }
            else
            {
                result = new BackpropagationContainer(gameState.getResultOfTheGame(), null);
            }

            bestNode.addResult(result.gameResult);
            bestNode.addResultToAMAFChilds(result);

            if (result.pathToResult != null)
            {
                result.addMoveToPath(bestNode.move);
            }

            return(result);
        }
Ejemplo n.º 7
0
 public MctsRootNode(IMctsableGameState initialGameState) : base(null, null, initialGameState.phasingPlayer)
 {
     this.initialGameState = initialGameState ?? throw new ArgumentNullException("CLASS: MctsRootNode, CONSTRUCTOR - the given game state is null!");
 }