You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Kivy与Minimax算法的Python井字棋AI无法拦截玩家走子问题求解

问题核心原因及修复方案

排查代码后共发现3个致命逻辑错误直接导致AI无法正常工作:

  • 第一:check_victory 函数未检测行的胜负状态,仅检测了列和对角线,导致AI完全无法识别玩家凑齐行的获胜趋势,自然不会做拦截
  • 第二:max_play 函数生成下一步状态时未对原始棋盘做拷贝,直接修改了遍历用的棋盘状态,导致后续递归逻辑全部错乱
  • 第三:估值函数evaluate的返回值未结合搜索深度,所有获胜/失败场景分值完全相同,导致AI在多个可选走法中只会选择遍历到的第一个,表现出随机落子的规律

具体修改步骤

  1. 修复check_victory函数,补充行胜负检测逻辑,同时将浮点数除法替换为整除避免精度问题:
def check_victory(self, array):
    # 新增行求和检测
    row_sum = np.sum(array, axis=1)
    for r in row_sum:
        if r % 10 == 3:
            return 'Player'
        if r // 10 == 3:
            return 'Computer'
    temp1 = array
    temp2 = np.rot90(array)
    column1 = np.sum(temp1, axis=0)
    column2 = np.sum(temp2, axis=0)
    diagonal1 = np.diag(temp1).sum()
    diagonal2 = np.diag(temp2).sum()
    for i in range(3):
        if column1[i] % 10 == 3 or column2[i] % 10 == 3:
            return 'Player'
        if column1[i] // 10 == 3 or column2[i] // 10 == 3:
            return 'Computer'
    if diagonal1 % 10 == 3 or diagonal2 % 10 == 3:
        return 'Player'
    if diagonal1 // 10 == 3 or diagonal2 // 10 ==3:
        return 'Computer'
    return 'None'
  1. 修复max_play函数的状态拷贝问题,生成克隆棋盘时调用copy()方法:
def max_play(self, game_state, level):
    if self.check_victory(game_state) == 'Computer' or level == 0:
        return self.evaluate(game_state, level)
    moves = self.find_moves(game_state)
    best_score = float('-inf')
    for move in moves:
        # 新增copy()调用,避免修改原棋盘
        clone = self.next_state(game_state.copy(), move[0], move[1], 'Computer')
        score = self.min_play(clone, level - 1)
        if score > best_score:
            best_score = score
    return best_score
  1. 优化evaluate函数,结合搜索深度调整分值,让AI优先选择最快获胜、最慢落败的走法:
def evaluate(self, array, level):
    if self.check_victory(array) == 'Player':
        # 玩家获胜分值为负,深度越小玩家赢的越快,分值越低
        return -10 - level
    if self.check_victory(array) == 'Computer':
        # AI获胜分值为正,深度越小AI赢的越快,分值越高
        return 10 + level
    return 0
  1. 同步修改min_play函数中调用evaluate的参数,传入当前深度:
def min_play(self, game_state, level):
    if self.check_victory(game_state) == 'Player' or level == 0:
        return self.evaluate(game_state, level)
    moves = self.find_moves(game_state)
    best_score = float('inf')
    for move in moves:
        clone = self.next_state(game_state.copy(), move[0], move[1], 'Player')
        score = self.max_play(clone, level - 1)
        if score < best_score:
            best_score = score
    return best_score

修改完成后AI即可正常识别获胜/拦截场景,不会再出现随机落子的问题。

内容的提问来源于stack exchange,提问作者Amir Ben Bassat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:54:04