/// <summary> /// Máy tính đi nước đi tốt nhất /// </summary> private void DoBestStep() { List <int[]> list = board.GetEnableSteps(Board.WHITE); int j = 0; int max = -Int32.MaxValue; int valueboard = 0; int difficulty = Convert.ToInt32(numericUpDown1.Value); // Bản chất minimax là heuristic của bàn cờ phe địch sao cho bàn cờ phe địch đó là tệ nhất trong các bàn cờ tốt nhất của phe địch . // Căn cứ vào đó ta đánh nước cờ làm cho phe địch tổn thất nhất . // tính xem ứng với mỗi nước đi của quân trắng(máy) thì quân đen(người) sẽ đi nước đi nào tốt nhất , // căn cứ vào giá trị minimax trả về ta chọn ra nước đi của quân trắng(máy) khiến quân đen(người) khó thắng nhất . for (int i = 0; i < list.Count; i++) { //Sở dĩ phải giả định các bàn cờ sau khi đi nước cờ của máy vì bàn cờ của ta lưu dưới dạng ma trận ,cần phải tìm ô tốt nhất để quân cờ di chuyển vào đó . Board copyboard1 = board.Copy(); copyboard1.Move(list[i][0], list[i][1], Board.WHITE, true); int res = Board.GetBestStep(Board.WHITE, -Int32.MaxValue, Int32.MaxValue, difficulty, true, copyboard1); //int res = Board.GetBestStep(Board.BLACK, -Int32.MaxValue, Int32.MaxValue, difficulty, false, copyboard1); if (max < res) { j = i; max = res; } } if (list.Count > j) // TH khác xảy ra là list.Count = j = 0 , khi này máy tính mất lượt . { Undo_Point.Push(new tuple(list[j][0], list[j][1])); board.Move(list[j][0], list[j][1], Board.WHITE, true); valueboard = board.GetValue(); board.X_Pre = list[j][0]; board.Y_Pre = list[j][1]; } Invoke(new EnableTimerDelegate(EnableTimer), false); Invoke(new InvokeShowGrade(ShowGrade), valueboard.ToString()); try { Invoke(new InvokeAdd(InsertToTable), list, j); } catch { Invoke(new ShowMessageDelegate(ShowMessage), "Máy tính mất lượt", "Mất lượt" , MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Minimax kết hợp alpha-beta /// </summary> /// <param name="piece"></param> /// <param name="alpha"></param> /// <param name="beta"></param> /// <param name="depth"></param> /// <param name="MAX"></param> /// <param name="board"></param> /// <returns></returns> public static int GetBestStep(int piece, int alpha, int beta, int depth, bool MAX, Board board) { if (depth == 0 || board.WhiteCount + board.BlackCount == 64) { return(board.GetValue()); } // List các nước đi có thể xảy ra List <int[]> EnableStepsList; if (piece == WHITE) { EnableStepsList = board.GetEnableSteps(BLACK);// <---------------- } else { EnableStepsList = board.GetEnableSteps(WHITE);// <---------------- } if (EnableStepsList.Count == 0 && MAX == true) { return(-Int32.MaxValue); } if (MAX == true) { int value = -Int32.MaxValue; foreach (int[] s in EnableStepsList) { Board boardcopy = board.Copy(); if (piece == WHITE) { boardcopy.Move(s[0], s[1], BLACK, true); } else { boardcopy.Move(s[0], s[1], WHITE, true); } value = Math.Max(value, GetBestStep(-piece, alpha, beta, depth - 1, false, boardcopy)); alpha = Math.Max(alpha, value); if (alpha >= beta) { break; } } return(value); } else { int value = Int32.MaxValue; foreach (int[] s in EnableStepsList) { Board boardcopy = board.Copy(); if (piece == WHITE) { boardcopy.Move(s[0], s[1], BLACK, true); } else { boardcopy.Move(s[0], s[1], WHITE, true); } value = Math.Min(value, GetBestStep(piece, alpha, beta, depth - 1, true, boardcopy)); beta = Math.Min(beta, value); if (alpha >= beta) { break; } } return(value); } }
/// <summary> /// Tìm nước đi tốt nhất (MiniMax) /// </summary> /// <param name="piece"></param> /// <param name="alpha"></param> /// <param name="depth">Độ sâu</param> /// <param name="board"></param> /// <param name="panel"></param> /// <returns></returns> public static int GetBestStep(int piece, int alpha, int depth, int difficulty, Board board, Panel panel) { // Giới hạn độ sâu if (depth > difficulty || board.WhiteCount + board.BlackCount == 64) { int k = board.GetValue(); return k; } // List các nước đi có thể xảy ra List<int[]> EnableStepsList = board.GetEnableSteps(piece); if (EnableStepsList.Count == 0 && piece == WHITE) return -Int32.MaxValue; int bestvalue = Int32.MaxValue; foreach (int[] s in EnableStepsList) { if (AlphaBetaPruning(alpha, bestvalue, depth)) { return alpha; } Board boardcopy = board.Copy(); boardcopy.Move(s[1], s[0], piece, true); // đệ quy tiếp, tăng độ sâu lên 1 int cur_value = GetBestStep(-piece, alpha, depth + 1, difficulty, boardcopy, panel); bestvalue = MinMaxValue(cur_value, -bestvalue, depth); } return bestvalue; }