3D Tic Tac Toe 使用 Minimax 和 Alpha-beta 剪枝选择次优移动

我正在尝试为3D Tic Tac Toe游戏实现Minimax与Alpha-beta剪枝。然而,看起来算法选择了次优路径。

例如,你可以通过直接穿过立方体的中间或在一个平面上横穿来获胜。但AI似乎选择了在下一步而不是当前步骤中最优的单元格。

我尝试重新创建并调整我为算法返回的启发式方法,但没有取得太大进展。不管是哪一层,它似乎都有同样的问题。

代码在这里:这里

相关的部分是computers_movethink_ahead(以及’2’变体,这些只是我在尝试一种略有不同的方法)。

我希望这可能是我忽略了什么简单的东西,但据我所知,我不确定问题出在哪里。如果有人能解释这个问题,我将非常感激。

def computers_move2(self):    best_score = -1000    best_move = None    h = None    win = False    for move in self.allowed_moves:        self.move(move, self.ai)        if self.complete:            win = True            break        else:            h = self.think_ahead2(self.human, -1000, 1000)        self.depth_count = 0        if h >= best_score:            best_score = h            best_move = move            self.undo_move(move)        else:            self.undo_move(move)    if not win:        self.move(best_move, self.ai)    self.human_turn = Truedef think_ahead2(self, player, a, b):    if self.depth_count <= self.difficulty:        self.depth_count += 1        if player == self.ai:            h = None            for move in self.allowed_moves:                self.move(move, player)                if self.complete:                    self.undo_move(move)                    return 1000                else:                    h = self.think_ahead2(self.human, a, b)                    if h > a:                        a = h                        self.undo_move(move)                    else:                        self.undo_move(move)                if a >= b:                    break            return a        else:            h = None            for move in self.allowed_moves:                self.move(move, player)                if self.complete:                    self.undo_move(move)                    return -1000                else:                    h = self.think_ahead2(self.ai, a, b)                    if h < b:                        b = h                        self.undo_move(move)                    else:                        self.undo_move(move)                if a >= b:                    break            return b    else:        diff = self.check_available(self.ai) - self.check_available(self.human)        return diff

回答:

结果发现我的算法似乎运行正常。问题是由我的辅助函数moveundo_move引起的。此外,根源问题在于我的允许移动集合。

我注意到在探索树时,computer_plays中最外层循环的移动数量急剧减少。即使在第一次扫描中,计算机和人类玩家每对回合的允许移动数量也会从总共27个减少到20个,然后是10个,最终是5个。

结果发现临时测试的移动没有被替换。所以我用标准列表替换了集合,并在每次移动/撤销后对列表进行排序,完全解决了我的问题。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注