private Int32 RunRecursive(ChessBoard myBoard, Int16 depth, ChessPiece turn) { List<ChessMove> moves = myBoard.GetAllMoves(turn); if (moves.Count == 0) { if (turn == this.MySuit) { // I am mated or stale mated return this.Board.InCheck(turn) ? -WonScore : StaleMateScore; } else { // Opponent is mated or stale mated return this.Board.InCheck(turn) ? WonScore : StaleMateScore; } } Int32 evaluation; Int32 bestEvaluation = LowestScore; ChessPiece capturedChessPiece; foreach (ChessMove move in moves) { myBoard.DoMove(move, out capturedChessPiece); if (depth > 1) { // Pre evaluation to determine cut evaluation = TryGetCachedEvaluation(myBoard, 1, () => { return Evaluate(myBoard, turn, depth); }); if (evaluation > this.CutLimit) { myBoard.UndoMove(move, capturedChessPiece); return evaluation; } // Full evaluation evaluation = TryGetCachedEvaluation(myBoard, depth, () => { return -RunRecursive(myBoard, (short)(depth - 1), turn == ChessPiece.White ? ChessPiece.Black : ChessPiece.White); }); } else { evaluation = TryGetCachedEvaluation(myBoard, depth, () => { return Evaluate(myBoard, turn, depth); }); } if (evaluation > bestEvaluation) { bestEvaluation = evaluation; } myBoard.UndoMove(move, capturedChessPiece); } return bestEvaluation; }
private Int32 RunRecursive(ChessBoard myBoard, Int16 depth, ChessPiece turn, Int32 alpha, Int32 beta, bool maximizingPlayer) { if (depth == 0) { return TryGetCachedEvaluation(myBoard, 0, () => { return Evaluate(myBoard, turn, 0); }); } List<ChessMove> moves = myBoard.GetAllMoves(turn); ChessPiece capturedChessPiece; Int32 evaluation; if (maximizingPlayer) { evaluation = Int32.MinValue; foreach (var move in moves) { myBoard.DoMove(move, out capturedChessPiece); int logPos = GetLogPos(); var e = TryGetCachedEvaluation(myBoard, depth, () => { return RunRecursive(myBoard, (short)(depth - 1), turn == ChessPiece.White ? ChessPiece.Black : ChessPiece.White, alpha, beta, false); }); evaluation = Math.Max(evaluation, e); Log(depth, "<m t=\"max\" d=\"" + (this.MaxDepth-depth) +"\" m=\"" + move.ToString() + "\" e=\"" + e + "\">", logPos); Log(depth, "</m>"); myBoard.UndoMove(move, capturedChessPiece); if (evaluation > alpha) { Log(depth, "<a>" + evaluation + " gt " + alpha + "</a>"); } alpha = Math.Max(alpha, evaluation); if (beta <= alpha) { Log(depth, "<c>" + beta + " lte " + alpha + "</c>"); break; } } } else { evaluation = Int32.MaxValue; foreach (var move in moves) { myBoard.DoMove(move, out capturedChessPiece); int logPos = GetLogPos(); var e = TryGetCachedEvaluation(myBoard, depth, () => { return RunRecursive(myBoard, (short)(depth - 1), turn == ChessPiece.White ? ChessPiece.Black : ChessPiece.White, alpha, beta, true); }); evaluation = Math.Min(evaluation, e); Log(depth, "<m t=\"min\" d=\"" + (this.MaxDepth - depth) + "\" m=\"" + move.ToString() + "\" e=\"" + e + "\">", logPos); Log(depth, "</m>"); myBoard.UndoMove(move, capturedChessPiece); if (evaluation < beta) { Log(depth, "<b>" + evaluation + " lt " + beta + "</b>"); } beta = Math.Min(beta, evaluation); if (beta <= alpha) { Log(depth, "<c>" + beta + " lte " + alpha + "</c>"); break; } } } return evaluation; }