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)
/// <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(); }
/// <summary> /// 获得开局时的决策 /// </summary> /// <param name="ThisChessBoard">当前棋盘状态</param> /// <returns>下一步决策</returns> public QuoridorAction GetFormulaePolicy(ChessBoard ThisChessBoard) { QuoridorAction NextPolicy = new QuoridorAction(NowAction.Action_Wait, new Point(-1, -1)); string CBString = ChessBoardToString(ThisChessBoard); string LString = ChessBoardLocationToString(ThisChessBoard, PolicyPlayer); if (CBFormulaeList.ContainsKey(CBString))//检测棋盘定式库 { NextPolicy = CBFormulaeList[CBString]; if (NextPolicy.SkipChessScore == 999) { NowGameSituation = GameSituation.PreviousSituation; } } else if (LocationFormulaeList.ContainsKey(LString))//检测位置定式库 { NextPolicy = LocationFormulaeList[LString]; if (NextPolicy.SkipChessScore == 999) { NowGameSituation = GameSituation.PreviousSituation; } } else//直走或者最短路径走 { Point PlayerLocation = ThisChessBoard.Player1Location; if (PolicyPlayer == EnumNowPlayer.Player2) { PlayerLocation = ThisChessBoard.Player2Location; NextPolicy.PlayerAction = NowAction.Action_Move_Player2; NextPolicy.ActionPoint = new Point(PlayerLocation.X - 1, PlayerLocation.Y); } else { NextPolicy.PlayerAction = NowAction.Action_Move_Player1; NextPolicy.ActionPoint = new Point(PlayerLocation.X + 1, PlayerLocation.Y); } string ErrorHint = ""; ErrorHint = NowEvalution.QuoridorRule.CheckMove_NoChange(ThisChessBoard , NextPolicy.ActionPoint.X, NextPolicy.ActionPoint.Y, NextPolicy.PlayerAction); if (ErrorHint != "OK")//只能最短路径走 { List <QuoridorAction> MoveActionList = new List <QuoridorAction>(); NowEvalution.AddMoveAction(ref MoveActionList, ThisChessBoard, PolicyPlayer, PlayerLocation); NowEvalution.ActionListEvaluation(ThisChessBoard, ref MoveActionList, PolicyPlayer, 0, 0, -50); NextPolicy = MoveActionList[0]; } if (CheckInitialSituationEnd(ThisChessBoard)) { NowGameSituation = GameSituation.PreviousSituation; } } FormulaePolicyNum++; return(NextPolicy); }
/// <summary> /// 获得PolicyPlayer下一步的决策 /// </summary> /// <param name="ThisChessBoard">当前局面棋盘</param> /// <param name="RootNode">返回的决策树根节点</param> /// <returns>下一步决策动作</returns> public QuoridorAction GetNextPolicy(ChessBoard ThisChessBoard, out GameTreeNode RootNode) { QuoridorAction NextPolicy = new QuoridorAction(NowAction.Action_Wait, new Point(-1, -1)); RootNode = new GameTreeNode(); RootNode.NodePlayer = NowEvalution.ReversePlayer(PolicyPlayer); int P2Dis = NowEvalution.AstarEngine.AstarRestart(ThisChessBoard, EnumNowPlayer.Player2 , ThisChessBoard.Player2Location.X, ThisChessBoard.Player2Location.Y); int P1Dis = NowEvalution.AstarEngine.AstarRestart(ThisChessBoard, EnumNowPlayer.Player1 , ThisChessBoard.Player1Location.X, ThisChessBoard.Player1Location.Y); RootNode.NodeAction.ActionCheckResult.P1Distance = P1Dis; RootNode.NodeAction.ActionCheckResult.P2Distance = P2Dis; if (UsedAlgorithm == Enum_DecisionAlgorithm.AlphaBetaPurning) { #region 配置AB剪枝参数 QuoridorEvalution.ActionListIfSort = ThisABPurningPara.SortActionList; GameTreeNode.SearchFrameWork = GameTreeNode.Enum_GameTreeSearchFrameWork.AlphaBetaPurning; GameTreeNode.IfUseTanslationTable = ThisABPurningPara.UseTT; GameTreeNode.DepthMax = ThisABPurningPara.DepthMax; RootNode.alpha = ThisABPurningPara.AlphaInit; RootNode.beta = ThisABPurningPara.BetaInit; #endregion if (ThisABPurningPara.UseFormulae && NowGameSituation == GameSituation.InitialSituation) { NextPolicy = GetFormulaePolicy(ThisChessBoard); } else { GameTreeNode.CreateGameTree(PolicyPlayer, RootNode, ThisChessBoard, ThisABPurningPara.DepthMax, false); NextPolicy = RootNode.NodeAction; } } return(NextPolicy); }
public void AddFormulae(Dictionary <string, QuoridorAction> ListToAdd, string FormulaeStr, int ActionNum, bool IfFinish) { QuoridorAction NowActionBuff = new QuoridorAction(NowAction.Action_Wait, new Point(-1, -1)); int ActionIndex = ActionNum / 100; switch (ActionIndex) { case 0: NowActionBuff.PlayerAction = NowAction.Action_PlaceVerticalBoard; break; case 1: NowActionBuff.PlayerAction = NowAction.Action_PlaceHorizontalBoard; break; case 2: NowActionBuff.PlayerAction = NowAction.Action_Move_Player1; break; case 3: NowActionBuff.PlayerAction = NowAction.Action_Move_Player2; break; default: break; } int row = (ActionNum / 10) % 10; int col = ActionNum % 10; NowActionBuff.ActionPoint = new Point(row, col); if (IfFinish) { NowActionBuff.SkipChessScore = 999; } ListToAdd.Add(FormulaeStr, NowActionBuff); }