Beispiel #1
0
        /// <summary>
        /// 根据当前局面拓展一个未拓展节点
        /// </summary>
        /// <param name="ThisChessBoard">当前局面棋盘</param>
        /// <param name="FatherNode">父节点</param>
        public void Expand(ChessBoard ThisChessBoard, MonteCartoTreeNode FatherNode)
        {
            if (SonNode.Count == 0)//未拓展节点
            {
                EnumNowPlayer PlayerSave = NowQuoridor.ReversePlayer(FatherNode.NodePlayer);
                NowQuoridor.Player_Now = PlayerSave;

                List <QuoridorAction> QABuff = NowQuoridor.ActionList;

//                QABuff = NowQuoridor.CreateActionList(ThisChessBoard, EnumNowPlayer.Player2);
                //QABuff = NowQuoridor.CreateActionList_ALL(ThisChessBoard);
                /*完全拓展*/
                foreach (QuoridorAction QA in QABuff)
                {
                    MonteCartoTreeNode MTSonNode = new MonteCartoTreeNode();
                    MTSonNode.NodePlayer       = PlayerSave;
                    MTSonNode.NodeAction       = QA.PlayerAction;
                    MTSonNode.ActionLocation.X = QA.ActionPoint.X;
                    MTSonNode.ActionLocation.Y = QA.ActionPoint.Y;
                    MTSonNode._P         = QA.WholeScore;
                    MTSonNode.FatherNode = FatherNode;
                    SonNode.Add(MTSonNode);
                    //if (QA.PlayerAction == NowAction.Action_PlaceHorizontalBoard || QA.PlayerAction == NowAction.Action_PlaceVerticalBoard)
                    //{
                    //    if (QA.OpponentScore - QA.SelfScore >= 5)
                    //    {
                    //        MTSonNode.IfWin = true;
                    //        SonNode = new List<MonteCartoTreeNode>();
                    //        SonNode.Add(MTSonNode);
                    //        break;
                    //    }
                    //}
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// 计算一个子节点的UCT值,用于Select
        /// </summary>
        /// <param name="FatherNode">父节点</param>
        /// <param name="SonNode">子节点</param>
        /// <returns>SonNode的UCT值</returns>
        public static double CalUCTValue_UCT(MonteCartoTreeNode FatherNode, MonteCartoTreeNode SonNode)
        {
            double UCTBuff = 0;
            double ExploitationComponent = 0, ExplorationComponent = 0;

            /*普通的UCT*/
            //ExploitationComponent = SonNode._Q / SonNode._N;
            //ExplorationComponent = _C * Math.Sqrt((Math.Log10(FatherNode._N) / SonNode._N));
            //UCTBuff = ExploitationComponent + ExplorationComponent;

            /*与P值有关的UCT*/
            UCTBuff = _C * SonNode._P * Math.Sqrt(FatherNode._N / (1 + SonNode._N));

            return(UCTBuff);
        }
Beispiel #3
0
        /// <summary>
        /// Select操作
        /// </summary>
        /// <param name="FatherNode">父节点</param>
        /// <returns>选择要去拓展的子节点</returns>
        public static MonteCartoTreeNode Select(MonteCartoTreeNode FatherNode)
        {
            MonteCartoTreeNode MTNode = new MonteCartoTreeNode();

            double MaxQUCT = -100;

            foreach (MonteCartoTreeNode NodeBuff in FatherNode.SonNode)
            {
                NodeBuff._UCT = CalUCTValue_UCT(FatherNode, NodeBuff);
                if (MaxQUCT < NodeBuff._UCT + NodeBuff._Q)//选择最大UCT + Q值的节点
                {
                    MaxQUCT = NodeBuff._UCT + NodeBuff._Q;
                    MTNode  = NodeBuff;
                }
            }

            return(MTNode);
        }
Beispiel #4
0
        /// <summary>
        /// 进行一次模拟(Simluation)
        /// </summary>
        /// <param name="InitChessBoard">当前决策节点局面</param>
        /// <param name="RootNode">根节点</param>
        public static void SimluationOnce(ChessBoard InitChessBoard, MonteCartoTreeNode RootNode)
        {
            #region 暂存挡板数量
            int Board1Save = InitChessBoard.NumPlayer1Board;
            int Board2Save = InitChessBoard.NumPlayer2Board;
            #endregion

            if (RootNode.SonNode.Count == 0)               //初始根节点
            {
                RootNode.Expand(InitChessBoard, RootNode); //先拓展一次
            }

            ChessBoard SimluationChessBoard = new ChessBoard();
            ChessBoard.SaveChessBoard(ref SimluationChessBoard, InitChessBoard);//相当于拷贝了
            MonteCartoTreeNode NextExpandNode = RootNode;
            while (true)
            {
                #region 提前终止局面检测
                if (NextExpandNode.SonNode.Count == 1)
                {
                    if (NextExpandNode.SonNode[0].IfWin)
                    {
                        double leaf_value = -1;
                        if (JudgePlayer != NextExpandNode.SonNode[0].NodePlayer)
                        {
                            leaf_value = 1;
                        }
                        NextExpandNode.BackPropagation(leaf_value);
                        break;
                    }
                }
                #endregion
                /*选择*/
                NextExpandNode = Select(NextExpandNode);

                #region 模拟落子
                string Hint = NowQuoridor.QuoridorRule.Action(ref SimluationChessBoard
                                                              , NextExpandNode.ActionLocation.X, NextExpandNode.ActionLocation.Y, NextExpandNode.NodeAction);
                try
                {
                    if (Hint != "OK")
                    {
                        Exception e = new Exception();
                    }
                }
                catch (Exception)
                {
                    throw;
                }

                if (NextExpandNode.NodePlayer == EnumNowPlayer.Player1)
                {
                    if (NextExpandNode.NodeAction == NowAction.Action_PlaceVerticalBoard ||
                        NextExpandNode.NodeAction == NowAction.Action_PlaceHorizontalBoard)
                    {
                        SimluationChessBoard.NumPlayer1Board -= 2;
                    }
                }
                else if (NextExpandNode.NodePlayer == EnumNowPlayer.Player2)
                {
                    if (NextExpandNode.NodeAction == NowAction.Action_PlaceVerticalBoard ||
                        NextExpandNode.NodeAction == NowAction.Action_PlaceHorizontalBoard)
                    {
                        SimluationChessBoard.NumPlayer2Board -= 2;
                    }
                }
                #endregion

                //SimluationChessBoard.DrawNowChessBoard(ref Form1.Gr, Form1.form1.ChessWhitePB, Form1.form1.ChessBlackPB);
                //Form1.form1.ChessBoardPB.Refresh();
                //System.Threading.Thread.Sleep(500);
                string SucessHint = RuleEngine.CheckResult(SimluationChessBoard);
                if (SucessHint != "No success")//搜索到胜利节点了
                {
                    double leaf_value = -1;
                    if (JudgePlayer == EnumNowPlayer.Player1 && SucessHint == "Player1 Success!")
                    {
                        leaf_value = 1;
                    }
                    if (JudgePlayer == EnumNowPlayer.Player2 && SucessHint == "Player2 Success!")
                    {
                        leaf_value = 1;
                    }

                    NextExpandNode.BackPropagation(leaf_value);
                    break;
                }

                double dis_player1 = RuleEngine.AstarEngine.AstarRestart(SimluationChessBoard, EnumNowPlayer.Player1
                                                                         , SimluationChessBoard.Player1Location.X, SimluationChessBoard.Player1Location.Y);
                double dis_player2 = RuleEngine.AstarEngine.AstarRestart(SimluationChessBoard, EnumNowPlayer.Player2
                                                                         , SimluationChessBoard.Player2Location.X, SimluationChessBoard.Player2Location.Y);

                EnumNowPlayer Winner = EnumNowPlayer.Player1;
                # region 必赢必输局面检测
                //if (dis_player1 >= 14 || dis_player2 >= 14)//某人步数过大
                //{
                //    if (dis_player2 - dis_player1 >= 5)
                //    {
                //        Winner = EnumNowPlayer.Player2;
                //    }
                //}
                //else if (SimluationChessBoard.NumPlayer2Board == 0 && SimluationChessBoard.NumPlayer1Board == 0)//挡板已用完
                //{
                //    #region 是否存在跳棋检测(未写)
                //    #endregion
                //    if (dis_player2 - dis_player1 > 0)
                //    {
                //        Winner = EnumNowPlayer.Player2;
                //    }
                //}

                //double leaf_value2 = -1;
                //if (JudgePlayer == EnumNowPlayer.Player1 && Winner == EnumNowPlayer.Player1)//下一步是P2走
                //{
                //    leaf_value2 = 1;
                //}
                //if (JudgePlayer == EnumNowPlayer.Player2 && Winner == EnumNowPlayer.Player2)//下一步是P1走
                //{
                //    leaf_value2 = 1;
                //}
                //NextExpandNode.BackPropagation(leaf_value2);

                #endregion

                /*拓展*/
                NextExpandNode.Expand(SimluationChessBoard, NextExpandNode);
            }