c# - 国际象棋静止搜索过于广泛

标签 c# algorithm chess alpha-beta-pruning

上个月,我一直在使用 C# 创建一个简单的国际象棋引擎,并取得了一些不错的进展。它使用简单的 Alpha-Beta 算法。

为了纠正地平线效应,我尝试实现静止搜索(但在成功之前失败了几次)。发动机的强度似乎因此提高了一点安静,但速度非常慢!

以前,我可以在大约 160 秒内搜索到 6 层深度(处于游戏中期状态的某个位置),使用静态搜索,计算机需要大约 80 秒才能在搜索深度 3 上移动!

暴力节点计数器在深度 3 处大约有 20000 个节点,而静态节点计数器高达 2000 万!

由于这是我的第一个国际象棋引擎,我真的不知道这些数字是否正常,或者我是否在我的静止算法中犯了错误。如果更有经验的人能告诉我 BF 节点/静态节点的通常比率是多少,我将不胜感激。

顺便说一句,只是为了看看: (只要searchdepth为0,BF树就会调用该方法)

public static int QuiescentValue(chessBoard Board, int Alpha, int Beta)
    {
        QuiescentNodes++;

        int MinMax = Board.WhoseMove; // 1 = maximierend, -1 = minimierend
        int Counter = 0;
        int maxCount;


        int tempValue = 0;
        int currentAlpha = Alpha;
        int currentBeta = Beta;
        int QuietWorth = chEvaluation.Evaluate(Board);

        if(MinMax == 1) //Max
        {
            if (QuietWorth >= currentBeta)
                return currentBeta;
            if (QuietWorth > currentAlpha)
                currentAlpha = QuietWorth;
        }

        else            //Min
        {
            if (QuietWorth <= currentAlpha)
                return currentAlpha;
            if (QuietWorth < currentBeta)
                currentBeta = QuietWorth;
        }




        List<chMove> HitMoves = GetAllHitMoves(Board);
        maxCount = HitMoves.Count;

        if(maxCount == 0)
            return chEvaluation.Evaluate(Board);


        chessBoard tempBoard;

        while (Counter < maxCount)
        {
            tempBoard = new chessBoard(Board);
            tempBoard.Move(HitMoves[Counter]);
            tempValue = QuiescentValue(tempBoard, currentAlpha, currentBeta);

            if (MinMax == 1) //maximierend
            {
                if (tempValue >= currentBeta)
                {
                    return currentBeta;
                }

                if (tempValue > currentAlpha)
                {
                    currentAlpha = tempValue;
                }

            }

            else            //minimierend
            {
                if (tempValue <= currentAlpha)
                {
                    return currentAlpha;
                }
                if (tempValue < currentBeta)
                {
                    currentBeta = tempValue;
                }
            }

            Counter++;
        }

        if (MinMax == 1)
            return currentAlpha;
        else
            return currentBeta;

    }

最佳答案

我不熟悉英文术语 - HitMove 是从棋盘上移除棋子的移动吗?

在那种情况下,在我看来,您可以使用 GetAllHitMoves 来获取静态搜索的“嘈杂” Action 列表,然后对这些 Action 进行比通常的 3 或 6 层更进一步的评估。不过,这是递归调用的,所以只要有可能的 HitMoves 剩余,你就会一遍又一遍地评估它。限制您的静态搜索应该可以解决您的性能问题。

至于选择静态搜索的限制 - wiki 状态:

Modern chess engines may search certain moves up to 2 or 3 times deeper than the minimum.

关于c# - 国际象棋静止搜索过于广泛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31145659/

相关文章:

c - 我试图制作绘制 8x8 chesstable 的 c 数组。请帮帮我吗?

java - 如何实现 JOptionpane 列表选项?

c# - Interlocked.Decrement(i) 适合 Parallel.ForEach() 吗?

c# - 如何在 C# 中将文本转换为超链接?

c# - 在 C# 中将小数或字符串转换为货币的最佳方法?

c - C 中的回溯

c++ - 快速选择 DOM 中的元素

c# - 为什么 .NET 中存在 null?

excel - 获取表格中的重心

java - 如何使用/修改 Knuth-Morris-Pratt 算法将任何给定字符串转换为回文