示例#1
0
        /// <summary>
        /// 根据当前棋盘状态以及寻路玩家生成哈希字符串
        /// </summary>
        /// <param name="ToHashChessBoard">当前棋盘状态</param>
        /// <param name="LookupPlayer">寻路玩家</param>
        /// <returns>哈希字符串</returns>
        public string GetHashCode_String(ChessBoard ToHashChessBoard, EnumNowPlayer LookupPlayer)
        {
            string HashBuff = "";

            HashBuff += "P";
            if (LookupPlayer == EnumNowPlayer.Player1)
            {
                HashBuff += "1";
            }
            else
            {
                HashBuff += "2";
            }
            HashBuff += "V";
            HashBuff += ToHashChessBoard.VerticalBoardHashCode.ToString();
            HashBuff += "H";
            HashBuff += ToHashChessBoard.HorizontalBoardHashCode.ToString();
            HashBuff += "P1L";
            HashBuff += ToHashChessBoard.Player1Location.X.ToString();
            HashBuff += ToHashChessBoard.Player1Location.Y.ToString();
            HashBuff += "P2L";
            HashBuff += ToHashChessBoard.Player2Location.X.ToString();
            HashBuff += ToHashChessBoard.Player2Location.Y.ToString();
            return(HashBuff);
        }
示例#2
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;
                    //    }
                    //}
                }
            }
        }
