Example #1
0
        /// <summary>
        /// Expand the tree out to our maximum depth, only expanding leaf nodes with the best-possible score
        /// </summary>
        /// <param name="maxDepth"></param>
        public void Expand(int maxDepth)
        {
            NumLeaves             = 0;
            ConsideredBoardStates = new List <TakBoard>();
            List <TakMove> nextMoves = PlayerAI.EnumerateMoves(MyColor, Root.InitialState);

            foreach (TakMove m in nextMoves)
            {
                MoveNode n = new MoveNode(Root.InitialState, m);
                if (!ConsideredBoardStates.Contains(n.ResultingState.Board))
                {
                    ConsideredBoardStates.Add(n.ResultingState.Board);
                    n.Depth  = 1;
                    n.Parent = null;
                    n.Score  = n.ResultingState.Evaluate(MyColor);
                    Root.Children.Add(n);
                }
            }

            // recursively expand the tree
            MaxDepth = maxDepth;
            foreach (MoveNode n in Root.Children)
            {
                n.Score = ABPrune(n, (double)int.MinValue - 1, (double)int.MaxValue + 1, true);
            }
            Root.Children.Sort();
            PrintDebug(string.Format("Explored {0} board states", ConsideredBoardStates.Count));
            PrintDebug(string.Format("Explored {0} leaves", NumLeaves));
        }
Example #2
0
        /// <summary>
        /// Expand a node using AB pruning
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        private double ABPrune(MoveNode root, double alpha, double beta, bool isMaxing)
        {
            // don't re-expand if we hit an automatic win or loss, or if we're at the depth limit
            if (root.Depth >= MaxDepth || root.ResultingState.GameOver)
            {
                NumLeaves++;
                root.Score = root.ResultingState.Evaluate(MyColor);
                return(root.Score);
            }
            else
            {
                List <TakMove> nextMoves = PlayerAI.EnumerateMoves(isMaxing ? MyColor : TheirColor, root.ResultingState);
                double         v;
                if (isMaxing)
                {
                    v = (double)int.MinValue - 1;
                    foreach (TakMove m in nextMoves)
                    {
                        MoveNode n = new MoveNode(root.ResultingState, m);
                        n.Depth = root.Depth + 1;
                        root.Children.Add(n);
                        n.Parent = root;
                        if (!ConsideredBoardStates.Contains(n.ResultingState.Board))
                        {
                            //Console.WriteLine("Considering\n{0}", n.ResultingState.Board);
                            ConsideredBoardStates.Add(n.ResultingState.Board);

                            v     = Math.Max(v, ABPrune(n, alpha, beta, false));
                            alpha = Math.Max(alpha, v);
                            if (beta <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    v = (double)int.MaxValue + 1;
                    foreach (TakMove m in nextMoves)
                    {
                        MoveNode n = new MoveNode(root.ResultingState, m);
                        n.Depth = root.Depth + 1;
                        root.Children.Add(n);
                        n.Parent = root;
                        if (!ConsideredBoardStates.Contains(n.ResultingState.Board))
                        {
                            //Console.WriteLine("Considering\n{0}", n.ResultingState.Board);
                            ConsideredBoardStates.Add(n.ResultingState.Board);

                            v    = Math.Max(v, ABPrune(n, alpha, beta, true));
                            beta = Math.Min(beta, v);
                            if (beta <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }

                root.Children.Sort();
                if (isMaxing)
                {
                    root.Children.Reverse();
                }

                return(v);
            }
        }