【问题标题】:Is there a problem with my Negamax implementation?我的 Negamax 实施有问题吗?
【发布时间】:2021-10-07 23:16:44
【问题描述】:

我正在尝试用 Rust 为我的国际象棋引擎编写一个简单的负最大算法。我有一个非常简单的评估函数:

pub fn evaluate(&self) -> i32 {
    let mut eval: i32 = 0;

    for piece_type in PType::PIECE_TYPES {
        eval += (
            self.bitboards[piece_type, Col::White].count_ones() as i32 - 
            self.bitboards[piece_type, Col::Black].count_ones() as i32
        ) * piece_type.value();
    }

    eval
}

这是我的 negamax 实现:

fn negamax(pos: &mut Position, depth: u32, piece_colour: Col) -> i32 {
    let mult = match piece_colour {
        Col::Black => -1,
        Col::White => 1
    };

    if depth == 0 {
        return pos.evaluate() * mult
    }

    let mut best_so_far = -9999;

    let legal_moves = movegen::legal_moves(pos, piece_colour);

    for child in legal_moves {
        pos.make_move(child);
        best_so_far = std::cmp::max(best_so_far, negamax(pos, depth - 1, piece_colour.inverse()));
        pos.unmake_move(child);
    }

    -best_so_far
}

其中很多来自 Negamax 算法的 Wikipedia 伪代码。然而,在深度 5 的以下位置中,为白色生成的最佳着法是 Nxd3,此时应该是 Nb7 来分叉皇后和国王,然后在下一步行动中捕获皇后(是的,我的移动生成器确实考虑了叉子)。

我感觉我的 Negamax 实现有问题,但我不知道在哪里。

【问题讨论】:

    标签: rust chess negamax


    【解决方案1】:

    您遵循的Wikipedia article 中给出的伪代码是错误的:depth == 0depth > 0 之间存在差异。在depth == 0 的情况下,它从当前玩家的角度返回评估。但是对于depth > 0,由于最后的否定,它返回了从另一个玩家的角度来看的评估。当从深度 1 到 0 时,这会导致不正确的结果。

    要解决此问题,应在递归调用之后立即进行否定,而不是在返回时进行。请注意,这是在 alpha-beta 修剪变体的伪代码中完成的方式,看起来是正确的。

    您的代码中还有一些其他问题:

    • 您没有检测到僵局。目前,当没有合法移动时,您返回 -9999(假设您首先进行了上述修复),这可能表明当前玩家已被将死。但另一种可能是僵局,得分应该是 0。
    • 所有“N 位交配”的分数都相同,均为 9999,这意味着 AI 不会急于交配,可能只是重复动作。解决此问题的一种方法是给“N 中的伴侣”评分 9999-N。

    【讨论】:

    • 感谢您的回答!将否定移动到递归调用之后似乎有很大帮助,但是,它现在正在移动 ne6,将 King 和 Rook 分叉,而不是 King 和 Queen(Negamax 评估这两个移动具有相同的分数 @987654326 @)。我很困惑它怎么会知道分叉,但却以某种方式得到了错误的部分。
    • @BenTechy66 在 Nb7、Kc7、Nxa5、Rb4 之后,骑士被困然后被俘虏,导致您的代码认为已将死的僵局。
    • 有趣,你可能是对的。然而,即使在低深度 (d=3) 上,它也会走棋,尽管它不应该看到僵局。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2020-04-16
    相关资源
    最近更新 更多