Ejemplo n.º 1
0
        /// <summary>
        /// 以Alpha-Beta剪枝框架并使用TranslationTable生成博弈树
        /// </summary>
        /// <param name="ThisChessBoard">当前棋盘状态</param>
        /// <param name="ThisNode">当前博弈树节点</param>
        public void ExpandNode_ABPruning(ChessBoard ThisChessBoard, GameTreeNode ThisNode, bool IfUseTT = true)
        {
            if (IfUseTT)
            {
                bool IfInTT = false;
                TranslationTable.GameTreeNodeForHash HashNode1 = new TranslationTable.GameTreeNodeForHash();
                HashNode1 = NodeTranslationTable.Search(ThisNode.NodeHashCode, ref IfInTT);
                if (ThisNode.depth != 0 && IfInTT && ThisNode.depth + RootDepth <= HashNode1.depth)
                {
                    ThisNode.alpha = HashNode1.alpha;
                    ThisNode.beta  = HashNode1.beta;
                    return;
                }
            }
            ///暂存一些量以便恢复
            EnumNowPlayer PlayerSave = NowQuoridor.ReversePlayer(ThisNode.NodePlayer);

            NowQuoridor.Player_Now = PlayerSave;

            List <QuoridorAction> QABuff = NowQuoridor.ActionList;

            //QABuff = NowQuoridor.CreateActionList_ALL(ThisChessBoard, ThisNode.P1Distance, ThisNode.P2Distance);
            QABuff = NowQuoridor.CreateActionList(ThisChessBoard, GameTreePlayer
                                                  , ThisNode.NodeAction.ActionCheckResult.P1Distance
                                                  , ThisNode.NodeAction.ActionCheckResult.P2Distance);

            foreach (QuoridorAction QA in QABuff)
            {
                #region 保存棋盘状态
                ChessBoard ChessBoardBuff = new ChessBoard();
                ChessBoard.SaveChessBoard(ref ChessBoardBuff, ThisChessBoard);
                #endregion
                #region 模拟落子
                string Hint = NowQuoridor.QuoridorRule.Action(ref ThisChessBoard, QA.ActionPoint.X, QA.ActionPoint.Y, QA.PlayerAction);
                try
                {
                    if (Hint != "OK")
                    {
                        Exception e = new Exception();
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                if (QA.PlayerAction == NowAction.Action_PlaceHorizontalBoard || QA.PlayerAction == NowAction.Action_PlaceVerticalBoard)
                {
                    if (PlayerSave == EnumNowPlayer.Player1)
                    {
                        ThisChessBoard.NumPlayer1Board -= 2;
                    }
                    else
                    {
                        ThisChessBoard.NumPlayer2Board -= 2;
                    }
                }
                #endregion

                if (ThisNode.depth <= DepthMax)
                {
                    CreateNewSon(ThisNode, new GameTreeNode(QA
                                                            , PlayerSave, ThisNode.depth + 1, ThisNode.alpha, ThisNode.beta, ThisNode.score));

                    if (IfUseTT)
                    {
                        long HashCodeBuff = NodeTranslationTable.NodeGetHashCode(ThisNode.NodeHashCode, QA, ChessBoardBuff);//ThisChessBoard已变,不能作为原棋盘传入,只能上一步的棋盘ChessBoardBuff
                        ThisNode.SonNode.Last().NodeHashCode = HashCodeBuff;
                    }
                    ExpandNode_ABPruning(ThisChessBoard, ThisNode.SonNode.Last(), IfUseTT);
                }
                else
                {
                    CreateNewSon(ThisNode, new GameTreeNode(QA
                                                            , PlayerSave, ThisNode.depth + 1, ThisNode.alpha, QA.WholeScore, QA.WholeScore));
                }

                ChessBoard.ResumeChessBoard(ref ThisChessBoard, ChessBoardBuff);

                #region Min层
                if (ThisNode.NodePlayer == PolicyPlayer)
                {
                    if (ThisNode.SonNode.Last().alpha < ThisNode.beta)
                    {
                        ThisNode.beta  = ThisNode.SonNode.Last().alpha;
                        ThisNode.score = ThisNode.SonNode.Last().alpha;
                    }
                }
                #endregion
                #region Max层
                else
                {
                    if (ThisNode.SonNode.Last().beta > ThisNode.alpha)
                    {
                        ThisNode.alpha = ThisNode.SonNode.Last().beta;
                        ThisNode.score = ThisNode.SonNode.Last().beta;
                    }
                }
                #endregion

                if (ThisNode.depth <= DepthMax && ThisNode.beta <= ThisNode.alpha)//剪枝
                {
                    #region 存入置换表
                    if (IfUseTT)
                    {
                        /*剪枝break前这个时刻该节点已经遍历完毕,可以加入置换表*/
                        TranslationTable.GameTreeNodeForHash HashNodeBuff = new TranslationTable.GameTreeNodeForHash();
                        HashNodeBuff.alpha = ThisNode.alpha;
                        HashNodeBuff.beta  = ThisNode.beta;
                        HashNodeBuff.depth = ThisNode.depth + RootDepth;

                        NodeTranslationTable.Add(ThisNode.NodeHashCode, HashNodeBuff);
                    }
                    #endregion
                    break;
                }
            }
            #region 存入置换表
            if (IfUseTT)
            {
                /*遍历完整个动作列表后可以加入置换表*/
                TranslationTable.GameTreeNodeForHash HashNodeBuff2 = new TranslationTable.GameTreeNodeForHash();
                HashNodeBuff2.alpha = ThisNode.alpha;
                HashNodeBuff2.beta  = ThisNode.beta;
                HashNodeBuff2.depth = ThisNode.depth + RootDepth;

                NodeTranslationTable.Add(ThisNode.NodeHashCode, HashNodeBuff2);
            }
            #endregion
        }