Example #1
0
        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());
            }
        }
Example #2
0
        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);
            }
        }