示例#3
0
        public QuoridorAction GetNextPolicy(Enum_PlayerType PlayerType, EnumNowPlayer Player, out string ErrorHint)
        {
            ErrorHint = "";
            QuoridorAction NextPolicy = new QuoridorAction(NowAction.Action_Wait, new Point(-1, -1));

            #region 玩家决策
            if (PlayerType == Enum_PlayerType.Human)
            {
                while (!HumanPolicyFinish)
                {
                }
                ErrorHint = MousePointToPolicyPoint(HumanMouseClickPoint);
                if (ErrorHint == "OK")
                {
                    NextPolicy.ActionPoint = HumanPolicyLocation;
                    if (HumanPolicyAction == NowAction.Action_Move_Player1 || HumanPolicyAction == NowAction.Action_Move_Player2)
                    {
                        if (Player == EnumNowPlayer.Player1)
                        {
                            HumanPolicyAction = NowAction.Action_Move_Player1;
                        }
                        else
                        {
                            HumanPolicyAction = NowAction.Action_Move_Player2;
                        }
                    }
                    NextPolicy.PlayerAction = HumanPolicyAction;
                    HumanPolicyFinish       = false;
                }
            }
            #endregion
            # region AI决策
            else if (PlayerType == Enum_PlayerType.AI)
示例#4
0
        /// <summary>
        /// 创建一棵博弈树
        /// </summary>
        /// <param name="RootNode">待生成树的根节点</param>
        /// <param name="ChessBoard_Init">初始棋盘状态</param>
        /// <param name="DepthMax_Set">博弈树深度</param>
        /// <param name="IfShowDebugLog">是否显示调试日志,默认不显示</param>
        public static void CreateGameTree(EnumNowPlayer PolicyPlayer, GameTreeNode RootNode, ChessBoard ChessBoard_Init, int DepthMax_Set, bool IfShowDebugLog = false)
        {
            try
            {
                Exception E = new Exception("最大深度设定错误!请设置为偶数!");
                if (DepthMax_Set % 2 != 0)//必须是偶数
                {
                    throw E;
                }
            }
            catch (Exception e)
            {
                throw;
            }
            DepthMax = DepthMax_Set - 1;
            RootNode.PolicyPlayer = PolicyPlayer;
            if (SearchFrameWork == Enum_GameTreeSearchFrameWork.MinMax)
            {
                RootNode.ExpandNode_MinMax(ChessBoard_Init, RootNode);//3W数量级节点数
                double MaxScore = -1000;
                foreach (GameTreeNode GTN in RootNode.SonNode)
                {
                    if (MaxScore < GTN.score)
                    {
                        MaxScore            = GTN.score;
                        RootNode.NodePlayer = GTN.NodePlayer;
                        RootNode.NodeAction = GTN.NodeAction;
                        RootNode.score      = MaxScore;
                    }
                }
            }
            else
            {
                RootNode.NodeHashCode = GameTreeNode.InitChessBoardHashCode;
                RootNode.ExpandNode_ABPruning(ChessBoard_Init, RootNode, GameTreeNode.IfUseTanslationTable);

                double MaxScore = -1000;
                foreach (GameTreeNode GTN in RootNode.SonNode)
                {
                    if (MaxScore < GTN.beta)
                    {
                        MaxScore              = GTN.beta;
                        RootNode.NodePlayer   = GTN.NodePlayer;
                        RootNode.NodeAction   = GTN.NodeAction;
                        RootNode.score        = MaxScore;
                        RootNode.NodeHashCode = GTN.NodeHashCode;
                    }
                }
                InitChessBoardHashCode = RootNode.NodeHashCode;
            }


            if (IfShowDebugLog)
            {
                PrintGameTree(RootNode);
            }
        }
示例#5
0
 /// <summary>
 /// 构造函数,用来设定该博弈树节点的信息
 /// </summary>
 public GameTreeNode(QuoridorAction Action_set, EnumNowPlayer Player_set, int depth_set, double alpha_set, double beta_set, double score_set)
 {
     NodeAction = Action_set;
     NodePlayer = Player_set;
     depth      = depth_set;
     alpha      = alpha_set;
     beta       = beta_set;
     score      = score_set;
     InitTranslationTable();
 }
示例#6
0
 public QuoridorDecisionSystem(EnumNowPlayer PolicyPlayer_Set, Enum_DecisionAlgorithm UsedAlgorithm_Set, ABPurningPara ABPurningPara_Set)
 {
     UsedAlgorithm = UsedAlgorithm_Set;
     if (UsedAlgorithm == Enum_DecisionAlgorithm.AlphaBetaPurning)
     {
         ThisABPurningPara = ABPurningPara_Set;
     }
     PolicyPlayer = PolicyPlayer_Set;
     FormulaeListInit();
 }
示例#7
0
        /// <summary>
        /// 计算某点的距离
        /// </summary>
        /// <param name="Player">要检测哪个玩家会被这步挡板堵死</param>
        /// <param name="Location_row">某点的行</param>
        /// <param name="Location_col">某点的列</param>
        /// <returns></returns>
        public int CalDistance(ChessBoard ThisChessBoard, EnumNowPlayer Player, int Location_row, int Location_col)
        {
            int Row_Destination = 0;

            switch (Player)
            {
            case EnumNowPlayer.Player1:
                Row_Destination = 6;
                break;

            case EnumNowPlayer.Player2:
                Row_Destination = 0;
                break;

            default:
                break;
            }

            int Num_VBoard = 0, Num_HBoard = 0;

            for (int i = Location_row + 1; i <= Row_Destination; i++)//下扫
            {
                if (ThisChessBoard.ChessBoardAll[i, Location_col].IfUpBoard)
                {
                    Num_HBoard++;
                }
            }
            for (int i = Location_row - 1; i >= Row_Destination; i--)//上扫
            {
                if (ThisChessBoard.ChessBoardAll[i + 1, Location_col].IfUpBoard)
                {
                    Num_HBoard++;
                }
            }
            for (int i = Location_col - 1; i >= 0; i--)//左扫
            {
                if (ThisChessBoard.ChessBoardAll[Location_row, i + 1].IfLeftBoard)
                {
                    Num_VBoard++;
                }
            }
            for (int i = Location_col + 1; i <= 6; i++)//右扫
            {
                if (ThisChessBoard.ChessBoardAll[Location_row, i - 1].IfLeftBoard)
                {
                    Num_VBoard++;
                }
            }

            return(Num_HBoard + Num_VBoard);
        }
示例#8
0
        /// <summary>
        /// 将棋盘玩家位置状态转换成字符串
        /// </summary>
        public string ChessBoardLocationToString(ChessBoard ThisChessBoard, EnumNowPlayer Player)
        {
            string LStr           = "";
            Point  PlayerLocation = ThisChessBoard.Player1Location;

            if (Player == EnumNowPlayer.Player2)
            {
                PlayerLocation = ThisChessBoard.Player2Location;
            }
            if (Player == EnumNowPlayer.Player1)
            {
                LStr = "P1:";
            }
            else
            {
                LStr = "P2:";
            }
            LStr += PlayerLocation.X.ToString() + "," + PlayerLocation.Y.ToString();
            return(LStr);
        }
示例#9
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);
            }
