/// <summary> /// 使用AI放置棋子 /// </summary> /// <param name="gs">游戏状态</param> /// <param name="ef">评价函数</param> public static void PlaceChessAI(GameState gs, EvaluateFunction ef) { IEnumerator <GameState> ie_gs = gs.GetNextSiblingStates(); int x = 0, y = 0; double value = Settings.LOSE_POINT; double temp_value = 0; while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { temp_value = MinMax(ie_gs.Current, Settings.SEARCH_DEPTH - 1, Settings.LOSE_POINT, Settings.WIN_POINT, gs.turn, ef); if (temp_value > value) { x = ie_gs.Current.X; y = ie_gs.Current.Y; value = temp_value; } } } //Debug.WriteLine("{0} {1} {2}", x, y, temp_value); gs.PlaceChess(x, y, gs.NextPlayer()); }
/// <summary> /// MIN_MAX博弈的核心 /// </summary> /// <param name="gs">游戏状态</param> /// <param name="depth">搜素深度</param> /// <param name="min">允许的最小值</param> /// <param name="max">允许的最大值</param> /// <param name="cp">评判的是哪一方</param> /// <param name="ef">可调整的评价函数</param> /// <returns></returns> public static double MinMax(GameState gs, int depth, double min, double max, ChessPiece cp, EvaluateFunction ef) { ChessPiece winner = gs.WhoIsWin(); if (winner == cp) { return Settings.WIN_POINT; } else if (winner == GameState.AnotherPlayer(cp)) { return Settings.LOSE_POINT; } if (depth == 0) { return ef(gs); } double value, temp_value; // 当前为极大节点 if (gs.NextPlayer() == cp) { // 检查其所有子节点 value = min; IEnumerator<GameState> ie_gs = gs.GetNextSiblingStates(); while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { temp_value = MinMax(ie_gs.Current, depth - 1, value, max, cp, ef); // alpha pruning if (temp_value > value) { value = temp_value; } if (value > max) { return max; } } } return value; } // 当前为极小节点 else { // 检查其所有子节点 value = max; IEnumerator<GameState> ie_gs = gs.GetNextSiblingStates(); while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { // beta pruning temp_value = MinMax(ie_gs.Current, depth - 1, min, value, cp, ef); if (temp_value < value) { value = temp_value; } if (value < min) { return min; } } } return value; } }
/// <summary> /// 使用AI放置棋子 /// </summary> /// <param name="gs">游戏状态</param> /// <param name="ef">评价函数</param> public static void PlaceChessAI(GameState gs, EvaluateFunction ef) { IEnumerator<GameState> ie_gs = gs.GetNextSiblingStates(); int x = 0, y = 0; double value = Settings.LOSE_POINT; double temp_value = 0; while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { temp_value = MinMax(ie_gs.Current, Settings.SEARCH_DEPTH - 1, Settings.LOSE_POINT, Settings.WIN_POINT, gs.turn, ef); if (temp_value > value) { x = ie_gs.Current.X; y = ie_gs.Current.Y; value = temp_value; } } } //Debug.WriteLine("{0} {1} {2}", x, y, temp_value); gs.PlaceChess(x, y, gs.NextPlayer()); }
/// <summary> /// MIN_MAX博弈的核心 /// </summary> /// <param name="gs">游戏状态</param> /// <param name="depth">搜素深度</param> /// <param name="min">允许的最小值</param> /// <param name="max">允许的最大值</param> /// <param name="cp">评判的是哪一方</param> /// <param name="ef">可调整的评价函数</param> /// <returns></returns> public static double MinMax(GameState gs, int depth, double min, double max, ChessPiece cp, EvaluateFunction ef) { ChessPiece winner = gs.WhoIsWin(); if (winner == cp) { return(Settings.WIN_POINT); } else if (winner == GameState.AnotherPlayer(cp)) { return(Settings.LOSE_POINT); } if (depth == 0) { return(ef(gs)); } double value, temp_value; // 当前为极大节点 if (gs.NextPlayer() == cp) { // 检查其所有子节点 value = min; IEnumerator <GameState> ie_gs = gs.GetNextSiblingStates(); while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { temp_value = MinMax(ie_gs.Current, depth - 1, value, max, cp, ef); // alpha pruning if (temp_value > value) { value = temp_value; } if (value > max) { return(max); } } } return(value); } // 当前为极小节点 else { // 检查其所有子节点 value = max; IEnumerator <GameState> ie_gs = gs.GetNextSiblingStates(); while (ie_gs.MoveNext()) { if (IsNessarySearch(ie_gs.Current, ie_gs.Current.X, ie_gs.Current.Y)) { // beta pruning temp_value = MinMax(ie_gs.Current, depth - 1, min, value, cp, ef); if (temp_value < value) { value = temp_value; } if (value < min) { return(min); } } } return(value); } }