public List <MoveSequence> AlphaBetaRecursive(Board board, int depth, bool isWhite) { var sw = System.Diagnostics.Stopwatch.StartNew(); var result = new List <MoveSequence>(); _numberOfLeafEvaluations = 0; _numberOfBranchesPruned = 0; MoveSequence alpha = new MoveSequence { Value = float.NegativeInfinity }; MoveSequence beta = new MoveSequence { Value = float.PositiveInfinity }; board.RecalculateScore(); var moves = board.GetMovesForPlayer(isWhite ? EnumBoardSquare.White : EnumBoardSquare.Black); if (isWhite) { moves = moves.OrderByDescending(x => x.ScoreChange).ToArray(); } else { moves = moves.OrderBy(x => x.ScoreChange).ToArray(); } foreach (var move in moves) { var scoreChange = AlphaBetaRecursive(board, move, depth - 1, alpha, beta, !isWhite); result.Add(scoreChange); } //Parallel.ForEach(moves, (Move move) => //{ // var scoreChange = AlphaBetaRecursive(board, move, depth - 1, alpha, beta, !isWhite); // lock (_lock) // { // result.Add(scoreChange); // } //}); _durationMilliseconds = sw.ElapsedMilliseconds; if (isWhite) { return(Shuffle(result).OrderByDescending(x => x.Value).ToList()); } else { return(Shuffle(result).OrderBy(x => x.Value).ToList()); } }
private MoveSequence AlphaBetaRecursive(Board previousBoard, Move move, int depth, MoveSequence alpha, MoveSequence beta, bool isWhite) { if (depth == 0 || (move.PieceCaptured & EnumBoardSquare.King) == EnumBoardSquare.King) { _numberOfLeafEvaluations++; return(new MoveSequence { Value = previousBoard.Score + move.ScoreChange, Move = move, NextMove = null }); } if (isWhite) { Board board = previousBoard.MakeMove(move); var moves = board.GetMovesForPlayer(EnumBoardSquare.White); Array.Sort(moves, (x, y) => y.ScoreChange.CompareTo(x.ScoreChange)); for (int i = 0; i < moves.Length; i++) { if (_boardStates.TryGetValue(board.GetHashCode(), out var info) && info.SearchDepth == depth) { if (alpha.Value < info.Value) { if (info.Value >= beta.Value) { _numberOfBranchesPruned++; return(beta); } else { alpha = new MoveSequence { Move = move, Value = info.Value, NextMove = null }; } } } else { var moveSequence = AlphaBetaRecursive(board, moves[i], depth - 1, alpha, beta, false); if (alpha.Value < moveSequence.Value) { if (moveSequence.Value >= beta.Value) { _numberOfBranchesPruned++; return(beta); } else { alpha = new MoveSequence { Move = move, Value = moveSequence.Value, NextMove = moveSequence }; } } lock (_lock) { if (!_boardStates.ContainsKey(board.GetHashCode())) { _boardStates.Add(board.GetHashCode(), new BoardStateInfo { SearchDepth = depth, Value = moveSequence.Value }); } } } } return(alpha); } else { Board board = previousBoard.MakeMove(move); var moves = board.GetMovesForPlayer(EnumBoardSquare.Black); Array.Sort(moves, (x, y) => x.ScoreChange.CompareTo(y.ScoreChange)); for (int i = 0; i < moves.Length; i++) { if (_boardStates.TryGetValue(board.GetHashCode(), out var info) && info.SearchDepth == depth) { if (info.Value < beta.Value) { if (alpha.Value >= info.Value) { _numberOfBranchesPruned++; return(alpha); } else { beta = new MoveSequence { Move = move, Value = info.Value, NextMove = null }; } } } else { var moveSequence = AlphaBetaRecursive(board, moves[i], depth - 1, alpha, beta, true); if (moveSequence.Value < beta.Value) { if (alpha.Value >= moveSequence.Value) { _numberOfBranchesPruned++; return(alpha); } else { beta = new MoveSequence { Move = move, Value = moveSequence.Value, NextMove = moveSequence }; } } lock (_lock) { if (!_boardStates.ContainsKey(board.GetHashCode())) { _boardStates.Add(board.GetHashCode(), new BoardStateInfo { SearchDepth = moveSequence.Length, Value = moveSequence.Value }); } } } } return(beta); } }