示例#10
0
        /// <summary>
        /// 检测该挡板是否能被放下
        /// </summary>
        /// <param name="WhichBoard">放置哪种挡板</param>
        /// <param name="Player">检测哪个玩家会被堵死</param>
        /// <param name="Location_row">玩家的位置行</param>
        /// <param name="Location_col">玩家的位置列</param>
        /// <returns>检测挡板结果</returns>
        public CheckBoardResult CheckBoard(ChessBoard ChessBoard_ToCheck, NowAction WhichBoard, EnumNowPlayer Player, int Location_row, int Location_col)
        {
            CheckBoardResult Result         = new CheckBoardResult();
            ChessBoard       ThisChessBoard = ChessBoard_ToCheck;

            //if (WhichBoard == NowAction.Action_Move_Player1 || WhichBoard == NowAction.Action_Move_Player2)
            //{
            //    Result.HintStr = "OK";
            //    return Result;
            //}
            if (WhichBoard != NowAction.Action_Move_Player1 && WhichBoard != NowAction.Action_Move_Player2)
            {
                if (Player == EnumNowPlayer.Player1 && ChessBoard_ToCheck.NumPlayer1Board <= 0)
                {
                    Result.HintStr = "Player1 No Board";
                    return(Result);
                }
                else if (Player == EnumNowPlayer.Player2 && ChessBoard_ToCheck.NumPlayer2Board <= 0)
                {
                    Result.HintStr = "Player2 No Board";
                    return(Result);
                }
            }
            ///为了不改变原状态而暂存原状态以便后续恢复
            ChessBoard ChessBoardBuff = new ChessBoard();

            ChessBoard.SaveChessBoard(ref ChessBoardBuff, ThisChessBoard);

            //假设能放挡板
            string Hint = Action(ref ThisChessBoard, Location_row, Location_col, WhichBoard);

            if (Hint == "OK")
            {
                int disbuff1 = 0, disbuff2 = 0;
                disbuff1 = AstarEngine.AstarRestart(ThisChessBoard, EnumNowPlayer.Player1
                                                    , ThisChessBoard.Player1Location.X, ThisChessBoard.Player1Location.Y);
                disbuff2 = AstarEngine.AstarRestart(ThisChessBoard, EnumNowPlayer.Player2
                                                    , ThisChessBoard.Player2Location.X, ThisChessBoard.Player2Location.Y);
                Result.P1Distance = disbuff1;
                Result.P2Distance = disbuff2;
                if (disbuff1 >= 999 && disbuff2 < 999)
                {
                    Hint = "Player1 No Road!";
                }
                else if (disbuff2 >= 999 && disbuff1 < 999)
                {
                    Hint = "Player2 No Road!";
                }
                else if (disbuff1 >= 999 && disbuff2 >= 999)
                {
                    Hint = "Player1&Player2 No Road!";
                }
            }
            if (Hint != "OK")
            {
                ChessBoard.ResumeChessBoard(ref ThisChessBoard, ChessBoardBuff);
                Result.HintStr = Hint;
                return(Result);
            }

            ChessBoard.ResumeChessBoard(ref ThisChessBoard, ChessBoardBuff);
            Result.HintStr = "OK";
            return(Result);
        }
