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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:26:05