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

四子棋中等难度CPU代码出现TypeError:int与NoneType无法比较

四子棋代码TypeError错误排查与修复

我开发的四子棋代码中,drop_piece函数用于检查列是否已满,其他辅助函数负责检测获胜条件,cpu_player_easy实现随机落子,draw_checker检测平局。运行测试用例时持续报错:TypeError: '<=' not supported between instances of 'int' and 'NoneType',代码如下:

import random
def drop_piece(board, player, column): #(start, stop, end)
    for row in range(5, -1, -1): #iterates and starts at 5 and makes it's way up the row by taking away 1 till it gets to the top and which would have a -1
           if board[row][column - 1] == 0: #makes sure that the column directly below does not have a token on it
                board[row][column - 1] = player 
                return True
    else:
        return False    



def cpu_player_easy(board, player):
  while True:
    column = random.randint(1,7)
    if drop_piece(board, player, column): ## calls on this function and says if that's true then return the columns
      return column

def vertical_Win():
    for row in range(0,3):  
        for column in range(0,7):
            if board[row][column] == board[row + 1][column] == board[row + 2][column] == board[row + 3][column] and board[row][column] != 0:    
                if board[row][column] == 1:
                    return column

def horizontal_Win():
    for row in range(6):    
        for column in range(1, 4):
            if board[row][column] == board[row][column + 1] == board[row][column + 2] == board[row][column + 3] and board[row][column] != 0:    
                if board[row][column] == 1:
                    return column
                else:
                    return None

def diagonal_Win_TL_To_BR():
    for row in range(3):    
        for column in range(1 , 4):
            if board[row][column - 1] == board[row + 1][column - 0] == board[row + 2][column + 1] == board[row + 3][column + 2] and board[row][column - 1] != 0:
                if board[row][column - 1] == 1:
                    return column
                else:
                    return None

def diagonal_Win_Tr_To_BL():
    for row in range(0,3): ## from top to bottom
        for column in range(3, 7): ## from left to right
            if board[row][column] == board[row + 1][column - 1] == board[row + 2][column - 2] == board[row + 3][column - 3] and board[row][column] != 0:
                if board[row][column] == 1:
                    return column
                else:
                    return None

def draw_checker(board):
    for row in range(0,6):
        for column in range(0,7):
            if board[row][column] == 0:
                return None
        
def create_board():
 number_of_rows = 6
 number_of_columns = 7
 arr_2d =[] ##this is the 2d array which we will store the zeroes in.
 for x in range(number_of_rows):## responsible for the rows
   column_elements = [] ## empty list that will hold the elements of the current row
   for y in range(number_of_columns):## responsible for the columns
     column_elements.append(0)
   arr_2d.append(column_elements)## appends the column_elements list to the "arr_2d" list representing a new row in the 2d array
 return arr_2d


def cpu_player_medium(board, player):
    """
    Executes a move for the CPU on medium difficulty.
    It first checks for an immediate win and plays that move if possible. 
    If no immediate win is possible, it checks for an immediate win 
    for the opponent and blocks that move. If neither of these are 
    possible, it plays a random move.

    :param board: The game board, 2D list of 6x7 dimensions.
    :param player: The player whose turn it is, integer value of 1 or 2.
    :return: Column that the piece was dropped into, int.
    """
    while draw_checker(board) == False:
        if vertical_Win() or horizontal_Win() or diagonal_Win_TL_To_BR() or diagonal_Win_Tr_To_BL():
            return column
        else:
            cpu_player_easy(board, player)

错误根源分析

  1. 获胜检测函数未接收board参数
    所有vertical_Win、horizontal_Win等函数都未将board作为参数传入,而是依赖全局变量。如果测试环境中没有定义全局board,或者变量未正确赋值,会导致函数内部的board为None,后续数组索引和值比较操作就会触发类型错误。

  2. draw_checker返回逻辑错误
    该函数找到空位时返回None,全满时无明确返回值(默认返回None)。但cpu_player_medium中用draw_checker(board) == False判断,None == False结果为False,导致循环逻辑失效,后续代码处理None值时引发错误。

  3. cpu_player_medium函数逻辑漏洞

    • 调用获胜检测函数时未传入board参数;
    • 直接返回未定义的column变量,会引发NameError;
    • 调用cpu_player_easy后未返回其结果,导致函数可能返回None,后续若将该返回值与整数比较就会触发TypeError。
  4. 获胜检测函数返回值不一致
    部分函数在非玩家1获胜时返回None,无获胜情况时也默认返回None,导致后续判断时拿到None值,与整数比较时触发类型错误。

修复方案

1. 修正获胜检测函数,传入board参数并统一返回逻辑

将所有获胜检测函数添加board参数,统一无获胜时返回None,获胜时返回用户视角的列号(1-7):

def vertical_Win(board):
    for row in range(0,3):  
        for column in range(0,7):
            if board[row][column] == board[row + 1][column] == board[row + 2][column] == board[row + 3][column] and board[row][column] != 0:    
                return column + 1  # 转换为1-7的列号
    return None

def horizontal_Win(board):
    for row in range(6):    
        for column in range(0, 4):  # 修正列范围,避免索引越界
            if board[row][column] == board[row][column + 1] == board[row][column + 2] == board[row][column + 3] and board[row][column] != 0:    
                return column + 1
    return None

def diagonal_Win_TL_To_BR(board):
    for row in range(3):    
        for column in range(0, 4):
            if board[row][column] == board[row + 1][column + 1] == board[row + 2][column + 2] == board[row + 3][column + 3] and board[row][column] != 0:
                return column + 1
    return None

def diagonal_Win_Tr_To_BL(board):
    for row in range(3): 
        for column in range(3, 7): 
            if board[row][column] == board[row + 1][column - 1] == board[row + 2][column - 2] == board[row + 3][column - 3] and board[row][column] != 0:
                return column + 1
    return None

2. 修复draw_checker的返回逻辑

明确返回布尔值,True表示平局,False表示还有空位:

def draw_checker(board):
    for row in range(6):
        for column in range(7):
            if board[row][column] == 0:
                return False  # 存在空位,不是平局
    return True  # 棋盘全满,平局

3. 重构cpu_player_medium函数逻辑

实现“先找自己的获胜点,再堵对手的获胜点,最后随机落子”的逻辑,同时修复参数传递和返回值问题:

def cpu_player_medium(board, player):
    opponent = 2 if player == 1 else 1

    # 检查自身是否有立即获胜的落子
    for col in range(1, 8):
        # 创建棋盘副本模拟落子
        temp_board = [row.copy() for row in board]
        if drop_piece(temp_board, player, col):
            # 检测模拟落子后是否获胜
            if vertical_Win(temp_board) or horizontal_Win(temp_board) or diagonal_Win_TL_To_BR(temp_board) or diagonal_Win_Tr_To_BL(temp_board):
                drop_piece(board, player, col)
                return col

    # 检查对手是否有立即获胜的落子,进行阻挡
    for col in range(1, 8):
        temp_board = [row.copy() for row in board]
        if drop_piece(temp_board, opponent, col):
            if vertical_Win(temp_board) or horizontal_Win(temp_board) or diagonal_Win_TL_To_BR(temp_board) or diagonal_Win_Tr_To_BL(temp_board):
                drop_piece(board, player, col)
                return col

    # 无获胜或阻挡机会,执行随机落子
    return cpu_player_easy(board, player)

内容的提问来源于stack exchange,提问作者j1400

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:52:33