示例#11
0
        public static int DepthMax = 1000;///博弈树最大深度
        /// <summary>
        /// 以极大极小搜索框架生成博弈树
        /// </summary>
        /// <param name="ThisChessBoard">当前棋盘状态</param>
        /// <param name="ThisNode">当前博弈树节点</param>
        public void ExpandNode_MinMax(ChessBoard ThisChessBoard, GameTreeNode ThisNode)
        {
            ///暂存一些量以便恢复
            EnumNowPlayer PlayerSave = NowQuoridor.ReversePlayer(ThisNode.NodePlayer);

            NowQuoridor.Player_Now = PlayerSave;

            List <QuoridorAction> QABuff = NowQuoridor.ActionList;

            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;
                }
                #endregion

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

                    ExpandNode_MinMax(ThisChessBoard, ThisNode.SonNode.Last());
                }
                else
                {
                    CreateNewSon(ThisNode, new GameTreeNode(QA
                                                            , PlayerSave, ThisNode.depth + 1, QA.WholeScore, QA.WholeScore, QA.WholeScore));
                }
                #region 恢复棋盘状态
                ChessBoard.ResumeChessBoard(ref ThisChessBoard, ChessBoardBuff);
                #endregion
            }
            if (ThisNode.NodePlayer == NowQuoridor.PlayerBuff)//MIN层
            {
                double minvalue = 99999;
                foreach (GameTreeNode Son in ThisNode.SonNode)
                {
                    if (Son.score < minvalue)
                    {
                        minvalue       = Son.score;
                        ThisNode.score = minvalue;
                    }
                }
            }
            else //MAX层
            {
                double maxvalue = -10000;
                foreach (GameTreeNode Son in ThisNode.SonNode)
                {
                    if (Son.score > maxvalue)
                    {
                        maxvalue       = Son.score;
                        ThisNode.score = maxvalue;
                        if (ThisNode.depth == 0)//根节点层
                        {
                            ThisNode.NodeAction = Son.NodeAction;
                            ThisNode.NodePlayer = Son.NodePlayer;
                        }
                    }
                }
            }
        }
示例#12
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
        }
示例#13
0
        public void QuoridorGame_Do()
        {
            #region 配置初始棋盘
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[0, 3].GridStatus = Grid.GridInsideStatus.Empty;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[1, 3].GridStatus = Grid.GridInsideStatus.Have_Player1;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[6, 3].GridStatus = Grid.GridInsideStatus.Empty;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[5, 3].GridStatus = Grid.GridInsideStatus.Have_Player2;

            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[1, 3].IfUpBoard = true;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[1, 4].IfUpBoard = true;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[6, 2].IfUpBoard = true;
            //NowGame.QuoridorEva.ThisChessBoard.ChessBoardAll[6, 3].IfUpBoard = true;

            ////NowQuoridor.ThisChessBoard.ChessBoardAll[2, 3].IfLeftBoard = true;
            ////NowQuoridor.ThisChessBoard.ChessBoardAll[3, 3].IfLeftBoard = true;
            ////NowQuoridor.ThisChessBoard.ChessBoardAll[2, 4].IfLeftBoard = true;
            ////NowQuoridor.ThisChessBoard.ChessBoardAll[3, 4].IfLeftBoard = true;

            //NowGame.QuoridorEva.ThisChessBoard.NumPlayer1Board = 16 - 2;
            //NowGame.QuoridorEva.ThisChessBoard.NumPlayer2Board = 16 - 2;


            //NowGame.QuoridorEva.ThisChessBoard.Player1Location = new Point(1, 3);
            //NowGame.QuoridorEva.ThisChessBoard.Player2Location = new Point(5, 3);
            #endregion
            BlackBoardNumLB.Text = NowGame.QuoridorEva.ThisChessBoard.NumPlayer2Board.ToString();
            WhiteBoardNumLB.Text = NowGame.QuoridorEva.ThisChessBoard.NumPlayer1Board.ToString();

            //刷新初始棋盘
            NowGame.QuoridorEva.ThisChessBoard.DrawNowChessBoard(ref Gr, ChessWhitePB, ChessBlackPB);
            ChessBoardPB.Refresh();

            EnumNowPlayer NowPlayer = EnumNowPlayer.Player1;
            while (true)
            {
                string Hint = NowGame.DoOncePolicy(ref NowPlayer);
                if (Hint == "Player1 Success!" || Hint == "Player2 Success!")
                {
                    NowGame.QuoridorEva.ThisChessBoard.DrawNowChessBoard(ref Gr, ChessWhitePB, ChessBlackPB);
                    ChessBoardPB.Refresh();
                    MessageBox.Show(Hint);
                    System.Environment.Exit(0);
                    break;
                }
                else if (Hint != "OK")
                {
                    TestTB.Text = Hint;
                    #region 取消放置挡板
                    IfPlaceBoard = false;
                    if (NowPlayer == EnumNowPlayer.Player1)
                    {
                        PlayerNowAction = NowAction.Action_Move_Player1;
                    }
                    if (NowPlayer == EnumNowPlayer.Player2)
                    {
                        PlayerNowAction = NowAction.Action_Move_Player2;
                    }
                    PlaceVerticalBoardBTN.Enabled   = true;
                    PlaceHorizontalBoardBTN.Enabled = true;

                    IfShowFollow      = false;
                    VBoardPB.Visible  = false;
                    VBoardPB.Location = new Point(837, 569);
                    HBoardPB.Visible  = false;
                    HBoardPB.Location = new Point(837, 569);
                    #endregion
                    continue;
                }
                #region 取消放置挡板
                IfPlaceBoard = false;
                if (NowPlayer == EnumNowPlayer.Player1)
                {
                    PlayerNowAction = NowAction.Action_Move_Player1;
                }
                if (NowPlayer == EnumNowPlayer.Player2)
                {
                    PlayerNowAction = NowAction.Action_Move_Player2;
                }
                PlaceVerticalBoardBTN.Enabled   = true;
                PlaceHorizontalBoardBTN.Enabled = true;

                IfShowFollow      = false;
                VBoardPB.Visible  = false;
                VBoardPB.Location = new Point(837, 569);
                HBoardPB.Visible  = false;
                HBoardPB.Location = new Point(837, 569);
                #endregion
                if (NowPlayer == EnumNowPlayer.Player2 && NowGame.P1Type == QuoridorGame.Enum_PlayerType.AI)
                {
                    NowGame.PolicyRootNodeList.Add(NowGame.NodeToTreeView);
                }
                else if (NowPlayer == EnumNowPlayer.Player1 && NowGame.P2Type == QuoridorGame.Enum_PlayerType.AI)
                {
                    NowGame.PolicyRootNodeList.Add(NowGame.NodeToTreeView);
                }
                TestTB.Text = Hint;
                NowGame.QuoridorEva.ThisChessBoard.DrawNowChessBoard(ref Gr, ChessWhitePB, ChessBlackPB);
                ChessBoardPB.Refresh();
                #region 更新状态提示界面
                if (NowPlayer == EnumNowPlayer.Player1)
                {
                    ActionPlayerLabel.Text = "白子";
                    BlackBoardNumLB.Text   = NowGame.QuoridorEva.ThisChessBoard.NumPlayer2Board.ToString();
                    WhiteBoardNumLB.Text   = NowGame.QuoridorEva.ThisChessBoard.NumPlayer1Board.ToString();
                }
                if (NowPlayer == EnumNowPlayer.Player2)
                {
                    ActionPlayerLabel.Text = "黑子";
                    BlackBoardNumLB.Text   = NowGame.QuoridorEva.ThisChessBoard.NumPlayer2Board.ToString();
                    WhiteBoardNumLB.Text   = NowGame.QuoridorEva.ThisChessBoard.NumPlayer1Board.ToString();
                }
                #endregion
            }
        }
