Javascript 阿尔法-贝塔国际象棋引擎搜索算法未正确移动

Javascript 阿尔法-贝塔国际象棋引擎搜索算法未正确移动,javascript,algorithm,exponential,alpha-beta-pruning,Javascript,Algorithm,Exponential,Alpha Beta Pruning,我成功地实现了minimax算法,并且正在寻找Alpha-Beta的改进 目前,这两种算法在搜索深度为3+的情况下都需要花费相当长的时间,然而minimax可以工作,Alpa-Beta正在做出非常可怕的动作。下面的算法基于在中找到的伪代码 当前位置的强度 算法:chessjs.move(m)移动。chessjs.undo()就是它。 var得分=0,最佳移动; 函数alphaBetaMax(alpha、beta、depthleft){ 如果(depthleft==0){ 返回计算位置强度();

我成功地实现了minimax算法,并且正在寻找Alpha-Beta的改进

目前,这两种算法在搜索深度为3+的情况下都需要花费相当长的时间,然而minimax可以工作,Alpa-Beta正在做出非常可怕的动作。下面的算法基于在中找到的伪代码

当前位置的强度 算法:chessjs.move(m)移动。chessjs.undo()就是它。
var得分=0,最佳移动;
函数alphaBetaMax(alpha、beta、depthleft){
如果(depthleft==0){
返回计算位置强度();
}
chessjs.moves().forEach(函数(move){
棋子移动(移动);
分数=α-β-氨基(α,β,深度-1);
chessjs.undo();
如果(分数>=beta){
返回beta;//失败硬beta截止
}
如果(分数>α){
最佳移动=移动;
alpha=分数;//alpha的行为类似于MiniMax中的max
}
});
返回α;
}
功能性α-β-氨基(α,β,depthleft){
如果(depthleft==0){
return-计算位置强度();
}
chessjs.moves().forEach(函数(move){
棋子移动(移动);
分数=αβmax(α、β、深度-1);
chessjs.undo();

如果(score代码中的
calculatePositionStrength()
非常琐碎,而且对于机器人游戏的任何AI算法来说,它都是代码的核心和灵魂。如果您的权重不正确,您甚至无法想象您的代码会产生(甚至接近)最佳移动。现在,在游戏中的每一步,棋子相等,你的计算会说,位置相等,但事实并非如此

现在,例如,国际象棋中有大量的攻击开口,在这些开口中,一方放弃材料以获得位置(称为Gambit)。在这种情况下,你的引擎会说该方的位置较弱,但事实并非如此

可以在重量计算函数中包括以下内容:

  • 是的,当然,材料强度是最重要的因素之一
  • 任何一方可能占据的方块数。例如,f3上的骑士可能占据8个空方块中的任何一个(h2、h4、d2、d4、g1、g5、e1、e5)
  • 几乎所有的棋子都有可能在棋盘的中心比两边更坚固。因此,你也可以在棋盘上分配一些重量
  • 此外,如果你正在制作一个国际象棋引擎,我建议你拥有一个数据库,其中包括最常见的开场白、位置牺牲和结束游戏
  • 同样,你的体重必须考虑战术,如发现的攻击,PIN,串,叉,这一切都是可能的,考虑点2。< /LI>
最后,祝你在开发一个伟大的国际象棋引擎方面好运

编辑:我没有看到你问题的第二部分。我想说,可能alpha-beta剪枝不能剪掉它应该剪掉的边缘,因为权重分布不明显。如果你实现更好的权重计算功能,这也应该会有所改进。此外,alpha-beta剪枝在游戏树深度较大时效果很好。在small-depth树,alpha-beta和min-max之间的性能差异几乎不可见。所以,若您将树的深度增加到6,即使使用基本实现,性能差异也应该是可见的

编辑2:几个链接:


EDIT3:深度3的意思是,你移动一步,你的对手移动一步,然后你移动一步。举个例子。你的主教在c1,骑士在d2,敌人的兵在d5,敌人的骑士在h6。你移动一步,Ne6。对手移动一步,兵拿骑士。你移动一步,主教拿骑士。现在,在下一步,如果h6上的敌人骑士有任何棋子支撑(典当/主教等)你的主教走了,但那是移动4,你的位置计算功能无法理解。根据它,这是一个平等的交易。比如说,在接下来的3个移动中没有移动顺序给你任何材料上的优势,所以,这个移动顺序很可能被选中,你说这是一个愚蠢的移动(obvs它是),但这里不怪你的alpha-beta删减。现在,如果选择了Nf6,你的骑士就死定了,下一步,又是一个新的棋盘和新的局面。所以,如果你试图理解,你会的。我在这里就不说了。

只是猜测,但你的评估函数可能太基本,无法指导搜索空间删减-大多数时候我都是这样做的t将计算为0或与前一个板位中的值相同。它所做的只是比较工件材料,目前没有其他操作。我将在1和0之间添加一个随机加法,看看它是否有差异……更新:无差异和M加法b/w 1和0??这在js中如何工作?在计算位置强度时,this公式是obvs非常简单的。
Math.random()
用于区分位置强度,允许切断某些值。我刚刚启动国际象棋引擎,因此公式实际上非常小。这不行。比如说,这会给错误的移动带来更大的值,然后,即使在区分时,也会选择错误的移动。我在考虑逻辑的情况下编写了一个答案部分。这并不能真正回答为什么阿尔法-贝塔会做出愚蠢的动作/速度慢的问题。位置强度目前非常简单,因为我昨天才开始,并将在搜索算法工作后研究实施更好的方法。事实上,这确实是。再次阅读第一段,最后一段也是。所谓愚蠢的动作,我的意思是pu毫无理由地在火线前跳到。它没有敌人的感觉,而min-max算法有。如果你能发布代码,而不是仅仅在一段中写下你的意见,我将不胜感激。此外,将深度增加到6的建议永远不会起作用,因为我首先需要让算法工作。如果我真的这样做的话如果将其增加到6,则需要20分钟才能生成一个
calculatePositionStrength()    //currently very simple
    return (My piece material - opponent's piece material)
var score = 0, bestMove;

function alphaBetaMax(alpha, beta, depthleft) {
    if(depthleft==0) {
        return calculatePositionStrength();
    }
    chessjs.moves().forEach(function(move) {
        chessjs.move(move);
        score = alphaBetaMin(alpha, beta, depthleft-1);
        chessjs.undo();
        if(score>=beta) {
            return beta;   // fail hard beta-cutoff
        }
        if(score>alpha) {
            bestMove = move;
            alpha = score; // alpha acts like max in MiniMax
        }
    });
    return alpha;
}

function alphaBetaMin(alpha, beta, depthleft) {
    if(depthleft==0) {
        return -calculatePositionStrength();
    }
    chessjs.moves().forEach(function(move) {
        chessjs.move(move);
        score = alphaBetaMax(alpha, beta, depthleft-1);
        chessjs.undo();
        if(score<=alpha ) {
            return alpha; // fail hard alpha-cutoff
        }
        if(score<beta ) {
            beta = score; // beta acts like min in MiniMax
        }
    });
    return beta;
}
alphaBetaMax(-Infinity, Infinity, 3);