Beispiel #1
0
        private MoveNode GetMoveNodeMaxDepth(Color color, ChessBoard board, Move move, float baseValue)
        {
            var node = new MoveNode
            {
                Children = null,
                Move     = move
            };

            var boardCopy = board.CopyWithMove(move);

            var cacheKey = new EvalCacheKey(boardCopy.GetFenString());

            if (boardEvalCache.ContainsKey(cacheKey))
            {
                node.Score = boardEvalCache[cacheKey];
            }
            else
            {
                var score = boardEvaluator.EvaluateBoard(boardCopy, color) - baseValue;

                if (!boardEvalCache.ContainsKey(cacheKey))
                {
                    boardEvalCache.TryAdd(cacheKey, score);
                    cacheChanged = true;
                }

                node.Score = score;
            }

            return(node);
        }
Beispiel #2
0
        private MoveNode CreateRootMoveNode(Color color, ChessBoard board, Move baseMove)
        {
            float baseValue = boardEvaluator.EvaluateBoard(board, color);

            var node = new MoveNode
            {
                Move = baseMove
            };

            var boardWithMove = board.CopyWithMove(node.Move);
            var cacheKey      = new EvalCacheKey(boardWithMove.GetFenString());

            if (boardWithMove.Winner.HasWinner)
            {
                float score = boardEvaluator.EvaluateBoard(board.CopyWithMove(node.Move), color);
                boardEvalCache.TryAdd(cacheKey, score);
                node.Score     = score;
                winFoundOnRoot = true;
                return(node);
            }

            if (boardEvalCache.ContainsKey(cacheKey))
            {
                node.Score = boardEvalCache[cacheKey];
            }
            else
            {
                node.Children = BuildMoveTreeForColor(ChessBoard.InvertColor(color), color, board.CopyWithMove(baseMove), 2, baseValue);
            }

            if (node.Children == null || !node.Children.Any())
            {
                cacheKey = new EvalCacheKey(board.CopyWithMove(node.Move).GetFenString());

                if (boardEvalCache.ContainsKey(cacheKey))
                {
                    node.Score = boardEvalCache[cacheKey];
                }
                else
                {
                    float score = boardEvaluator.EvaluateBoard(board.CopyWithMove(node.Move), color);
                    boardEvalCache.TryAdd(cacheKey, score);
                    cacheChanged = true;
                    node.Score   = score;
                }
            }
            else
            {
                node.Score = node.GetWorstChild();
            }

            return(node);
        }
Beispiel #3
0
        private List <MoveNode> BuildMoveTreeForColor(Color color, Color originalColor, ChessBoard board, int currentLevel, float baseValue)
        {
            if (winFoundOnRoot)
            {
                return(new List <MoveNode>());
            }

            if (currentLevel > maxDepth)
            {
                return(null);
            }

            var nodes = new List <MoveNode>();

            var cacheKey = new EvalCacheKey(board.GetFenString());

            var initScore = boardEvaluator.EvaluateBoard(board, originalColor);

            if (initScore - baseValue <= -4)
            {
                nodes.Add(new MoveNode
                {
                    Score    = initScore - baseValue,
                    Children = null
                });
                return(nodes);
            }

            if (boardEvalCache.ContainsKey(cacheKey))
            {
                return(new List <MoveNode>
                {
                    new MoveNode
                    {
                        Score = boardEvalCache[cacheKey] - baseValue,
                        Children = null
                    }
                });
            }

            foreach (var move in board.GetAllAvailableMoves(color))
            {
                if (winFoundOnRoot)
                {
                    return(new List <MoveNode>());
                }

                if (currentLevel == maxDepth)
                {
                    var node = GetMoveNodeMaxDepth(color, board, move, baseValue);

                    nodes.Add(node);
                }
                else
                {
                    var chessBoard = board.CopyWithMove(move);

                    float testScore = boardEvaluator.EvaluateBoard(board.CopyWithMove(move), originalColor);
                    boardEvalCache.TryAdd(cacheKey, testScore);

                    var node = new MoveNode
                    {
                        Children = BuildMoveTreeForColor(ChessBoard.InvertColor(color), originalColor, chessBoard, currentLevel + 1, baseValue),
                        Move     = move
                    };

                    if (node.Children.Any())
                    {
                        node.Score = color == originalColor?node.GetWorstChild() : node.GetBestChild();
                    }
                    else
                    {
                        cacheKey = new EvalCacheKey(board.GetFenString());

                        if (boardEvalCache.ContainsKey(cacheKey))
                        {
                            node.Score = boardEvalCache[cacheKey] - baseValue;
                        }
                        else
                        {
                            var score = boardEvaluator.EvaluateBoard(chessBoard.CopyWithMove(move), originalColor);

                            if (!boardEvalCache.ContainsKey(cacheKey))
                            {
                                boardEvalCache.TryAdd(cacheKey, score);
                                cacheChanged = true;
                            }

                            node.Score = score - baseValue;
                        }
                    }

                    nodes.Add(node);
                }
            }

            return(nodes);
        }