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

AI井字棋游戏出现TypeError: 'int' object is not callable错误求助

井字棋AI游戏代码错误排查

错误信息

File "C:\Users\dejan\Desktop\pyth programs\TicTackToewAI\main.py", line 102, in miniMax
    temp_board.marked_square(row,col,self.player)
TypeError: 'int' object is not callable

问题描述

我正在开发一款带AI的井字棋游戏,运行代码时触发上述错误,无法定位错误原因,请求帮助排查代码问题。

完整代码

main.py

import copy

import pygame
import numpy as np
import sys
from constance import *
import random
pygame.init()
win=pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("TICK TACK TOE AI")
win.fill(BG_COLOR)
run=True

class Board():
    def__init__(self):
        self.squares=np.zeros((ROWS,COLS))
        self.empty_squares=self.squares
        self.marked_square=0

    def markSquare(self,row,col,player):
        self.squares[row][col]=player
        self.marked_square+=1

    def isFull(self):
        return self.marked_square==9

    def isempty(self):
        return self.marked_square==0


    def emptySquare(self,row,col):
        return self.squares[row][col]==0

    def getEmptySquares(self):
        empty_sqrs=[]
        for row in range(ROWS):
            for col in range(COLS):
                if self.emptySquare(row,col):
                    empty_sqrs.append((row,col))
        return empty_sqrs

    def final_State(self):
        for col in range(COLS):
            if self.squares[0][col]==self.squares[1][col]==self.squares[2][col]!=0:
                return self.squares[0][col]

        for row in range(ROWS):
            if self.squares[row][0] == self.squares[row][1] == self.squares[row][2] != 0:
                return self.squares[row][0]

        if self.squares[0][0]==self.squares[1][1]==self.squares[2][2]:
            return self.squares[1][1]

        if self.squares[2][0] == self.squares[1][1] == self.squares[0][2]:
            return self.squares[1][1]

        return 0


class AI():
    def__init__(self,level=1,player=2):
        self.level=level
        self.player=player

    def rnd_choice(self,board):
        empty_sqrs=board.getEmptySquares()
        idx=random.randrange(0,len(empty_sqrs))
        return empty_sqrs[idx]

    def miniMax(self,board,maximizing):
        case=board.final_State()
        if case==1:
            return 1,None
        if case==2:
            return -1,None
        elif board.isFull():
            return 0,None

        if maximizing:
            max_eval = -100
            best_move = None
            empty_sqrs = board.getEmptySquares()

            for (row, col) in empty_sqrs:
                temp_board = copy.deepcopy(board)
                temp_board.marked_square(row, col,1)
                eval = self.miniMax(temp_board, False)[0]

                if eval > max_eval:
                    max_eval = eval
                    best_move = (row, col)

            return max_eval, best_move

        elif not maximizing:
            min_eval=100
            best_move=None
            empty_sqrs=board.getEmptySquares()

            for (row,col)in empty_sqrs:
                temp_board=copy.deepcopy(board)
                temp_board.marked_square(row,col,self.player)
                eval=self.miniMax(temp_board,True)[0]

                if eval<min_eval:
                    min_eval=eval
                    best_move=(row,col)

            return min_eval,best_move




    def eval(self,main_board):
        if self.level==0:
            eval='random'
            move=self.rnd_choice(main_board)
        else:
           eval,move= self.miniMax(main_board,False)
        print(f'AI has chosen to mark the square in pos{move}witha an eval of{eval}')

        return move

