protected override int[] CheckClickPos() { if (ChessBoard.Instance.ChessStack.Count == 0) { int[] pos = new int[2]; // 随机一个位置(-2是为了避免太靠近边界,有可能使对方太过容易赢得比赛) pos[0] = Random.Range(2, ChessBoard.Max_LINE - 2); pos[1] = Random.Range(2, ChessBoard.Max_LINE - 2); return(pos); } else { AILevelNode maxNode = null; int[,] temGrid = (int[, ])ChessBoard.Instance.GetGrid(); foreach (AILevelNode child in GetChildList(temGrid, true, ChessType)) { // 创建树 子节点为非自己,所以用false; // 每个grid都为独立不同的方案,为了不影响独立的grid,所以Clone(); CreateTree(child, (int[, ])temGrid.Clone(), false, DeepCount); child.score += DoAlphBeta(child, false, DeepCount, float.MinValue, float.MaxValue); if (maxNode == null) { maxNode = child; } else { if (maxNode.score < child.score) { maxNode = child; } } } return(maxNode.pos); } }
// 剪枝 private float DoAlphBeta(AILevelNode node, bool isSelf, int deep, float alpha, float beta) { if (deep == 0 || node.score == float.MaxValue || node.score == float.MinValue) { return(node.score); } //alpha剪枝 if (isSelf) { foreach (AILevelNode child in node.child) { alpha = Mathf.Max(alpha, DoAlphBeta(child, !isSelf, deep - 1, alpha, beta)); // "="的情况下有可能出现更差的结果,所以也直接return; if (alpha >= beta) { return(alpha); } } return(alpha); } // beta剪枝 else { foreach (AILevelNode child in node.child) { beta = Mathf.Min(beta, DoAlphBeta(child, !isSelf, deep - 1, alpha, beta)); if (alpha >= beta) { return(beta); } } return(beta); } }
// 创建树 private void CreateTree(AILevelNode node, int[,] grid, bool isSelf, int deep) { if (deep == 0 || node.score == float.MaxValue) { return; } // 设置当前点填充到地图上 grid[node.pos[0], node.pos[1]] = (int)node.chessType; node.child = GetChildList(grid, !isSelf, node.chessType); foreach (AILevelNode child in node.child) { // 创建下一级的节点,Clone()避免修改父节点的grid数据 CreateTree(child, (int[, ])grid.Clone(), !isSelf, deep - 1); } }
// 获取当前受益值最大或者最小Node列表 private List <AILevelNode> GetChildList(int[,] grid, bool isSelf, GameDefine.ChessType type) { List <AILevelNode> temList = new List <AILevelNode>(); AILevelNode node; // 获取三个极大或极小的子节点child; for (int i = 0; i < ChessBoard.Max_LINE; i++) { for (int j = 0; j < ChessBoard.Max_LINE; j++) { if (grid[i, j] != (int)GameDefine.DotType.NONE) { continue; } int[] pos = new int[2] { i, j }; node = new AILevelNode(); node.chessType = type; node.pos = pos; // 获取当前点的得分 if (isSelf) { // 最大分(当前位置的初始score = 白+黑的得分) node.score = (GetMaxScore(grid, pos, GameDefine.ChessType.Black) + GetMaxScore(grid, pos, GameDefine.ChessType.White)); } else { // 最小分 负号可取得最小值的点 node.score = (-GetMaxScore(grid, pos, GameDefine.ChessType.Black) - GetMaxScore(grid, pos, GameDefine.ChessType.White)); } // 取出极大极小点 if (temList.Count < 4) { temList.Add(node); } else { foreach (AILevelNode temNode in temList) { if (isSelf) { if (temNode.score < node.score) { temList.Remove(temNode); temList.Add(node); break; } } else { if (temNode.score > node.score) { temList.Remove(temNode); temList.Add(node); break; } } } } } } return(temList); }