示例#14
0
        /// <summary>
        /// 重启A*寻路,最短路径保存在Player1MinRoad或Player2MinRoad中,返回最短路径长度
        /// </summary>
        /// <param name="Player">寻路玩家</param>
        /// <param name="Location_row">该玩家所在位置行</param>
        /// <param name="Location_col">该玩家所在位置列</param>
        /// <returns>最短路径长度</returns>
        public int AstarRestart(ChessBoard ToAstarSearch, EnumNowPlayer Player, int Location_row, int Location_col)
        {
            //bool IfContains = false;
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start(); //  开始监视代码运行时间
            /***************待测代码段****************/

            //int TableSearchResult = 0;
            //string BoardHashCode = LookupRoadAlgorithm.ResultSaveTable.GetHashCode_String(
            //    ToAstarSearch, Player);
            //if (ResultSaveTable.Search(BoardHashCode, ref TableSearchResult))
            //{
            //    Console.WriteLine("此局面已在存储表中!K值:" + BoardHashCode + "V值:" + TableSearchResult.ToString());
            //    /***************待测代码段****************/
            //    stopwatch.Stop(); //  停止监视
            //    TimeSpan timespan = stopwatch.Elapsed; //  获取当前实例测量得出的总时间
            //    Console.WriteLine("存储表命中寻路用时:" + timespan.TotalMilliseconds.ToString() + "ms");
            //    //return TableSearchResult;
            //    IfContains = true;
            //}
            //else
            //{
            //    /***************待测代码段****************/
            //    stopwatch.Stop(); //  停止监视
            //    TimeSpan timespan2 = stopwatch.Elapsed; //  获取当前实例测量得出的总时间
            //    Console.WriteLine("存储表查询费时:" + timespan2.TotalMilliseconds.ToString() + "ms");
            //}
            //stopwatch.Restart();
            /***************待测代码段****************/

            Min_DistanceLength = 999;
            List <AstarList> InitAList = new List <AstarList>();

            Astar_Stop = false;

            AstarList InitGrid = new AstarList(6, 0, 6, Location_row, Location_col);

            InitAList.Add(InitGrid);

            int distance = LookupRoad_Astar(ToAstarSearch, Player, InitGrid, 1,
                                            new List <AstarList>(), InitAList);

            /***************待测代码段****************/
            stopwatch.Stop();                       //  停止监视
            TimeSpan timespan3 = stopwatch.Elapsed; //  获取当前实例测量得出的总时间

            if (QuoridorEvalution.AIRunTime.Astar_s == 0)
            {
                QuoridorEvalution.AIRunTime.Astar_s = timespan3.TotalMilliseconds;
            }
            else
            {
                QuoridorEvalution.AIRunTime.Astar_s += timespan3.TotalMilliseconds;
                QuoridorEvalution.AIRunTime.Astar_s /= 2;
            }
            QuoridorEvalution.AIRunTime.AstarNum++;

            //if (!IfContains)
            //    LookupRoadAlgorithm.ResultSaveTable.Add(BoardHashCode, Min_DistanceLength);

            return(Min_DistanceLength);
        }
