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

国际象棋阿尔法贝塔向棋盘返回错误的移动

谷梁弘深
2023-03-14

我试图实现一个带有alpha beta修剪的国际象棋游戏。以下几乎可以工作,但它返回错误的动作。

例如,可以出现以下情况。

白色(用户)移动,白色国王位置-a1/黑色(计算机),黑色国王位置-h1

白色从a1-a2移动其国王,然后黑色返回移动g2-g1???

计算机似乎返回了错误节点的移动(电路板表示),就好像给定电路板位置的最佳评估没有一直传播到树的后面。因此,在探索的一个模拟位置中,计算机“想象”它的国王移动到g2,然后返回从该位置进行的移动,没有意识到该位置是模拟位置,而不是实际电路板(根节点?)的表示。

如何更正代码以使计算机返回实际董事会表示的移动,而不是错误的模拟之一?

非常感谢。

初始调用alphaBeta(3,ChessEngine.invertBoard(ChessEngine.board),-10000,10000,true)

private static int alphaBetaEvaluate = 0;
private static int alphaBetaSelectedSquare = 0;
private static int alphaBetaMoveToSquare = 0;
public static int alphaBeta(int depth, char[] board, int alpha, int beta, boolean maxPlayer) {

    //create a copy of the board
    char[] boardCopy = board.clone();

    //if terminal state has not been met, keep searching
    if (maxPlayer == true && depth > 0) {

        //for all of the moves that max can make
        for (int i = 0; i < board.length; i++) {
            for (int move : ChessEngine.getValidMoves(i, boardCopy)) {

                //make the move
                boardCopy[move] = boardCopy[i];
                boardCopy[i] = '.';

                alphaBetaEvaluate = rating(board, boardCopy, i, move);

                //store the best move to make
                int temp = alphaBeta(--depth, ChessEngine.invertBoard(boardCopy), -10000, 10000, false);
                if (temp > alpha) {
                    alphaBetaSelectedSquare = i;
                    alphaBetaMoveToSquare = move;           
                    alpha = temp;
                }

                //reset the board for the next simulated move
                boardCopy = board.clone();

                if (beta <= alpha) {
                    break;
                }
            }
        }
        return alpha;
    } else if (maxPlayer == false && depth > 0) {

        //for all of the moves that min can make
        for (int i = 0; i < board.length; i++) {
            for (int move : ChessEngine.getValidMoves(i, boardCopy)) {

                //make the move
                boardCopy[move] = boardCopy[i];
                boardCopy[i] = '.';
                beta = Math.min(beta, alphaBeta(--depth, ChessEngine.invertBoard(boardCopy), -10000, 10000, true));

                //reset the board for the next simulated move
                boardCopy = board.clone();

                if (beta <= alpha) {
                    break;
                }
            }
        }
        return beta;
    }
    return alphaBetaEvaluate;
}

共有1个答案

太叔涵亮
2023-03-14

我还是不明白你的想法。首先,你要做的是创建一棵树。一个决策树,并将决策向上传播。你想最大限度地提高你的评估,同时也希望敌人会选择降低你评估的招式作为回报。

所以,对我来说,反转电路板听起来不太合理,除非你知道你对情况的评估是正确的。

对我来说,另一个严重的问题是,你总是在下一步调用最小/最大值,用-10k和10k作为alpha和beta的边界。这样你的算法就不会从之前的动作中“学习”。

你需要的是再次检查算法(例如,我使用的维基百科),看看它们使用的是阿尔法和贝塔法,并根据之前的评估进行了修改。这样,在更高深度的计算可以首先停止,然后更好地评估最佳移动。

我不是这方面的专家。几十年前,当我编写我的实现时,我使用了一些不同的东西。

另一个想法是不要在同一个方法中使用min和max,而是使用min和max方法。这让你更有可能发现其他缺陷。

也不要使用两个国王进行评估。这是没有目标的。两个国王是随机的,不可能赢。有一件事可能是两个骑士或四个皇后之类的。这并不是随机的,你可以看到皇后们在跳舞,却无法抓住对方。或者用三个骑士对抗一个女王。

试着围绕其他部分为自己创建一些单元测试。只是为了确保零件能够独立正常工作。你为什么要使用角色?为什么不使用枚举或对象呢。可以为每个字段重用对象(更像是各种图形)。

但无论如何,这是风格,而不是算法正确性。

 类似资料:
  • 我对我的象棋游戏的最小极大算法的实现有问题。它的大部分似乎都起作用了,但它要么从来没有做出好的动作,要么对它们的评估(基于两个玩家的活动棋子的分数)出了问题。例如,如果我设置了check(例如,傻瓜的伴侣),ai会做一些随机的事情,而不是杀死国王。我真的找不出我做错了什么。 评估电路板的类StandardBoardEvaluator在经过一些测试后似乎可以工作,因此问题很可能出现在MiniMax实

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

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

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

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

  • 本文向大家介绍python输出国际象棋棋盘的实例分享,包括了python输出国际象棋棋盘的实例分享的使用技巧和注意事项,需要的朋友参考一下 国际象棋是当今国际上最流行的智力体育运动项目。青年人下棋可以锻炼思维、增强记忆力和培养坚强的意志;中年人下棋可以享受美学;老年下棋可以很好的休息娱乐。国际象棋游戏有自己的规则,需要两个人将棋子落在棋盘上。 棋子落在棋盘上事件,在计算机看来,是一段程序,而这些程