class Game():
    def__init__(self):
        self.board=Board()
        self.ai=AI()
        self.player = 1
        self.gameMode='ai'
        self.running=True
        self.showLines()

    def showLines(self):
        pygame.draw.line(win,LINE_COLOR,(sQSIZE,0),(sQSIZE,HEIGHT),LINE_WIDTH)
        pygame.draw.line(win, LINE_COLOR, (WIDTH-sQSIZE, 0), (WIDTH-sQSIZE, HEIGHT), LINE_WIDTH)
        pygame.draw.line(win, LINE_COLOR, (0, sQSIZE), (WIDTH, sQSIZE), LINE_WIDTH)
        pygame.draw.line(win, LINE_COLOR, (0, HEIGHT-sQSIZE), (WIDTH, HEIGHT-sQSIZE), LINE_WIDTH)

    def drawFig(self,row,col):
        if self.player==1:
            start_desc=(col*sQSIZE+OFFSET,row*sQSIZE+OFFSET)
            end_desc=(col*sQSIZE+sQSIZE-OFFSET,row*sQSIZE+sQSIZE-OFFSET)
            pygame.draw.line(win,CROSS_COLOR,start_desc,end_desc,CROSS_WIDTH)

            start_asc = (col * sQSIZE + OFFSET, row * sQSIZE+sQSIZE -OFFSET)
            end_asc = (col * sQSIZE + sQSIZE - OFFSET, row * sQSIZE + OFFSET)
            pygame.draw.line(win, CROSS_COLOR, start_asc, end_asc, CROSS_WIDTH)

        elif self.player==2:
            center=(col*sQSIZE+sQSIZE//2,row*sQSIZE+sQSIZE//2)
            pygame.draw.circle(win,CIRCLE_COLOR,center,CIRCLE_RADIOUS,CIRCLE_WIDTH)

    def nextTurn(self):
        self.player=self.player%2+1


def main():
    game=Game()
    board=game.board
    ai=game.ai
    while run:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type==pygame.MOUSEBUTTONDOWN:
                pos=event.pos
                row=pos[1]//sQSIZE
                cols=pos[0]//sQSIZE
                if board.emptySquare(row,cols):
                    board.markSquare(row,cols,game.player)
                    game.drawFig(row,cols)
                    game.nextTurn()

        if game.gameMode=='ai' and game.player==ai.player:
            pygame.display.update()
            row,cols=ai.eval(board)
            board.markSquare(row, cols, ai.player)
            game.drawFig(row, cols)
            game.nextTurn()


        pygame.display.update()



main()

constance.py

WIDTH,HEIGHT=600,600

BG_COLOR=(20,170,156)
ROWS=3
COLS=3
sQSIZE=WIDTH//COLS
LINE_COLOR=(23,145,135)
LINE_WIDTH=15

CROSS_COLOR=(66,66,66)
CROSS_WIDTH=20
CIRCLE_COLOR=(239,231,200)

CIRCLE_WIDTH=15
CIRCLE_RADIOUS=sQSIZE//4

OFFSET=50

错误排查与修复

核心错误原因

报错的直接原因是:你在AI.miniMax方法中调用了temp_board.marked_square(row,col,self.player),但marked_square是Board类中用来计数已标记格子数量的整数属性,并非方法。而真正用于标记格子的方法是Board.markSquare(注意驼峰命名和拼写差异)。

修复步骤

  1. 修改main.py中两处错误的方法调用:
    • 第79行:将temp_board.marked_square(row, col,1)改为temp_board.markSquare(row, col,1)
    • 第102行:将temp_board.marked_square(row,col,self.player)改为temp_board.markSquare(row,col,self.player)

其他潜在问题修复

为了避免后续出现其他异常,建议同时修复以下代码细节:

  • Board类和AI类的构造方法缺少空格:将def__init__(self):改为def __init__(self):(两处)
  • Board.final_State方法中,对角线判断逻辑缺少非空校验,修改为:
    if self.squares[0][0]==self.squares[1][1]==self.squares[2][2]!=0:
        return self.squares[1][1]
    
    if self.squares[2][0] == self.squares[1][1] == self.squares[0][2]!=0:
        return self.squares[1][1]
    
  • Board.isempty方法名改为isEmpty,符合Python驼峰命名规范(可选,但建议统一)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:57:32