Beispiel #1
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);
        }
Beispiel #2
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;
        }
Beispiel #3
0
        public MctsChanceNode(MctsNode previousNode, INonDeterministicMove move, int phasingPlayer, ReadOnlyCollection <double> childDistribution) : base(previousNode, move, phasingPlayer)
        {
            if (previousNode == null || move == null || childDistribution == null)
            {
                throw new ArgumentNullException("CLASS: MctsChanceNode, CONSTRUCTOR - at least one of the given parameter is null!");
            }

            expandNode();

            if (childDistribution.Count != getChildNodes().Count)
            {
                throw new ArgumentException("CLASS: MctsChanceNode, CONSTRUCTOR - the number of the given probabilities does not coincide with the number of possible moves!!");
            }

            double checksum = 0;

            for (int i = 0; i < childDistribution.Count; i++)
            {
                if (childDistribution[i] < 0 || childDistribution[i] > 1)
                {
                    throw new ArgumentException("CLASS: MctsChanceNode, CONSTRUCTOR - invalid given probability!");
                }

                checksum += childDistribution[i];
            }

            if (Math.Abs(checksum - 1.0) > Math.Pow(10, _FLOATING_PRECISSION))
            {
                throw new ArgumentException("CLASS: MctsChanceNode, CONSTRUCTOR - invalid distribution (sum has to be 1)!");
            }

            this.childDistribution = childDistribution;
        }
Beispiel #4
0
        public void addResult(GameResult gameResult, MctsNode backpropagatingNode)
        {
            if (gameResult == null || backpropagatingNode == null)
            {
                throw new ArgumentNullException("CLASS: MctsChanceNode, METHOD: addResult - at least one of the given parameter is null!");
            }

            int indexOfBackpropagatingNode;

            try {
                indexOfBackpropagatingNode = getChildNodes().IndexOf(backpropagatingNode);
            }
            catch (InvalidOperationException) {
                throw new InvalidOperationException("CLASS: MctsChanceNode, METHOD: addResult - the child nodes do not have been expanded yet!");
            }

            if (indexOfBackpropagatingNode == -1)
            {
                throw new ArgumentException("CLASS: MctsChanceNode, METHOD: addResult - the given backpropagating node is not a child node!");
            }

            playouts++;

            if (gameResult.winner == move.playerWhoDoesTheMove)
            {
                value += childDistribution[indexOfBackpropagatingNode] * (1 + gameResult.relativeVictoryPoints);
            }
        }
Beispiel #5
0
        public MctsNode(MctsNode previousNode, IMove move, int phasingPlayer)
        {
            this.move          = move;
            this.previousNode  = previousNode;
            this.phasingPlayer = phasingPlayer;

            areChildNodesExpanded = false;
        }
Beispiel #6
0
        public static MctsNode childSelection(MctsNode node, double explorationConstant)
        {
            MctsNode selectedChild = childSelectionService(node, explorationConstant) as MctsNode;

            if (selectedChild == null)
            {
                throw new InvalidOperationException("CLASS: MctsNode, METHOD: childSelection - child selection service returns no mcts node!");
            }

            return(selectedChild);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
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);
        }