Discord.py cog编写井字棋游戏时checkWinner未定义报错求助
问题原因
- 类成员方法调用规则错误:
checkWinner是你定义的help类的实例方法,Python中类内部调用自身的实例方法必须加self.前缀,你直接调用checkWinner()会被判定为找全局作用域的函数,自然会抛出未定义错误。 - 方法定义缺失必要参数:你写的
checkWinner方法作为类实例方法,第一个参数必须是实例本身self,你当前的定义缺少该参数,即便补了调用前缀也会报参数数量不匹配的错误。 - 额外存在严重的缩进逻辑错误:你把胜负校验、换回合、提示消息的代码全部错误缩进放在了打印棋盘的for循环内部的else分支,不仅会导致逻辑重复执行多次,后续的条件判断分支也完全错位,游戏逻辑根本无法正常运行。
- 全局变量使用不符合Cog开发规范:Discord Cog多为单实例多服务器共用,用global存储游戏状态会导致多个服务器的游戏数据串线,非常容易触发不可预期的bug。
修复方案
- 先修正
checkWinner方法的定义,补全self参数:
# 修正后的方法定义,第一个参数必须为self def checkWinner(self, winningConditions, mark): global gameOver for condition in winningConditions: if board[condition[0]] == mark and board[condition[1]] == mark and board[condition[2]] == mark: gameOver = True
- 修正
checkWinner的调用语句,添加self.前缀:
把原来的checkWinner(winningConditions, mark)改为self.checkWinner(winningConditions, mark) - 修正place方法的缩进逻辑,把胜负判断、换回合的代码从for循环中移出,调整后完整的place方法参考:
@commands.command() async def place(self, ctx: commands.Context, pos: int): global turn global player1 global player2 global board global count global gameOver if not gameOver: mark = "" if turn == ctx.author: if turn == player1: mark = ":regional_indicator_x:" elif turn == player2: mark = ":o2:" if 0 < pos < 10 and board[pos - 1] == ":white_large_square:" : board[pos - 1] = mark count += 1 # 打印棋盘 line = "" for x in range(len(board)): if x == 2 or x == 5 or x == 8: line += " " + board[x] await ctx.send(line) line = "" else: line += " " + board[x] # 校验胜负,逻辑放在for循环外 self.checkWinner(self.winningConditions, mark) print(count) if gameOver == True: await ctx.send(mark + " wins!") elif count >= 9: gameOver = True await ctx.send("It's a tie!") else: # 交换回合 turn = player2 if turn == player1 else player1 await ctx.send(f"It is <@{turn.id}>'s turn") else: await ctx.send("Be sure to choose an integer between 1 and 9 (inclusive) and an unmarked tile.") else: await ctx.send("It is not your turn.") else: await ctx.send("Please start a new game using the !tictactoe command.")
- (可选优化)建议把所有全局变量替换为类的实例属性,在Cog的
__init__方法中初始化,彻底避免全局污染和多服务器串数据的问题。
内容的提问来源于stack exchange,提问作者Sir Pez
相关产品推荐
相关产品推荐

