当前位置: 首页 > 知识库问答 >
问题:

在国际象棋中使用Zobrist转置表

耿招
2023-03-14

我正在尝试将转置表放入我的阿尔法β侦察兵中。我确实看到了一个增量速度提升,我认为是在游戏中期或后期,然而,即使有1-2GB的桌子大小,它可能会也可能不会比根本不从转置表中读取慢。我还注意到,如果我在没有桌子的情况下玩完全相同的游戏,一些效率较低的动作。

我测试了我的Zobrist键散列,即使在进行和撤消操作后,它们也会正常显示。我不相信它们是问题所在。我试图遵循这些文章中的建议来设计alpha/beta修剪。http://web.archive.org/web/20070809015843/http://www.seanet.com/~brucemo/topics/hashing.htmhttp://mediocrechess.blogspot.com/2007/01/guide-transposition-tables.html

有人能帮我找出一个错误吗?也许我不理解从哈希中检查alpha和beta的评估。还是1-2GB太小而无法发挥作用?如果需要,我可以发布更多的转位表代码。

    // !!!! With or without this specific section, and any other Transpose.Insert, doesn't make the game play or evaluate any faster.
    HashType type = HashType.AlphaPrune;
    HashEntry h = Transpose.GetInstance().Get(board.zobristKey);
    if (h != null)
    {
        if (h.depth >= depth)
        {
            if (h.flag == HashType.ExactPrune)
            {
                return h.scored;
            }
            if (h.flag == HashType.BetaPrune)
            {
                if(h.scoredState < beta)
                {
                    beta = h.scored;
                }
            }
            if (h.flag == HashType.AlphaPrune)
            {
                if(h.scoredState > alpha)
                {
                    alpha = h.scored;
                }
            }
            if (alpha >= beta)
            {
                return alpha;
            }
        }
    }

    if (board.terminal)
    {
        int scoredState = board.Evaluate(color);
        Table.GetInstance().Add(board.zobristKey, depth, Entry.EXACT, scoredState);
        return scoredState;
    }

    //May do Quescience search here if necessary && depth = 0

    Stack movesGenerated = GeneratePossibleMoves();
    while(!movesGenerated.isEmpty())
    {
        int scoredState = MAXNEGASCOUT;

        board.MakeMove(movesGenerated.pop());
        int newAlpha = -(alpha +1)
        scoredState = -alphaBetaScout(board, depth - 1, newAlpha, -alpha, !color, quiscence);

        if (scoredState < beta && alpha < scoredState)
        {
            scoredState = -alphaBetaScout(board, depth - 1, -beta, -scoredState, !color, quiscence);
        }

        board.UndoMove();

        if (scoredState >= beta)
        {
            Table.GetInstance().Add(key, depth, Entry.BETA, beta);
            return scoredState;
        }

        if (scoredState > alpha)
        {
            type = HashType.ExactPrune;
            alpha = scoredState;
        }
    }
    Table.GetInstance().Add(key, depth, type, alpha);
    return alpha;

共有1个答案

孙成益
2023-03-14

我相信在一开始搜索表格之前,您需要复制您的 alpha 和 beta 边界。当您更新边界(使用表格或通过搜索)时,这些副本不会更改。

然后,当您将新条目添加到换位表中时,您应该将scoredState与表中保存的边界(即,开始时创建的边界的副本)进行比较,而不是将其与更新的边界进行比较,因为更新的边界不是表中存储的边界,而是备份的边界!

 类似资料:
  • DreamChess 是一款开放源码、跨平台(可在 Windows、Mac OS X 及 Linux 上运行)的 3D 国际象棋游戏。该游戏包含自身的引擎 Dreamer,提供各种国际象棋棋盘,并具有背景音乐及声效等其他附属功能。

  • 我已经有一个Board对象,包含一个碎片列表。Piece是一个抽象类,有一个位置(x,y)和一个颜色(黑色或白色)。然后是King、Queen、Knight这三个类,实现了Piece类。 谢谢

  • 问题内容: 我正在计划制作一个与UCI国际象棋引擎接口的程序。我一直在对此进行一些研究,但是我想在获得更多信息之前获得更多的信息。我想知道你们中是否有人可以提供一些UCI引擎和前端程序之间的“交换”示例。我并不在乎实用的接口代码(例如发送/接收命令),这应该足够简单。我只是想获得一些小游戏的好例子和一些选择。我目前正在使用Stockfish引擎,但是我希望能够使用多个引擎。 因此,无论如何,我正在

  • 上面的代码显示了一个可以上下移动的部分的示例。这不是一个有效的棋步。所以,如果我要移动一个皇后,我该怎么做呢?我们只是假设我们已经有了一个矩阵(x,y)8×8的板。

  • 我正在下国际象棋,除了一件事,我几乎得到了所有的东西:我需要使棋手不可能将棋子移动到棋盘上。我很难解决这个问题。 我现在用伪代码生成的有效移动是:类getMoveLocations(我定义了一个位置为国际象棋中的一个方块):如果这个位置在边界内,这个位置的棋子是敌人的棋子,并且模拟的移动不会导致棋盘被检查,然后将该位置添加到工件可以移动到的可能位置。 问题是我如何检查棋盘是否“在检查中”。在我的代

  • 我正在创建一个国际象棋游戏,现在我已经用所有棋子填充了我的图形棋盘,现在我需要使用鼠标滑动器来移动棋子。在实现图形版本之前,我创建了一个2D控制台版本,它采用了“玩家移动”,所以我有所有这些方法,但我现在需要使用Mouselistener,我阅读了这些方法,但是,我需要在每个类中实现Mouselistener吗? 我有1个抽象工件类和7个子类(包括虚拟工件),还有一个棋盘类,它填充所有工件,并提供