Discord.py井字棋:如何实现等待用户输入并解决无限等待问题
问题分析与修复方案
核心错误点
upper方法未调用:代码里user = xo.upper只是拿了方法对象,没执行方法,导致user是函数而非字符串。而ttt.player(board)返回的是"X"或"O"字符串,user == player永远不成立,根本进不了用户输入的逻辑块,只会无限循环执行await printBoard(ctx, board)。- 潜在
printBoard问题:如果printBoard不是异步函数,用await会报错;要是它内部有无限循环或未完成的异步操作,也会卡住程序。
修复步骤
1. 修正upper调用
把user = xo.upper改成:
user = xo.upper()
这样才能拿到大写的玩家标记,让user == player判断生效,进入用户输入流程。
2. 确保printBoard是合法异步函数
如果printBoard是你自己写的,得保证它是异步的,内部没有阻塞操作。示例写法:
async def printBoard(ctx, board): # 拼接棋盘字符串 board_content = "" for row in board: board_content += "\t".join(cell if cell else " " for cell in row) + "\n" await ctx.send(f"当前棋盘:\n{board_content}")
要是printBoard不是异步的,直接去掉await调用(不推荐,同步函数可能阻塞事件循环)。
3. 补全循环逻辑(可选)
当前代码落子后没更新游戏状态,会一直循环。需要在玩家落子后更新棋盘并检查游戏是否结束:
# 获取move后添加: board = ttt.result(board, move) gameOver = ttt.terminal(board)
同时要处理AI回合(当player不是user时),避免循环空转。
修复后完整代码示例
@bot.command() async def tictactoe(ctx, xo="X"): await ctx.send( "按以下格式输入你的落子(后续会优化):\nA1\tB1\tC1\t\nA2\tB2\tC2\t\nA3\tB3\tC3\t" ) user = xo.upper() # 修复:调用upper方法 board = ttt.initial_state() gameOver = ttt.terminal(board) while not gameOver: await printBoard(ctx, board) player = ttt.player(board) if user == player: await ctx.send(f"你的回合,用{user}落子:") def check(msg): return ( msg.author == ctx.author and msg.channel == ctx.channel and msg.content.upper() in ["A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3", "C3"] ) try: msg = await bot.wait_for("message", check=check, timeout=60.0) move = h.tttMoves[msg.content.upper()] board = ttt.result(board, move) # 更新棋盘 gameOver = ttt.terminal(board) # 检查游戏是否结束 print(move) except asyncio.TimeoutError: await ctx.send("超时!游戏结束。") break else: # 这里添加AI落子逻辑 await ctx.send("AI思考中...") ai_move = # 调用你的AI算法获取落子位置 board = ttt.result(board, ai_move) gameOver = ttt.terminal(board)
内容的提问来源于stack exchange,提问作者grey
相关产品推荐
相关产品推荐

