Пример #1
0
        /// <summary>
        /// Performs the tree search.
        /// </summary>
        /// <param name="rootState"></param>
        /// <param name="maxIterations"></param>
        /// <param name="randomizeState"></param>
        /// <returns></returns>
        internal static TreeNode Search(PlayingState rootState, int maxIterations = int.MaxValue, bool randomizeState = true)
        {
            var rootNode = new TreeNode();

            HandRandomizer randomizer = null;

            if ((randomizeState) && (rootState.NeedRandomize()))
            {
                randomizer = new HandRandomizer(rootState);
            }

            for (var i = 0; i < maxIterations; i++)
            {
                var node = rootNode;

                // 1. Determinize.
                var state = rootState.CloneAndRandomize(randomizer);

                // 2. Select.
                var validMoves = state.GetValidMoves();
                while ((validMoves != 0) && (node.GetUntriedMoves(validMoves) == 0)) // The node is fully expanded and non-terminal.
                {
                    node = node.UcbSelectChild(validMoves);
                    state.DoMove(node.Move);

                    validMoves = state.GetValidMoves();
                }

                // 3. Expand.
                var untriedMoves = node.GetUntriedMoves(validMoves);
                if (untriedMoves != 0)
                {
                    var randomMove  = GetRandomMove(untriedMoves, state);
                    var activeIndex = state.ActiveIndex;

                    state.DoMove(randomMove);

                    node = node.AddChild(randomMove, activeIndex);
                }

                // 4. Simulate.
                validMoves = state.GetValidMoves();
                while (validMoves != 0)
                {
                    var randomMove = GetRandomMove(validMoves, state);
                    state.DoMove(randomMove);

                    validMoves = state.GetValidMoves();
                }

                // 5. Backpropagate.
                while (node != null)
                {
                    node.UpdateStatistics(state);
                    node = node.Parent;
                }
            }

            return(rootNode.GetBestChild());
        }
Пример #2
0
        /// <summary>
        /// Performs the tree search.
        /// </summary>
        /// <param name="rootState"></param>
        /// <param name="maxIterations"></param>
        /// <param name="randomizeState"></param>
        /// <returns></returns>
        internal static TreeNode Search(PlayingState rootState, int maxIterations = int.MaxValue, bool randomizeState = true)
        {
            var rootNode = new TreeNode();

            HandRandomizer randomizer = null;

            if ((randomizeState) && (rootState.NeedRandomize()))
                randomizer = new HandRandomizer(rootState);

            for (var i = 0; i < maxIterations; i++)
            {
                var node = rootNode;

                // 1. Determinize.
                var state = rootState.CloneAndRandomize(randomizer);

                // 2. Select.
                var validMoves = state.GetValidMoves();
                while ((validMoves != 0) && (node.GetUntriedMoves(validMoves) == 0)) // The node is fully expanded and non-terminal.
                {
                    node = node.UcbSelectChild(validMoves);
                    state.DoMove(node.Move);

                    validMoves = state.GetValidMoves();
                }

                // 3. Expand.
                var untriedMoves = node.GetUntriedMoves(validMoves);
                if (untriedMoves != 0)
                {
                    var randomMove = GetRandomMove(untriedMoves, state);
                    var activeIndex = state.ActiveIndex;

                    state.DoMove(randomMove);

                    node = node.AddChild(randomMove, activeIndex);
                }

                // 4. Simulate.
                validMoves = state.GetValidMoves();
                while (validMoves != 0)
                {
                    var randomMove = GetRandomMove(validMoves, state);
                    state.DoMove(randomMove);

                    validMoves = state.GetValidMoves();
                }

                // 5. Backpropagate.
                while (node != null)
                {
                    node.UpdateStatistics(state);
                    node = node.Parent;
                }
            }

            return rootNode.GetBestChild();
        }
Пример #3
0
        /// <summary>
        /// Returns a clone of the state replacing closed (not visible) hands with random card distributions.
        /// </summary>
        /// <param name="randomizer">Null to clone without randomizing.</param>
        /// <returns></returns>
        internal PlayingState CloneAndRandomize(HandRandomizer randomizer)
        {
            PlayingState clone = Clone();

            if (randomizer != null)
            {
                randomizer.Randomize();
            }

            return(clone);
        }
Пример #4
0
 private static Move GetRandomMove(int cards, PlayingState state)
 {
     if (!state.IsActiveHandOpen)
     {
         return(GetRandomCard(cards));
     }
     else
     {
         return(GetRandomGroup(cards, state.Discards));
     }
 }
Пример #5
0
        private PlayingState Clone()
        {
            var clone = new PlayingState(mContext);

            for (int i = 0; i < HandCount; i++)
            {
                clone.mHands[i] = mHands[i].Clone();
            }

            clone.mActiveIndex = mActiveIndex;
            clone.mLeadingSuit = mLeadingSuit;
            clone.mDiscards    = mDiscards;

            return(clone);
        }
Пример #6
0
 internal HandRandomizer(PlayingState state)
 {
     mState = state;
     CalculateCardSets();
 }
Пример #7
0
 internal HandRandomizer(PlayingState state)
 {
     mState = state;
     CalculateCardSets();
 }
Пример #8
0
 /// <summary>
 /// Updates the statistics for this node using the specified state.
 /// </summary>
 /// <param name="state"></param>
 internal void UpdateStatistics(PlayingState state)
 {
     VisitCount++;
     mTotalValue += state.Evaluate(ActiveIndex);
 }
Пример #9
0
        private PlayingState Clone()
        {
            var clone = new PlayingState(mContext);

            for (int i = 0; i < HandCount; i++)
                clone.mHands[i] = mHands[i].Clone();

            clone.mActiveIndex = mActiveIndex;
            clone.mLeadingSuit = mLeadingSuit;
            clone.mDiscards = mDiscards;

            return clone;
        }
Пример #10
0
 /// <summary>
 /// Updates the statistics for this node using the specified state.
 /// </summary>
 /// <param name="state"></param>
 internal void UpdateStatistics(PlayingState state)
 {
     VisitCount++;
     mTotalValue += state.Evaluate(ActiveIndex);
 }
Пример #11
0
 private static Move GetRandomMove(int cards, PlayingState state)
 {
     if (!state.IsActiveHandOpen)
         return GetRandomCard(cards);
     else
         return GetRandomGroup(cards, state.Discards);
 }