示例#15
0
        /// <summary>
        /// 寻找路径长度——贪婪方法
        /// </summary>
        /// <param name="Player"></param>
        /// <param name="Location_row"></param>
        /// <param name="Location_col"></param>
        /// <returns></returns>
        public int LookupRoad_Greedy(ChessBoard ThisChessBoard, EnumNowPlayer Player, int Location_row, int Location_col, List <Point> MovedPoint)
        {
            int Row_Destination = 0;

            #region 设置目的地行
            switch (Player)
            {
            case EnumNowPlayer.Player1:
                Row_Destination = 6;
                break;

            case EnumNowPlayer.Player2:
                Row_Destination = 0;
                break;

            default:
                break;
            }
            #endregion
            #region   扫描是否有木板,用来减少搜索空间
            bool flag_NoBoard      = true;
            bool flag_UpNowBoard   = true;
            bool flag_DownNowBoard = true;

            for (int i = Location_row + 1; i <= Row_Destination; i++)//下扫
            {
                if (ThisChessBoard.ChessBoardAll[i, Location_col].IfUpBoard)
                {
                    flag_DownNowBoard = false;
                    break;
                }
            }
            for (int i = Location_row - 1; i >= Row_Destination; i--)//上扫
            {
                if (ThisChessBoard.ChessBoardAll[i + 1, Location_col].IfUpBoard)
                {
                    flag_UpNowBoard = false;
                    break;
                }
            }
            if (flag_DownNowBoard && flag_UpNowBoard)
            {
                flag_NoBoard = true;
            }
            else
            {
                flag_NoBoard = false;
            }

            if (flag_NoBoard)
            {
                return(Math.Abs((Row_Destination - Location_row)));
            }

            #endregion
            #region 检查四周能移动的位置添加进P_List_Enable列表
            //计算四周能移动的位置的距离
            List <Point> P_List_Enable = new List <Point>();
            //左
            if (Location_col > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfLeftBoard) &&
                !MovedPoint.Contains(new Point(Location_row, Location_col - 1)))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col - 1));
            }
            //右
            if (Location_col < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col + 1].IfLeftBoard) &&
                !MovedPoint.Contains(new Point(Location_row, Location_col + 1)))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col + 1));
            }
            //上
            if (Location_row > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfUpBoard) &&
                !MovedPoint.Contains(new Point(Location_row - 1, Location_col)))
            {
                P_List_Enable.Add(new Point(Location_row - 1, Location_col));
            }
            //下
            if (Location_row < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row + 1, Location_col].IfUpBoard) &&
                !MovedPoint.Contains(new Point(Location_row + 1, Location_col)))
            {
                P_List_Enable.Add(new Point(Location_row + 1, Location_col));
            }
            if (P_List_Enable.Count == 0)
            {
                return(999);
            }
            #endregion

            #region 搜索树搜索策略——贪婪
            int[] P_Dis    = new int[P_List_Enable.Count];
            int   mindis   = 999;
            int   minindex = 0;
            //选择距离最近的点尝试
            for (int i = 0; i < P_List_Enable.Count; i++)
            {
                P_Dis[i] = CalDistance(ThisChessBoard, Player, P_List_Enable[i].X, P_List_Enable[i].Y);
                if (P_Dis[i] < mindis)
                {
                    mindis   = P_Dis[i];
                    minindex = i;
                }
            }

            MovedPoint.Add(new Point(P_List_Enable[minindex].X, P_List_Enable[minindex].Y));
            int dissum  = 0;
            int disbuff = LookupRoad_Greedy(ThisChessBoard, Player, P_List_Enable[minindex].X, P_List_Enable[minindex].Y, MovedPoint);

            #endregion

            if (disbuff != 999)
            {
                dissum += disbuff;
                return(dissum);
            }

            return(999);
        }
