Esempio n. 1
0
    int Search(FastBoardNode node, int searchDepth, int plyFromRoot, int alpha, int beta, int color)
    {
        if (searchDepth == 0)
        {
            using (diagnostics.quiescence.Measure())
                return(QuiescenceSearch(node, plyFromRoot, alpha, beta, color));
        }

        List <FastMove> moves;

        using (diagnostics.moveGen.Measure())
        {
            moves = moveCache[searchDepth];
            moves.Clear();
            node.AddAllPossibleMoves(moves, node.currentMove);
        }

        evaluationData.Prepare(node);

        using (diagnostics.moveSort.Measure())
        {
            OrderMoves(node, moves, plyFromRoot);
        }

        bool isTerminal = true;
        int  value      = int.MinValue;

        foreach (var move in moves)
        {
            if (cancellationRequested)
            {
                return(0);
            }

            using (diagnostics.apply.Measure())
                node.DoMove(move);

            bool isKingVulnerable;
            using (diagnostics.moveValidate.Measure())
                isKingVulnerable = node.IsChecking(node.currentMove);

            if (isKingVulnerable)
            {
                diagnostics.invalidMoves++;
                using (diagnostics.apply.Measure())
                    node.UndoMove(move);
                continue;
            }

            isTerminal = false;
            int currentValue = -Search(node, searchDepth - 1, plyFromRoot + 1, -beta, -alpha, -color);

            if (previousOrderingEnabled && plyFromRoot == 0)
            {
                previousScores[move] = currentValue;
            }

            using (diagnostics.apply.Measure())
                node.UndoMove(move);

            if (currentValue > value)
            {
                if (plyFromRoot == 0)
                {
                    bestMoveThisIteration = move;
                }
                value = currentValue;
            }
            alpha = Math.Max(alpha, value);
            if (alpha >= beta)
            {
                diagnostics.searchCutoff++;
                break;
            }
        }

        if (isTerminal)
        {
            value = color * EvaluateTerminalBoard(node, plyFromRoot);
        }

        return(value);
    }
Esempio n. 2
0
    int QuiescenceSearch(FastBoardNode node, int plyFromRoot, int alpha, int beta, int color)
    {
        int eval;

        evaluationData.Prepare(node);

        using (diagnostics.quiescenceEval.Measure())
            eval = color * EvaluateBoard(node, plyFromRoot);

        if (!quiescenceSearchEnabled)
        {
            return(eval);
        }

        if (eval >= beta)
        {
            diagnostics.quiescenceCutoff++;
            return(beta);
        }

        if (eval > alpha)
        {
            alpha = eval;
        }

        List <FastMove> moves;

        using (diagnostics.quiescenceMoveGen.Measure())
        {
            moves = new List <FastMove>(10);
            node.AddAllPossibleMoves(moves, node.currentMove, generateQuiet: false);
        }

        using (diagnostics.quiescenceMoveSort.Measure())
            OrderMoves(node, moves, -1);

        bool maybeTerminal = true;
        int  value         = int.MinValue;

        foreach (var move in moves)
        {
            if (cancellationRequested)
            {
                return(0);
            }

            using (diagnostics.quiescenceApply.Measure())
                node.DoMove(move);

            bool isKingVulnerable;
            using (diagnostics.quiescenceMoveValidate.Measure())
                isKingVulnerable = node.IsChecking(node.currentMove);
            if (isKingVulnerable)
            {
                diagnostics.invalidMoves++;
                using (diagnostics.quiescenceApply.Measure())
                    node.UndoMove(move);
                continue;
            }

            maybeTerminal = false;
            int currentValue = -QuiescenceSearch(node, plyFromRoot + 1, -beta, -alpha, -color);

            using (diagnostics.quiescenceApply.Measure())
                node.UndoMove(move);

            if (currentValue > value)
            {
                value = currentValue;
            }
            alpha = Math.Max(alpha, value);
            if (alpha >= beta)
            {
                diagnostics.quiescenceCutoff++;
                break;
            }
        }

        // No non-quiet moves were found from this position
        if (maybeTerminal)
        {
            return(eval);
        }

        return(value);
    }