示例#16
0
        /// <summary>
        /// A*寻路,最短路径保存在Player1MinRoad或Player2MinRoad中,返回最短路径长度
        /// </summary>
        /// <param name="Player">寻路玩家</param>
        /// <param name="NowGrid">当前寻路的格子</param>
        /// <param name="num_renew">迭代次数</param>
        /// <param name="OpenList">Open列表</param>
        /// <param name="CloseList">Close列表</param>
        /// <returns></returns>
        public int LookupRoad_Astar(ChessBoard ThisChessBoard, EnumNowPlayer Player, AstarList NowGrid, int num_renew, List <AstarList> OpenList, List <AstarList> CloseList)
        {
            int Location_row = NowGrid.Grid_row;
            int Location_col = NowGrid.Grid_col;

            if (Astar_Stop == true)
            {
                return(Min_DistanceLength);
            }

            int Row_Destination = 0;

            #region 设置目的地行
            switch (Player)
            {
            case EnumNowPlayer.Player1:
                Row_Destination = 6;
                break;

            case EnumNowPlayer.Player2:
                Row_Destination = 0;
                break;

            default:
                break;
            }
            #endregion

            #region 检查四周能移动的位置添加进P_List_Enable列表
            //计算四周能移动的位置的距离
            List <Point> P_List_Enable = new List <Point>();
            //左
            if (Location_col > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfLeftBoard))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col - 1));
            }
            //右
            if (Location_col < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col + 1].IfLeftBoard))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col + 1));
            }
            //上
            if (Location_row > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfUpBoard))
            {
                P_List_Enable.Add(new Point(Location_row - 1, Location_col));
            }
            //下
            if (Location_row < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row + 1, Location_col].IfUpBoard))
            {
                P_List_Enable.Add(new Point(Location_row + 1, Location_col));
            }
            #endregion

            #region   扫描是否有木板,用来减少搜索空间
            bool flag_NoBoard      = true;
            bool flag_UpNowBoard   = true;
            bool flag_DownNowBoard = true;

            for (int k = Location_row + 1; k <= Row_Destination; k++)//下扫
            {
                if (ThisChessBoard.ChessBoardAll[k, Location_col].IfUpBoard)
                {
                    flag_DownNowBoard = false;
                    break;
                }
            }
            for (int k = Location_row - 1; k >= Row_Destination; k--)//上扫
            {
                if (ThisChessBoard.ChessBoardAll[k + 1, Location_col].IfUpBoard)
                {
                    flag_UpNowBoard = false;
                    break;
                }
            }
            if (flag_DownNowBoard && flag_UpNowBoard)
            {
                flag_NoBoard = true;
            }
            else
            {
                flag_NoBoard = false;
            }

            if (flag_NoBoard)
            {
                Astar_Stop         = true;
                Min_DistanceLength = Math.Abs((Row_Destination - Location_row)) + CloseList.Last().G;

                #region 迭代寻找最短路径
                List <Point> MinRoad;
                if (Player == EnumNowPlayer.Player1)
                {
                    Player1MinRoad = new List <Point>();
                    MinRoad        = Player1MinRoad;
                }
                else
                {
                    Player2MinRoad = new List <Point>();
                    MinRoad        = Player2MinRoad;
                }

                if (Location_row < Row_Destination)
                {
                    for (int i = Row_Destination; i >= Location_row; i--)
                    {
                        MinRoad.Add(new Point(i, Location_col));
                    }
                }
                else
                {
                    for (int i = Row_Destination; i <= Location_row; i++)
                    {
                        MinRoad.Add(new Point(i, Location_col));
                    }
                }
                AstarList ALBuff = CloseList.Last();
                while (true)
                {
                    if (ALBuff.Father != null)
                    {
                        MinRoad.Add(new Point(ALBuff.Father.Grid_row, ALBuff.Father.Grid_col));
                        ALBuff = ALBuff.Father;
                    }
                    else
                    {
                        break;
                    }
                }
                #endregion
                return(Min_DistanceLength);
            }

            #endregion

            #region 搜索树搜索策略——A*算法
            List <int> P_Dis = new List <int>();
            for (int i = 0; i < P_List_Enable.Count; i++)
            {
                P_Dis.Add(999);
            }
            int minF     = 9999;
            int minindex = 0;
            for (int i = 0; i < P_List_Enable.Count && i >= 0; i++)
            {
                int Hbuff = Math.Abs(P_List_Enable[i].X - Row_Destination);
                P_Dis[i] = Hbuff;
                int  Gbuff        = num_renew;
                int  Fbuff        = Hbuff + Gbuff;
                bool flag_InClose = false;
                //检测是否在Close列表里
                for (int j = 0; j < CloseList.Count; j++)
                {
                    if (P_List_Enable[i].X == CloseList[j].Grid_row && P_List_Enable[i].Y == CloseList[j].Grid_col)
                    {
                        P_List_Enable.Remove(P_List_Enable[i]);
                        P_Dis.Remove(P_Dis[i]);
                        i--;
                        flag_InClose = true;
                        break;
                    }
                }
                if (flag_InClose)
                {
                    continue;
                }

                bool flag_InOpen = false;
                //检测是否在Open列表里
                for (int j = 0; j < OpenList.Count; j++)
                {
                    if (P_List_Enable[i].X == OpenList[j].Grid_row && P_List_Enable[i].Y == OpenList[j].Grid_col)
                    {
                        P_List_Enable.Remove(P_List_Enable[i]);
                        P_Dis.Remove(P_Dis[i]);
                        i--;
                        flag_InOpen = true;

                        if (Gbuff < OpenList[j].G)
                        {
                            OpenList[j].G      = Gbuff;
                            OpenList[j].F      = Fbuff;
                            OpenList[j].H      = Hbuff;
                            OpenList[j].Father = NowGrid;
                        }
                        break;
                    }
                }

                if (!flag_InOpen && !flag_InClose)
                {
                    AstarList NewGrid = new AstarList(Hbuff, Gbuff, Fbuff, P_List_Enable[i].X, P_List_Enable[i].Y);
                    NewGrid.Father = NowGrid;
                    OpenList.Add(NewGrid);
                }
            }
            AstarList MinFGrid = new AstarList(-1, -1, -1, -1, -1);
            for (int i = 0; i < OpenList.Count; i++)
            {
                int Fbuff = OpenList[i].F;
                if (Fbuff < minF)
                {
                    minF     = Fbuff;
                    minindex = i;
                    MinFGrid = OpenList[i];
                }
            }
            CloseList.Add(MinFGrid);

            int dislengthbuff = 0;
            if (MinFGrid.Grid_row == Row_Destination && Astar_Stop == false)
            {
                Min_DistanceLength += MinFGrid.G;
                Astar_Stop          = true;
                return(Min_DistanceLength);
            }
            else
            {
                if (OpenList.Count > 0)
                {
                    OpenList.Remove(MinFGrid);
                    dislengthbuff = LookupRoad_Astar(ThisChessBoard, Player, MinFGrid, MinFGrid.G + 1, OpenList, CloseList);
                }
                else
                {
                    return(999);
                }
            }
            #endregion

            return(dislengthbuff);
        }